From 0b3929808bb1b3b4270aeb0d43f762dc45e1ac1a Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Tue, 12 Mar 2019 00:26:31 +0100 Subject: [PATCH] Apply matchMedia to the top frame (#3612) * Apply matchMedia to the top frame In case Prebid.js is called from within an iFrame, matchMedia should be applied to window.top, not the containing iFrame. This PR falls back to the legacy behavior in case of unfriendly iFrames. * Spec update --- src/sizeMapping.js | 14 ++++++++++++-- test/spec/sizeMapping_spec.js | 7 +++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/sizeMapping.js b/src/sizeMapping.js index b8278df69c0..04c9773a1af 100644 --- a/src/sizeMapping.js +++ b/src/sizeMapping.js @@ -1,5 +1,5 @@ import { config } from './config'; -import {logWarn, isPlainObject, deepAccess, deepClone} from './utils'; +import {logWarn, isPlainObject, deepAccess, deepClone, getWindowTop} from './utils'; import includes from 'core-js/library/fn/array/includes'; let sizeConfig = []; @@ -123,7 +123,17 @@ function evaluateSizeConfig(configs) { typeof config === 'object' && typeof config.mediaQuery === 'string' ) { - if (matchMedia(config.mediaQuery).matches) { + let ruleMatch = false; + + try { + ruleMatch = getWindowTop().matchMedia(config.mediaQuery).matches; + } catch (e) { + logWarn('Unfriendly iFrame blocks sizeConfig from being correctly evaluated'); + + ruleMatch = matchMedia(config.mediaQuery).matches; + } + + if (ruleMatch) { if (Array.isArray(config.sizesSupported)) { results.shouldFilter = true; } diff --git a/test/spec/sizeMapping_spec.js b/test/spec/sizeMapping_spec.js index aca4ccf8f54..f85da4cba0b 100644 --- a/test/spec/sizeMapping_spec.js +++ b/test/spec/sizeMapping_spec.js @@ -60,6 +60,13 @@ describe('sizeMapping', function () { matchMediaOverride = {matches: false}; + sandbox.stub(utils.getWindowTop(), 'matchMedia').callsFake((...args) => { + if (typeof matchMediaOverride === 'function') { + return matchMediaOverride.apply(utils.getWindowTop(), args); + } + return matchMediaOverride; + }); + sandbox.stub(window, 'matchMedia').callsFake((...args) => { if (typeof matchMediaOverride === 'function') { return matchMediaOverride.apply(window, args);