tor-browser

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

Element-innerHTML.html (6669B)


      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 <div id="host">
     10    <template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry>
     11        <new-element></new-element>
     12    </template>
     13 </div>
     14 <body>
     15 <script>
     16 
     17 function createConnectedShadowTree(test, customElementRegistry) {
     18    const host = document.createElement('div');
     19    const shadowRoot = host.attachShadow({mode: 'closed', customElementRegistry});
     20    document.body.appendChild(host);
     21    test.add_cleanup(() => host.remove());
     22    return shadowRoot;
     23 }
     24 
     25 class GlobalSomeElement extends HTMLElement { };
     26 customElements.define('some-element', GlobalSomeElement);
     27 
     28 class GlobalOtherElement extends HTMLElement { };
     29 customElements.define('other-element', GlobalOtherElement);
     30 
     31 class WrongNewElement extends HTMLElement{ };
     32 customElements.define('new-element', WrongNewElement);
     33 
     34 test((test) => {
     35    const registry = new CustomElementRegistry;
     36 
     37    class ScopedSomeElement extends HTMLElement { };
     38    registry.define('some-element', ScopedSomeElement);
     39 
     40    class ScopedOtherElement extends HTMLElement { };
     41    registry.define('other-element', ScopedOtherElement);
     42 
     43    const someElement = document.createElement('some-element', {customElementRegistry: registry});
     44    assert_true(someElement instanceof ScopedSomeElement);
     45    someElement.innerHTML = '<other-element></other-element>';
     46    assert_true(someElement.querySelector('other-element') instanceof ScopedOtherElement);
     47 }, 'innerHTML on a disconnected element should use the scoped registry it was created with');
     48 
     49 test((test) => {
     50    const registry = new CustomElementRegistry;
     51 
     52    class ScopedSomeElement extends HTMLElement { };
     53    registry.define('some-element', ScopedSomeElement);
     54 
     55    class ScopedOtherElement extends HTMLElement { };
     56    registry.define('other-element', ScopedOtherElement);
     57 
     58    const someElement = document.createElement('some-element', {customElementRegistry: registry});
     59    assert_true(someElement instanceof ScopedSomeElement);
     60    someElement.innerHTML = `
     61        <other-element id="foo">
     62            <other-element id="bar">
     63                <div id="baz">
     64                    <other-element id="nested-ce"></other-element>
     65                </div>
     66            </other-element>
     67        </other-element>
     68        <div id="bux"></div>
     69        <another-element></another-element>`;
     70 
     71    assert_true(someElement.querySelector('#foo') instanceof ScopedOtherElement);
     72    assert_true(someElement.querySelector('#bar') instanceof ScopedOtherElement);
     73    assert_true(someElement.querySelector('#nested-ce') instanceof ScopedOtherElement);
     74 
     75    assert_true(someElement.querySelector('#foo').customElementRegistry === registry);
     76    assert_true(someElement.querySelector('#bar').customElementRegistry === registry);
     77    assert_true(someElement.querySelector('#baz').customElementRegistry === registry);
     78    assert_true(someElement.querySelector('#nested-ce').customElementRegistry === registry);
     79    assert_true(someElement.querySelector('#bux').customElementRegistry === registry);
     80    assert_true(someElement.querySelector('another-element').customElementRegistry === registry);
     81 }, 'nested descendants in innerHTML on a disconnected element should use the scoped registry the element was created with');
     82 
     83 test((test) => {
     84    const registry = new CustomElementRegistry;
     85 
     86    class ScopedSomeElement extends HTMLElement { };
     87    registry.define('some-element', ScopedSomeElement);
     88 
     89    const div = document.createElement('div', {customElementRegistry: registry});
     90    div.innerHTML = '<span></span>';
     91    assert_equals(div.querySelector('span').customElementRegistry, registry);
     92 }, 'innerHTML on a disconnected element should use the scoped registry it was created with when parsing a simple HTML');
     93 
     94 test((test) => {
     95    const registry1 = new CustomElementRegistry;
     96    const registry2 = new CustomElementRegistry;
     97 
     98    class ScopedSomeElement extends HTMLElement { };
     99    registry1.define('some-element', ScopedSomeElement);
    100 
    101    class ScopedOtherElement1 extends HTMLElement { };
    102    registry1.define('other-element', ScopedOtherElement1);
    103    class ScopedOtherElement2 extends HTMLElement { };
    104    registry2.define('other-element', ScopedOtherElement2);
    105 
    106    const shadowRoot1 = createConnectedShadowTree(test, registry1);
    107    const shadowRoot2 = createConnectedShadowTree(test, registry2);
    108    const someElement = document.createElement('some-element', {customElementRegistry: registry1});
    109    someElement.innerHTML = '<other-element></other-element>';
    110    assert_true(someElement.querySelector('other-element') instanceof ScopedOtherElement1);
    111    shadowRoot2.appendChild(someElement);
    112    someElement.innerHTML = '<other-element></other-element>';
    113    assert_true(someElement.querySelector('other-element') instanceof ScopedOtherElement1);
    114    someElement.remove();
    115    someElement.innerHTML = '<other-element></other-element>';
    116    assert_true(someElement.querySelector('other-element') instanceof ScopedOtherElement1);
    117 }, 'innerHTML on an inserted element should continue to use the scoped registry it was created with');
    118 
    119 test((test) => {
    120    const shadowRoot = host.cloneNode(true).shadowRoot;
    121    const container_element = shadowRoot.lastElementChild;
    122    assert_equals(container_element.customElementRegistry, null);
    123    assert_false(container_element instanceof WrongNewElement);
    124 
    125    container_element.innerHTML = '<new-element><new-element></new-element></new-element>';
    126    const outer_element = container_element.querySelector('new-element');
    127    const inner_element = outer_element.querySelector('new-element');
    128    assert_equals(outer_element.customElementRegistry, null);
    129    assert_false(outer_element instanceof WrongNewElement);
    130    assert_equals(inner_element.customElementRegistry, null);
    131    assert_false(inner_element instanceof WrongNewElement);
    132 }, 'nested descendants in innerHTML should use the null registry when the container element has null registry');
    133 
    134 test((test) => {
    135    const shadowRoot = host.cloneNode(true).shadowRoot;
    136    shadowRoot.firstElementChild.insertAdjacentHTML('afterend', '<new-element></new-element>');
    137    const container_element = shadowRoot.lastElementChild;
    138    assert_equals(container_element.customElementRegistry, null);
    139    assert_false(container_element instanceof WrongNewElement);
    140 }, 'insertAdjacentHTML should use the element\'s registry even when the registry is null');
    141 
    142 </script>
    143 </body>
    144 </html>