diff --git a/libraries/devicePixelRatio/devicePixelRatio.js b/libraries/devicePixelRatio/devicePixelRatio.js
new file mode 100644
index 00000000000..8bfe23bcb3d
--- /dev/null
+++ b/libraries/devicePixelRatio/devicePixelRatio.js
@@ -0,0 +1,17 @@
+import {canAccessWindowTop, internal as utilsInternals} from '../../src/utils.js';
+
+function getFallbackWindow(win) {
+ if (win) {
+ return win;
+ }
+
+ return canAccessWindowTop() ? utilsInternals.getWindowTop() : utilsInternals.getWindowSelf();
+}
+
+export function getDevicePixelRatio(win) {
+ try {
+ return getFallbackWindow(win).devicePixelRatio;
+ } catch (e) {
+ }
+ return 1;
+}
diff --git a/modules/apstreamBidAdapter.js b/modules/apstreamBidAdapter.js
index 838487925c8..f432c85388f 100644
--- a/modules/apstreamBidAdapter.js
+++ b/modules/apstreamBidAdapter.js
@@ -1,5 +1,6 @@
import {getDNT} from '../libraries/dnt/index.js';
import { generateUUID, deepAccess, createTrackPixelHtml } from '../src/utils.js';
+import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { getStorageManager } from '../src/storageManager.js';
@@ -335,7 +336,7 @@ function injectPixels(ad, pixels, scripts) {
}
function getScreenParams() {
- return `${window.screen.width}x${window.screen.height}@${window.devicePixelRatio}`;
+ return `${window.screen.width}x${window.screen.height}@${getDevicePixelRatio(window)}`;
}
function getBids(bids) {
diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js
index b37ceab6631..7f5a4bedd62 100644
--- a/modules/datablocksBidAdapter.js
+++ b/modules/datablocksBidAdapter.js
@@ -1,3 +1,4 @@
+import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js';
import {deepAccess, getWinDimensions, getWindowTop, isGptPubadsDefined} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
@@ -135,7 +136,7 @@ export const spec = {
'whl': win.history.length,
'wxo': win.pageXOffset,
'wyo': win.pageYOffset,
- 'wpr': win.devicePixelRatio,
+ 'wpr': getDevicePixelRatio(win),
'is_bot': botTest.doTests(),
'is_hid': win.document.hidden,
'vs': win.document.visibilityState
diff --git a/modules/greenbidsBidAdapter.js b/modules/greenbidsBidAdapter.js
index 490eb9e703d..58aa8608194 100644
--- a/modules/greenbidsBidAdapter.js
+++ b/modules/greenbidsBidAdapter.js
@@ -1,4 +1,5 @@
import { getValue, logError, deepAccess, parseSizesInput, getBidIdParameter, logInfo, getWinDimensions, getScreenOrientation } from '../src/utils.js';
+import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { getStorageManager } from '../src/storageManager.js';
import { getHLen } from '../libraries/navigatorData/navigatorData.js';
@@ -65,7 +66,7 @@ export const spec = {
device: bidderRequest?.ortb2?.device || {},
deviceWidth: screen.width,
deviceHeight: screen.height,
- devicePixelRatio: topWindow.devicePixelRatio,
+ devicePixelRatio: getDevicePixelRatio(topWindow),
screenOrientation: getScreenOrientation(),
historyLength: getHLen(),
viewportHeight: getWinDimensions().visualViewport.height,
diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js
index 8bfb5b841d0..c1a5b8328dc 100644
--- a/modules/gumgumBidAdapter.js
+++ b/modules/gumgumBidAdapter.js
@@ -1,5 +1,6 @@
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {_each, deepAccess, getWinDimensions, logError, logWarn, parseSizesInput} from '../src/utils.js';
+import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js';
import {config} from '../src/config.js';
import {getStorageManager} from '../src/storageManager.js';
@@ -89,7 +90,7 @@ function _getBrowserParams(topWindowUrl, mosttopLocation) {
pu: stripGGParams(topUrl),
tpl: mosttopURL,
ce: storage.cookiesAreEnabled(),
- dpr: topWindow.devicePixelRatio || 1,
+ dpr: getDevicePixelRatio(topWindow),
jcsi: JSON.stringify(JCSI),
ogu: getOgURL()
};
diff --git a/modules/hypelabBidAdapter.js b/modules/hypelabBidAdapter.js
index 9982af84cc9..bc562b84cb3 100644
--- a/modules/hypelabBidAdapter.js
+++ b/modules/hypelabBidAdapter.js
@@ -1,6 +1,7 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
import { generateUUID, isFn, isPlainObject, getWinDimensions } from '../src/utils.js';
+import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js';
import { ajax } from '../src/ajax.js';
import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js';
import { getWalletPresence, getWalletProviderFlags } from '../libraries/hypelabUtils/hypelabUtils.js';
@@ -40,7 +41,7 @@ function buildRequests(validBidRequests, bidderRequest) {
const uuid = uids[0] ? uids[0] : generateTemporaryUUID();
const floor = getBidFloor(request, request.sizes || []);
- const dpr = typeof window !== 'undefined' ? window.devicePixelRatio : 1;
+ const dpr = typeof window !== 'undefined' ? getDevicePixelRatio(window) : 1;
const wp = getWalletPresence();
const wpfs = getWalletProviderFlags();
const winDimensions = getWinDimensions();
diff --git a/modules/oguryBidAdapter.js b/modules/oguryBidAdapter.js
index 507cb63fe2a..00c8bfb77ef 100644
--- a/modules/oguryBidAdapter.js
+++ b/modules/oguryBidAdapter.js
@@ -2,6 +2,7 @@
import { BANNER } from '../src/mediaTypes.js';
import { getWindowSelf, getWindowTop, isFn, deepAccess, isPlainObject, deepSetValue, mergeDeep } from '../src/utils.js';
+import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { ajax } from '../src/ajax.js';
import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js';
@@ -25,7 +26,7 @@ export const ortbConverterProps = {
request(buildRequest, imps, bidderRequest, context) {
const req = buildRequest(imps, bidderRequest, context);
req.tmax = DEFAULT_TIMEOUT;
- deepSetValue(req, 'device.pxratio', window.devicePixelRatio);
+ deepSetValue(req, 'device.pxratio', getDevicePixelRatio(getWindowContext()));
deepSetValue(req, 'site.page', getWindowContext().location.href);
req.ext = mergeDeep({}, req.ext, {
diff --git a/modules/sspBCBidAdapter.js b/modules/sspBCBidAdapter.js
index 09b7e6a6daa..5ce8fb34492 100644
--- a/modules/sspBCBidAdapter.js
+++ b/modules/sspBCBidAdapter.js
@@ -1,4 +1,5 @@
import { deepAccess, getWinDimensions, getWindowTop, isArray, logInfo, logWarn } from '../src/utils.js';
+import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js';
import { ajax } from '../src/ajax.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
@@ -174,7 +175,7 @@ const applyClientHints = ortbRequest => {
'CH-SaveData': connection.saveData,
'CH-Downlink': connection.downlink,
'CH-DeviceMemory': null,
- 'CH-Dpr': W.devicePixelRatio,
+ 'CH-Dpr': getDevicePixelRatio(W),
'CH-ViewportWidth': viewport.width,
'CH-BrowserBrands': JSON.stringify(userAgentData.brands),
'CH-isMobile': userAgentData.mobile,
diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js
index 24894b9e7c1..bc2e3ef9588 100644
--- a/modules/teadsBidAdapter.js
+++ b/modules/teadsBidAdapter.js
@@ -1,4 +1,5 @@
import {logError, parseSizesInput, isArray, getBidIdParameter, getWinDimensions, getScreenOrientation} from '../src/utils.js';
+import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getStorageManager} from '../src/storageManager.js';
import {isAutoplayEnabled} from '../libraries/autoplayDetection/autoplay.js';
@@ -72,7 +73,7 @@ export const spec = {
device: bidderRequest?.ortb2?.device || {},
deviceWidth: screen.width,
deviceHeight: screen.height,
- devicePixelRatio: topWindow.devicePixelRatio,
+ devicePixelRatio: getDevicePixelRatio(topWindow),
screenOrientation: getScreenOrientation(),
historyLength: getHLen(),
viewportHeight: getWinDimensions().visualViewport.height,
diff --git a/src/utils/winDimensions.js b/src/utils/winDimensions.js
index 01122a9761c..2759e56eba6 100644
--- a/src/utils/winDimensions.js
+++ b/src/utils/winDimensions.js
@@ -34,22 +34,22 @@ const winDimensions = new CachedApiWrapper(
);
export const internal = {
- reset: winDimensions.reset,
+ winDimensions,
};
export const getWinDimensions = (() => {
let lastCheckTimestamp;
return function () {
if (!lastCheckTimestamp || (Date.now() - lastCheckTimestamp > CHECK_INTERVAL_MS)) {
- internal.reset();
+ internal.winDimensions.reset();
lastCheckTimestamp = Date.now();
}
- return winDimensions.obj;
+ return internal.winDimensions.obj;
}
})();
export function resetWinDimensions() {
- internal.reset();
+ internal.winDimensions.reset();
}
export function getScreenOrientation(win) {
diff --git a/test/spec/modules/greenbidsBidAdapter_spec.js b/test/spec/modules/greenbidsBidAdapter_spec.js
index 4cf992434dc..00c0005fe16 100644
--- a/test/spec/modules/greenbidsBidAdapter_spec.js
+++ b/test/spec/modules/greenbidsBidAdapter_spec.js
@@ -2,6 +2,7 @@ import { expect } from 'chai';
import { newBidder } from 'src/adapters/bidderFactory.js';
import { spec, ENDPOINT_URL } from 'modules/greenbidsBidAdapter.js';
import { getScreenOrientation } from 'src/utils.js';
+import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js';
const AD_SCRIPT = '"';
describe('greenbidsBidAdapter', () => {
@@ -277,7 +278,7 @@ describe('greenbidsBidAdapter', () => {
it('should add pixelRatio info to payload', function () {
const request = spec.buildRequests(bidRequests, bidderRequestDefault);
const payload = JSON.parse(request.data);
- const pixelRatio = window.top.devicePixelRatio
+ const pixelRatio = getDevicePixelRatio()
expect(payload.devicePixelRatio).to.exist;
expect(payload.devicePixelRatio).to.deep.equal(pixelRatio);
diff --git a/test/spec/modules/hypelabBidAdapter_spec.js b/test/spec/modules/hypelabBidAdapter_spec.js
index d6c79a957cc..ff98c33b136 100644
--- a/test/spec/modules/hypelabBidAdapter_spec.js
+++ b/test/spec/modules/hypelabBidAdapter_spec.js
@@ -13,6 +13,7 @@ import {
} from 'modules/hypelabBidAdapter.js';
import { BANNER } from 'src/mediaTypes.js';
+import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js';
const mockValidBidRequest = {
bidder: 'hypelab',
@@ -177,7 +178,7 @@ describe('hypelabBidAdapter', function () {
expect(data.dpr).to.be.a('number');
expect(data.location).to.be.a('string');
expect(data.floor).to.equal(null);
- expect(data.dpr).to.equal(1);
+ expect(data.dpr).to.equal(getDevicePixelRatio());
expect(data.wp).to.deep.equal({
ada: false,
bnb: false,
diff --git a/test/spec/modules/oguryBidAdapter_spec.js b/test/spec/modules/oguryBidAdapter_spec.js
index 57ebea5e2ab..3cd7542f6c2 100644
--- a/test/spec/modules/oguryBidAdapter_spec.js
+++ b/test/spec/modules/oguryBidAdapter_spec.js
@@ -3,6 +3,7 @@ import sinon from 'sinon';
import { spec, ortbConverterProps } from 'modules/oguryBidAdapter';
import * as utils from 'src/utils.js';
import { server } from '../../mocks/xhr.js';
+import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js';
const BID_URL = 'https://mweb-hb.presage.io/api/header-bidding-request';
const TIMEOUT_URL = 'https://ms-ads-monitoring-events.presage.io/bid_timeout'
@@ -577,10 +578,6 @@ describe('OguryBidAdapter', () => {
return stubbedCurrentTime;
});
- const stubbedDevicePixelMethod = sinon.stub(window, 'devicePixelRatio').get(function() {
- return stubbedDevicePixelRatio;
- });
-
const defaultTimeout = 1000;
function assertImpObject(ortbBidRequest, bidRequest) {
@@ -639,7 +636,7 @@ describe('OguryBidAdapter', () => {
beforeEach(() => {
windowTopStub = sinon.stub(utils, 'getWindowTop');
- windowTopStub.returns({ location: { href: currentLocation } });
+ windowTopStub.returns({ location: { href: currentLocation }, devicePixelRatio: stubbedDevicePixelRatio});
});
afterEach(() => {
@@ -648,7 +645,6 @@ describe('OguryBidAdapter', () => {
after(() => {
stubbedCurrentTimeMethod.restore();
- stubbedDevicePixelMethod.restore();
});
it('sends bid request to ENDPOINT via POST', function () {
diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js
index f776f5243a8..c698473260f 100644
--- a/test/spec/modules/teadsBidAdapter_spec.js
+++ b/test/spec/modules/teadsBidAdapter_spec.js
@@ -3,6 +3,7 @@ import * as autoplay from 'libraries/autoplayDetection/autoplay.js';
import { spec, storage } from 'modules/teadsBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
import { getScreenOrientation } from 'src/utils.js';
+import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js';
const ENDPOINT = 'https://a.teads.tv/hb/bid-request';
const AD_SCRIPT = '"';
@@ -360,7 +361,7 @@ describe('teadsBidAdapter', () => {
it('should add pixelRatio info to payload', function () {
const request = spec.buildRequests(bidRequests, bidderRequestDefault);
const payload = JSON.parse(request.data);
- const pixelRatio = window.top.devicePixelRatio
+ const pixelRatio = getDevicePixelRatio();
expect(payload.devicePixelRatio).to.exist;
expect(payload.devicePixelRatio).to.deep.equal(pixelRatio);
diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js
index 1efdc5621f6..8ed2efa3b9f 100644
--- a/test/spec/utils_spec.js
+++ b/test/spec/utils_spec.js
@@ -1446,7 +1446,7 @@ describe('getWinDimensions', () => {
});
it('should clear cache once per 20ms', () => {
- const resetWinDimensionsSpy = sinon.spy(winDimensions.internal, 'reset');
+ const resetWinDimensionsSpy = sinon.spy(winDimensions.internal.winDimensions, 'reset');
expect(getWinDimensions().innerHeight).to.exist;
clock.tick(1);
expect(getWinDimensions().innerHeight).to.exist;