diff --git a/lib/services/window.js b/lib/services/window.js index 5784b7c..f9af85d 100644 --- a/lib/services/window.js +++ b/lib/services/window.js @@ -14,12 +14,36 @@ windowService._setMessageSource(domEmitterSource); module.exports = windowService; - _.extend(windowService, { - isTop: windowService_isTop + isTop: windowService_isTop, + getTop: windowService_getTop }); +/** + * Gets the top window containing a milo instance. + * It is not possible to use `window.top` if the application is contained + * in an iframe being served from a different domain (Trying to access + * properties of the top window in this case would breach the browser's + * cross-origin iframe policy) + */ +function windowService_getTop() { + var topWindow = window; + + while (true) { + try { + var parentWindow = topWindow.parent; + // Trying to access this property outside of the same domain will throw an error + var milo = parentWindow.milo; + if (!milo || topWindow === parentWindow) return topWindow; // No more milo / we're at the top + + topWindow = parentWindow; + } catch (_e) { + return topWindow; + } + } +} function windowService_isTop() { - return window.top == window.self || window.__karma__; + const topMiloWindow = windowService_getTop(); + return topMiloWindow == window.self || window.__karma__; } diff --git a/package.json b/package.json index ef7d0ec..7c85ab2 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "brfs": "^1.4.3", "browserify": "^14.0.0", "eslintify": "^3.1.0", - "grunt": "^1.0.1", + "grunt": "1.0.1", "grunt-browserify": "^5.0.0", "grunt-contrib-copy": "^1.0.0", "grunt-contrib-uglify": "^2.0.0",