tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Document-importNode.html (9452B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
      5 <link rel="help" href="https://github.com/whatwg/html/issues/10854">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 </head>
      9 <body>
     10 <div id="host">
     11    <template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry>
     12        <div>
     13            <some-element></some-element>
     14            <other-element></other-element>
     15        </div>
     16    </template>
     17 </div>
     18 <template id="template">
     19    <some-element>
     20        <template shadowrootmode="closed" shadowrootclonable="true" shadowrootcustomelementregistry>
     21            <div>
     22                <some-element></some-element>
     23                <other-element></other-element>
     24            </div>
     25        </template>
     26    </some-element>
     27 </template>
     28 <div id="root">
     29    <span></span>
     30 </div>
     31 <script>
     32 
     33 const scopedRegistry = new CustomElementRegistry();
     34 const emptyRegistry = new CustomElementRegistry();
     35 class GlobalSomeElement extends HTMLElement {
     36    elementInternals;
     37 
     38    constructor() {
     39        super();
     40        this.elementInternals = this.attachInternals();
     41        if (this.elementInternals.shadowRoot)
     42            scopedRegistry.initialize(this.elementInternals.shadowRoot);
     43    }
     44 };
     45 class GlobalOtherElement extends HTMLElement {};
     46 class ScopedSomeElement extends HTMLElement {};
     47 customElements.define('some-element', GlobalSomeElement);
     48 customElements.define('other-element', GlobalOtherElement);
     49 scopedRegistry.define('some-element', ScopedSomeElement);
     50 
     51 test(() => {
     52    assert_true(document.importNode(document.createElement('some-element')) instanceof GlobalSomeElement);
     53 }, 'importNode should clone using the global regsitry by default');
     54 
     55 test(() => {
     56    assert_true(document.importNode(document.createElement('some-element'), {customElementRegistry: scopedRegistry}) instanceof GlobalSomeElement);
     57 }, 'importNode should clone using target\'s registry if non-null');
     58 
     59 test(() => {
     60    assert_true(document.importNode(document.implementation.createHTMLDocument().createElement('some-element'), {customElementRegistry: scopedRegistry}) instanceof ScopedSomeElement);
     61 }, 'importNode should clone using the specified registry if target\'s registry is null');
     62 
     63 test(() => {
     64    const clone = document.importNode(host, {selfOnly: false, customElementRegistry: scopedRegistry});
     65    assert_equals(clone.shadowRoot.querySelector('some-element').__proto__.constructor.name, 'HTMLElement');
     66    assert_false(clone.shadowRoot.querySelector('some-element') instanceof GlobalSomeElement);
     67    assert_false(clone.shadowRoot.querySelector('some-element') instanceof ScopedSomeElement);
     68    assert_true(clone.shadowRoot.querySelector('other-element') instanceof HTMLElement);
     69    assert_false(clone.shadowRoot.querySelector('other-element') instanceof GlobalOtherElement);
     70 }, 'importNode should preserve null-ness of custom element registry');
     71 
     72 test(() => {
     73    const clone = document.importNode(host.shadowRoot.querySelector('div'), {selfOnly: false});
     74    assert_equals(clone.customElementRegistry, window.customElements);
     75    assert_true(clone.querySelector('some-element') instanceof GlobalSomeElement);
     76    assert_true(clone.querySelector('other-element') instanceof GlobalOtherElement);
     77 }, 'importNode should clone a shadow host with a declarative shadow DOM using the global registry by default');
     78 
     79 test(() => {
     80    const clone = document.importNode(host.shadowRoot.querySelector('div'), {selfOnly: false, customElementRegistry: scopedRegistry});
     81    assert_equals(clone.customElementRegistry, scopedRegistry);
     82    assert_true(clone.querySelector('some-element') instanceof ScopedSomeElement);
     83    assert_false(clone.querySelector('other-element') instanceof GlobalOtherElement);
     84 }, 'importNode should clone a shadow host with a declarative shadow DOM using a specified scoped registry');
     85 
     86 test(() => {
     87    const element = document.createElement('div', {customElementRegistry: emptyRegistry});
     88    element.innerHTML = '<some-element></some-element><other-element></other-element>';
     89    const clone = document.importNode(element, {selfOnly: false, customElementRegistry: scopedRegistry});
     90    assert_equals(clone.customElementRegistry, emptyRegistry);
     91    assert_true(clone.querySelector('some-element') instanceof HTMLElement);
     92    assert_false(clone.querySelector('some-element') instanceof GlobalSomeElement);
     93    assert_false(clone.querySelector('some-element') instanceof ScopedSomeElement);
     94    assert_true(clone.querySelector('other-element') instanceof HTMLElement);
     95    assert_false(clone.querySelector('other-element') instanceof GlobalOtherElement);
     96 }, 'importNode should clone using target\'s registry if non-null, including when it\'s not the global registry');
     97 
     98 test(() => {
     99    const template = document.createElement('template');
    100    template.innerHTML = '<div><some-element>hello</some-element><other-element>world</other-element></div>';
    101    assert_equals(template.content.querySelector('some-element').__proto__.constructor.name, 'HTMLElement');
    102    assert_equals(template.content.querySelector('other-element').__proto__.constructor.name, 'HTMLElement');
    103    const clone = document.importNode(template.content, {selfOnly: false});
    104    assert_equals(clone.querySelector('some-element').customElementRegistry, window.customElements);
    105    assert_equals(clone.querySelector('some-element').__proto__.constructor.name, 'GlobalSomeElement');
    106    assert_equals(clone.querySelector('other-element').__proto__.constructor.name, 'GlobalOtherElement');
    107 }, 'importNode should clone a template content using the global registry by default');
    108 
    109 test(() => {
    110    const template = document.createElement('template');
    111    template.innerHTML = '<div><some-element>hello</some-element><other-element>world</other-element></div>';
    112    assert_equals(template.content.querySelector('some-element').__proto__.constructor.name, 'HTMLElement');
    113    assert_equals(template.content.querySelector('other-element').__proto__.constructor.name, 'HTMLElement');
    114    const clone = document.importNode(template.content, {selfOnly: false, customElementRegistry: scopedRegistry});
    115    assert_equals(clone.querySelector('some-element').customElementRegistry, scopedRegistry);
    116    assert_equals(clone.querySelector('some-element').__proto__.constructor.name, 'ScopedSomeElement');
    117    assert_equals(clone.querySelector('other-element').__proto__.constructor.name, 'HTMLElement');
    118 }, 'importNode should clone a template content using a specified scoped registry');
    119 
    120 test(() => {
    121    const template = document.createElement('template');
    122    template.innerHTML = `
    123 <div>
    124    <some-element>
    125        <template>
    126            <other-element>
    127                hello
    128            </other-element>
    129        </template>
    130    </some-element>
    131    <other-element>
    132        world
    133    </other-element>
    134 </div>`;
    135    assert_equals(template.content.querySelector('some-element').__proto__.constructor.name, 'HTMLElement');
    136    assert_equals(template.content.querySelector('other-element').__proto__.constructor.name, 'HTMLElement');
    137    const clone = document.importNode(template.content, {selfOnly: false});
    138    assert_equals(clone.querySelector('some-element').customElementRegistry, window.customElements);
    139    assert_equals(clone.querySelector('some-element').__proto__.constructor.name, 'GlobalSomeElement');
    140    const otherElementInTemplate = clone.querySelector('template').content.querySelector('other-element');
    141    assert_equals(otherElementInTemplate.__proto__.constructor.name, 'HTMLElement');
    142    assert_equals(clone.querySelector('other-element').__proto__.constructor.name, 'GlobalOtherElement');
    143 }, 'importNode should clone a template content with a nested template element using a scoped registry');
    144 
    145 test(() => {
    146    const clone = document.importNode(root);
    147    assert_false(clone.hasChildNodes());
    148 }, "importNode: don't pass options argument");
    149 
    150 test(() => {
    151    const clone = document.importNode(root, false);
    152    assert_false(clone.hasChildNodes());
    153 }, "importNode: pass options argument with value false");
    154 
    155 test(() => {
    156    const clone = document.importNode(root, true);
    157    assert_true(clone.hasChildNodes());
    158 }, "importNode: pass options argument with value true");
    159 
    160 test(() => {
    161    const clone = document.importNode(root, undefined);
    162    assert_false(clone.hasChildNodes());
    163 }, "importNode: pass options argument with value undefined");
    164 
    165 test(() => {
    166    const clone = document.importNode(root, { });
    167    assert_true(clone.hasChildNodes());
    168 }, "importNode: pass options argument with value { }");
    169 
    170 test(() => {
    171    const clone = document.importNode(root, { selfOnly: false });
    172    assert_true(clone.hasChildNodes());
    173 }, "importNode: pass options argument with value { selfOnly: false }");
    174 
    175 test(() => {
    176    const clone = document.importNode(root, { selfOnly: true });
    177    assert_false(clone.hasChildNodes());
    178 }, "importNode: pass options argument with value { selfOnly: true }");
    179 
    180 test(() => {
    181    const clone = document.importNode(root, { customElementRegistry: scopedRegistry });
    182    assert_true(clone.hasChildNodes());
    183 }, "importNode: pass options argument with value { customElementRegistry: scopedRegistry }");
    184 
    185 test(() => {
    186    assert_throws_js(TypeError, () => document.importNode(root, { customElementRegistry: null }));
    187 }, "importNode: pass options argument with value { customElementRegistry: null }");
    188 
    189 </script>
    190 </body>
    191 </html>