diff --git a/src/utils.js b/src/utils.js index 0071d319f7b..b3ffbfc9896 100644 --- a/src/utils.js +++ b/src/utils.js @@ -159,47 +159,56 @@ export function parseGPTSingleSizeArray(singleSize) { } }; -export function getTopWindowLocation() { +exports.getTopWindowLocation = function() { if (exports.inIframe()) { - return getIframeParentLoc(); - } else { - return window.location; + let loc; + try { + loc = exports.getAncestorOrigins() || exports.getTopFrameReferrer(); + } catch (e) { + logInfo('could not obtain top window location', e); + } + if (loc) return parse(loc); } + return exports.getWindowLocation(); } -const getIframeParentLoc = function() { - let loc = window.location; +exports.getTopFrameReferrer = function () { try { - if (window.$sf) { - loc = window.document.referrer; - } else { - if (window.document.location && window.document.location.ancestorOrigins && - window.document.location.ancestorOrigins.length >= 1) { - loc = window.document.location.ancestorOrigins[window.document.location.ancestorOrigins.length - 1]; - } else if (window.document.location) { - // force an exception in x-domain environments. #1509 - window.top.location.toString(); - loc = getNonWebKitIframeParentLoc(); + // force an exception in x-domain environments. #1509 + window.top.location.toString(); + let referrerLoc = ''; + let currentWindow; + do { + currentWindow = currentWindow ? currentWindow.parent : window; + if (currentWindow.document && currentWindow.document.referrer) { + referrerLoc = currentWindow.document.referrer; } } - loc = parse(loc); + while (currentWindow !== window.top); + return referrerLoc; } catch (e) { - this.logMessage('getTopParentLoc failure', e); + return window.document.referrer; } - return loc; }; -const getNonWebKitIframeParentLoc = function() { - let referrerLoc = ''; - let currentWindow; - do { - currentWindow = currentWindow ? currentWindow.parent : window; - if (currentWindow.document && currentWindow.document.referrer) { - referrerLoc = currentWindow.document.referrer; - } +exports.getAncestorOrigins = function () { + if (window.document.location && window.document.location.ancestorOrigins && + window.document.location.ancestorOrigins.length >= 1) { + return window.document.location.ancestorOrigins[window.document.location.ancestorOrigins.length + - 1]; } - while (currentWindow !== window.top); - return referrerLoc; +}; + +exports.getWindowTop = function () { + return window.top; +}; + +exports.getWindowSelf = function () { + return window.self; +}; + +exports.getWindowLocation = function () { + return window.location; }; exports.getTopWindowUrl = function () { @@ -684,7 +693,7 @@ export function deepClone(obj) { export function inIframe() { try { - return window.self !== window.top; + return exports.getWindowSelf() !== exports.getWindowTop(); } catch (e) { return true; } diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js index f02b4881be3..37f8d90168b 100755 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -1,8 +1,7 @@ -import { getSlotTargeting, getAdServerTargeting } from 'test/fixtures/fixtures'; -import { cookiesAreEnabled } from '../../src/utils'; +import { getAdServerTargeting } from 'test/fixtures/fixtures'; var assert = require('assert'); -var utils = require('../../src/utils'); +var utils = require('src/utils'); describe('Utils', function () { var obj_string = 's', @@ -623,4 +622,88 @@ describe('Utils', function () { expect(adUnitCopy[0].renderer.render).to.be.a('function'); }); }); + describe('getTopWindowLocation', () => { + let sandbox; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + it('returns window.location if not in iFrame', () => { + sandbox.stub(utils, 'getWindowLocation').returns({ + href: 'https://www.google.com/', + ancestorOrigins: {}, + origin: 'https://www.google.com', + protocol: 'https', + host: 'www.google.com', + hostname: 'www.google.com', + port: '', + pathname: '/', + search: '', + hash: '' + }); + let windowSelfAndTopObject = { self: 'is same as top' }; + sandbox.stub(utils, 'getWindowSelf').returns( + windowSelfAndTopObject + ); + sandbox.stub(utils, 'getWindowTop').returns( + windowSelfAndTopObject + ); + var topWindowLocation = utils.getTopWindowLocation(); + expect(topWindowLocation).to.be.a('object'); + expect(topWindowLocation.href).to.equal('https://www.google.com/'); + expect(topWindowLocation.protocol).to.equal('https'); + expect(topWindowLocation.hostname).to.equal('www.google.com'); + expect(topWindowLocation.port).to.equal(''); + expect(topWindowLocation.pathname).to.equal('/'); + expect(topWindowLocation.hash).to.equal(''); + expect(topWindowLocation.search).to.equal(''); + expect(topWindowLocation.host).to.equal('www.google.com'); + }); + + it('returns parsed dom string from ancestorOrigins if in iFrame & ancestorOrigins is populated', () => { + sandbox.stub(utils, 'getWindowSelf').returns( + { self: 'is not same as top' } + ); + sandbox.stub(utils, 'getWindowTop').returns( + { top: 'is not same as self' } + ); + sandbox.stub(utils, 'getAncestorOrigins').returns('https://www.google.com/a/umich.edu/acs'); + var topWindowLocation = utils.getTopWindowLocation(); + expect(topWindowLocation).to.be.a('object'); + expect(topWindowLocation.pathname).to.equal('/a/umich.edu/acs'); + expect(topWindowLocation.href).to.equal('https://www.google.com/a/umich.edu/acs'); + expect(topWindowLocation.protocol).to.equal('https'); + expect(topWindowLocation.hostname).to.equal('www.google.com'); + expect(topWindowLocation.port).to.equal(0); + expect(topWindowLocation.hash).to.equal(''); + assert.deepEqual(topWindowLocation.search, {}); + expect(topWindowLocation.host).to.equal('www.google.com'); + }); + + it('returns parsed referrer string if in iFrame but no ancestorOrigins', () => { + sandbox.stub(utils, 'getWindowSelf').returns( + { self: 'is not same as top' } + ); + sandbox.stub(utils, 'getWindowTop').returns( + { top: 'is not same as self' } + ); + sandbox.stub(utils, 'getAncestorOrigins').returns(null); + sandbox.stub(utils, 'getTopFrameReferrer').returns('https://www.example.com/'); + var topWindowLocation = utils.getTopWindowLocation(); + expect(topWindowLocation).to.be.a('object'); + expect(topWindowLocation.href).to.equal('https://www.example.com/'); + expect(topWindowLocation.protocol).to.equal('https'); + expect(topWindowLocation.hostname).to.equal('www.example.com'); + expect(topWindowLocation.port).to.equal(0); + expect(topWindowLocation.pathname).to.equal('/'); + expect(topWindowLocation.hash).to.equal(''); + assert.deepEqual(topWindowLocation.search, {}); + expect(topWindowLocation.host).to.equal('www.example.com'); + }); + }); });