Przeglądaj źródła

Make `isHTMLElement` work for nodes that belong to other realms (#931).

Naotoshi Fujita 2 lat temu
rodzic
commit
fe6b65c300

Plik diff jest za duży
+ 0 - 0
dist/js/splide-renderer.min.js


Plik diff jest za duży
+ 0 - 0
dist/js/splide-renderer.min.js.map


+ 5 - 1
dist/js/splide.js

@@ -69,7 +69,11 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   }
 
   function isHTMLElement(subject) {
-    return subject instanceof HTMLElement;
+    try {
+      return subject instanceof (subject.ownerDocument.defaultView || window).HTMLElement;
+    } catch (e) {
+      return false;
+    }
   }
 
   function toArray(value) {

Plik diff jest za duży
+ 0 - 0
dist/js/splide.min.js


Plik diff jest za duży
+ 0 - 0
dist/js/splide.min.js.map


+ 36 - 23
src/js/utils/type/type.test.ts

@@ -1,7 +1,6 @@
 import {
   isArray,
   isFunction,
-  isHTMLButtonElement,
   isHTMLElement,
   isNull,
   isObject,
@@ -11,9 +10,6 @@ import {
 
 
 describe( 'Type methods', () => {
-  const div  = document.createElement( 'div' );
-  const text = document.createTextNode( 'test' );
-
   describe( 'isObject', () => {
     test( 'can return `true` if a subject is an object.', () => {
       [ {}, { a: 1 }, new Date() ].forEach( subject => {
@@ -93,29 +89,46 @@ describe( 'Type methods', () => {
       } );
     } );
   } );
+} );
 
-  describe( 'isHTMLElement', () => {
-    test( 'can return `true` if a subject is an HTMLElement.', () => {
-      expect( isHTMLElement( div ) ).toBe( true );
-    } );
+describe( 'isHTMLElement', () => {
+  const div  = document.createElement( 'div' );
+  const text = document.createTextNode( 'test' );
 
-    test( 'should return `false` for other subjects.', () => {
-      [ document, window, text, 1, true, undefined, '1', null, [ 1 ], { a: 1 }, NaN ].forEach( subject => {
-        expect( isHTMLElement( subject ) ).toBe( false );
-      } );
-    } );
+  document.body.innerHTML = '<iframe></iframe>';
+
+  test( 'can return `true` if a subject is an HTMLElement.', () => {
+    expect( isHTMLElement( div ) ).toBe( true );
   } );
 
-  describe( 'isHTMLButtonElement', () => {
-    test( 'can return `true` if a subject is an HTMLElement.', () => {
-      const button = document.createElement( 'button' );
-      expect( isHTMLButtonElement( button ) ).toBe( true );
+  test( 'should return `false` for other subjects.', () => {
+    [ document, window, text, 1, true, undefined, '1', null, [ 1 ], { a: 1 }, NaN ].forEach( subject => {
+      expect( isHTMLElement( subject ) ).toBe( false );
     } );
+  } );
 
-    test( 'should return `false` for other subjects.', () => {
-      [ document, window, div, text, 1, true, undefined, '1', null, [ 1 ], { a: 1 }, NaN ].forEach( subject => {
-        expect( isHTMLButtonElement( subject ) ).toBe( false );
-      } );
-    } );
+  test( 'should work for nodes coming from other realms.', () => {
+    const iframe = document.querySelector( 'iframe' );
+
+    expect( iframe ).toBeTruthy();
+
+    const { contentDocument, contentWindow } = iframe;
+    const iDiv = contentDocument.createElement( 'div' );
+
+    expect( contentWindow ).not.toBe( window );
+
+    // This should fail since `HTMLElement` is different with the iframe's.
+    expect( iDiv instanceof HTMLElement ).toBe( false );
+
+    // But this method will work since checking owners.
+    expect( isHTMLElement( iDiv ) ).toBe( true );
   } );
-} );
+
+  test( 'should work for nodes that do not belong to a specific window.', () => {
+    const div = new DOMParser().parseFromString( '<div>', 'text/html' ).body.firstElementChild;
+
+    expect( div ).toBeTruthy();
+    expect( div.ownerDocument.defaultView ).toBeNull();
+    expect( isHTMLElement( div ) ).toBe( true );
+  } );
+} );

+ 8 - 14
src/js/utils/type/type.ts

@@ -73,23 +73,17 @@ export function isNull( subject: unknown ): subject is null {
 }
 
 /**
- * Checks if the given subject is an HTMLElement or not.
+ * Checks if the given subject is an HTMLElement instance or not.
+ * This method takes into account which `window` the node belongs to.
  *
  * @param subject - A subject to check.
  *
  * @return `true` if the subject is an HTMLElement instance, or otherwise `false`.
  */
 export function isHTMLElement( subject: unknown ): subject is HTMLElement {
-  return subject instanceof HTMLElement;
-}
-
-/**
- * Checks if the given subject is an HTMLButtonElement or not.
- *
- * @param subject - A subject to check.
- *
- * @return `true` if the subject is an HTMLButtonElement, or otherwise `false`.
- */
-export function isHTMLButtonElement( subject: unknown ): subject is HTMLButtonElement {
-  return subject instanceof HTMLButtonElement;
-}
+  try {
+    return subject instanceof ( ( subject as Node ).ownerDocument.defaultView || window ).HTMLElement;
+  } catch ( e ) {
+    return false;
+  }
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików