Skip to content

Commit

Permalink
Access the top window in a safe manner (#550)
Browse files Browse the repository at this point in the history
Fixes Uncaught DOMException: Failed to read a named property
'addEventListener' from 'Window': Blocked a frame with origin
"xxx" from accessing a cross-origin frame.
  • Loading branch information
paulsmirnov authored Aug 20, 2024
1 parent e35706d commit fa60029
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/miew/demo/scripts/ui/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -2039,7 +2039,7 @@ Menu.prototype._onTerminalOff = function () {
};

Menu.prototype._fixKeyboard = function () {
// do IFRAME related hack
// do IFRAME related hack // NOTE: embedding the demo is not recommended/supported anymore
if (window !== window.top) {
const parentDocument = window.top.document;
let button = parentDocument.querySelector('button');
Expand Down
6 changes: 4 additions & 2 deletions packages/miew/src/Miew.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import capabilities from './gfx/capabilities';
import WebVRPoC from './gfx/vr/WebVRPoC';
import vertexScreenQuadShader from './gfx/shaders/ScreenQuad.vert';
import fragmentScreenQuadFromDistTex from './gfx/shaders/ScreenQuadFromDistortionTex.frag';
import getTopWindow from './utils/getTopWindow';

const {
selectors,
Expand Down Expand Up @@ -298,11 +299,12 @@ Miew.prototype.init = function () {
zIndex: 700,
});

window.top.addEventListener('keydown', (event) => {
const target = getTopWindow();
target.addEventListener('keydown', (event) => {
self._onKeyDown(event);
});

window.top.addEventListener('keyup', (event) => {
target.addEventListener('keyup', (event) => {
self._onKeyUp(event);
});

Expand Down
3 changes: 2 additions & 1 deletion packages/miew/src/ui/ObjectControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as THREE from 'three';
import Timer from '../Timer';
import settings from '../settings';
import EventDispatcher from '../utils/EventDispatcher';
import getTopWindow from '../utils/getTopWindow';

const VK_LEFT = 37;
const VK_UP = 38;
Expand Down Expand Up @@ -806,7 +807,7 @@ ObjectControls.prototype.keydownup = function (event) {
};

ObjectControls.prototype.getKeyBindObject = function () {
return window.top;
return getTopWindow();
};

ObjectControls.prototype.dispose = function () {
Expand Down
11 changes: 11 additions & 0 deletions packages/miew/src/utils/getTopWindow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function getTopWindow() {
// intercept the exception if we have cross-origin iframe
try {
if (window.top.location.href !== undefined) {
return window.top;
}
} catch (e) {
// provide fallback
}
return window;
}
31 changes: 31 additions & 0 deletions packages/miew/src/utils/getTopWindow.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect } from 'chai';
import getTopWindow from './getTopWindow';

describe('utils/getTopWindow()', () => {
it('returns top window if no iframe', () => {
const window = { location: { href: 'http://example.com' } };
window.top = window;

global.window = window;
expect(getTopWindow()).to.equal(window.top);
delete global.window;
});

it('returns top window if no cross-origin iframe', () => {
const window = { location: { href: 'http://example.com/viewer.html' } };
window.top = { location: { href: 'http://example.com/index.html' } };

global.window = window;
expect(getTopWindow()).to.equal(window.top);
delete global.window;
});

it('returns window if called inside cross-origin iframe', () => {
const window = { location: { href: 'http://example.com:8000' } };
window.top = { locationRestricted: { href: 'http://example.com:8001' } };

global.window = window;
expect(getTopWindow()).to.equal(window);
delete global.window;
});
});

0 comments on commit fa60029

Please sign in to comment.