Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 84ccda2

Browse files
authored
Merge pull request #208 from ckeditor/t/201
Fix: Bulletproofed `isDomNode()` helper when used in iframes. Removed `isWindow()` logic from the helper. Closes #201.
2 parents 28b34d5 + 6f2ad28 commit 84ccda2

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

src/dom/emittermixin.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { default as EmitterMixin, _getEmitterListenedTo, _setEmitterId } from '.
1111
import uid from '../uid';
1212
import extend from '../lib/lodash/extend';
1313
import isDomNode from './isdomnode';
14+
import isWindow from './iswindow';
1415

1516
/**
1617
* Mixin that injects the DOM events API into its host. It provides the API
@@ -56,7 +57,7 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
5657

5758
// Check if emitter is an instance of DOM Node. If so, replace the argument with
5859
// corresponding ProxyEmitter (or create one if not existing).
59-
if ( isDomNode( emitter ) ) {
60+
if ( isDomNode( emitter ) || isWindow( emitter ) ) {
6061
args[ 0 ] = this._getProxyEmitter( emitter ) || new ProxyEmitter( emitter );
6162
}
6263

@@ -85,7 +86,7 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
8586
const emitter = args[ 0 ];
8687

8788
// Check if emitter is an instance of DOM Node. If so, replace the argument with corresponding ProxyEmitter.
88-
if ( isDomNode( emitter ) ) {
89+
if ( isDomNode( emitter ) || isWindow( emitter ) ) {
8990
const proxy = this._getProxyEmitter( emitter );
9091

9192
// Element has no listeners.

src/dom/isdomnode.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@
77
* @module utils/dom/isdomnode
88
*/
99

10-
import isNative from '../lib/lodash/isNative';
11-
1210
/**
1311
* Checks if the object is a native DOM Node.
1412
*
1513
* @param {*} obj
1614
* @returns {Boolean}
1715
*/
1816
export default function isDomNode( obj ) {
19-
return !!( obj && isNative( obj.addEventListener ) );
17+
if ( obj ) {
18+
if ( obj.defaultView ) {
19+
return obj instanceof obj.defaultView.Document;
20+
} else if ( obj.ownerDocument && obj.ownerDocument.defaultView ) {
21+
return obj instanceof obj.ownerDocument.defaultView.Node;
22+
}
23+
}
24+
25+
return false;
2026
}

tests/dom/isdomnode.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,34 @@ import isDomNode from '../../src/dom/isdomnode';
99

1010
describe( 'isDomNode()', () => {
1111
it( 'detects native DOM nodes', () => {
12+
expect( isDomNode( document ) ).to.be.true;
13+
expect( isDomNode( document.createElement( 'div' ) ) ).to.be.true;
14+
expect( isDomNode( document.createTextNode( 'Foo' ) ) ).to.be.true;
15+
1216
expect( isDomNode( {} ) ).to.be.false;
1317
expect( isDomNode( null ) ).to.be.false;
1418
expect( isDomNode( undefined ) ).to.be.false;
1519
expect( isDomNode( new Date() ) ).to.be.false;
1620
expect( isDomNode( 42 ) ).to.be.false;
17-
expect( isDomNode( window ) ).to.be.true;
18-
expect( isDomNode( document ) ).to.be.true;
19-
expect( isDomNode( document.createElement( 'div' ) ) ).to.be.true;
20-
expect( isDomNode( document.createTextNode( 'Foo' ) ) ).to.be.true;
21+
expect( isDomNode( window ) ).to.be.false;
22+
} );
23+
24+
it( 'works for nodes in an iframe', done => {
25+
const iframe = document.createElement( 'iframe' );
26+
27+
iframe.addEventListener( 'load', () => {
28+
const iframeDocument = iframe.contentWindow.document;
29+
30+
expect( isDomNode( iframeDocument ) ).to.be.true;
31+
expect( isDomNode( iframeDocument.createElement( 'div' ) ) ).to.be.true;
32+
expect( isDomNode( iframeDocument.createTextNode( 'Foo' ) ) ).to.be.true;
33+
34+
expect( isDomNode( iframe.contentWindow ) ).to.be.false;
35+
36+
iframe.remove();
37+
done();
38+
} );
39+
40+
document.body.appendChild( iframe );
2141
} );
2242
} );

0 commit comments

Comments
 (0)