tor-browser

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

constructor-reentry-with-different-definition.html (4840B)


      1 <!DOCTYPE html>
      2 <meta name="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
      3 <meta name="assert" content="Custom element constructors can re-enter with different definitions">
      4 <link rel="help" href="https://wicg.github.io/webcomponents/proposals/Scoped-Custom-Element-Registries">
      5 <link rel="help" href="https://github.com/WICG/webcomponents/issues/969">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 
      9 <div id='test-container-1'></div>
     10 <div id='test-container-2'></div>
     11 
     12 <script>
     13 setup({allow_uncaught_exception : true});
     14 
     15 function createShadowForTest(t, customElementRegistry) {
     16  const host = document.createElement('div');
     17  const shadow = host.attachShadow({mode: 'open', customElementRegistry});
     18  document.body.appendChild(host);
     19  t.add_cleanup(() => host.remove());
     20  return shadow;
     21 }
     22 
     23 test(t => {
     24  let needsTest = true;
     25  class ReentryBeforeSuper extends HTMLElement {
     26    constructor() {
     27      if (needsTest) {
     28        needsTest = false;
     29        document.getElementById('test-container-1').innerHTML =
     30            '<test-element-1></test-element-1>';
     31      }
     32      super();
     33    }
     34  };
     35  window.customElements.define('test-element-1', ReentryBeforeSuper);
     36 
     37  let registry = new CustomElementRegistry;
     38  registry.define('shadow-test-element-1', ReentryBeforeSuper);
     39 
     40  let shadow = createShadowForTest(t, registry);
     41  shadow.innerHTML = '<shadow-test-element-1></shadow-test-element-1>';
     42 
     43  let shadowElement = shadow.firstChild;
     44  assert_true(shadowElement instanceof ReentryBeforeSuper);
     45  assert_equals(shadowElement.localName, 'shadow-test-element-1');
     46 
     47  let mainDocElement = document.getElementById('test-container-1').firstChild;
     48  assert_true(mainDocElement instanceof ReentryBeforeSuper);
     49  assert_equals(mainDocElement.localName, 'test-element-1');
     50 }, 'Re-entry via upgrade before calling super()');
     51 
     52 test(t => {
     53  let needsTest = true;
     54  class ReentryAfterSuper extends HTMLElement {
     55    constructor() {
     56      super();
     57      if (needsTest) {
     58        needsTest = false;
     59        document.getElementById('test-container-2').innerHTML =
     60            '<test-element-2></test-element-2>';
     61      }
     62    }
     63  };
     64  window.customElements.define('test-element-2', ReentryAfterSuper);
     65 
     66  let registry = new CustomElementRegistry;
     67  registry.define('shadow-test-element-2', ReentryAfterSuper);
     68 
     69  let shadow = createShadowForTest(t, registry);
     70  shadow.innerHTML = '<shadow-test-element-2></shadow-test-element-2>';
     71 
     72  let shadowElement = shadow.firstChild;
     73  assert_true(shadowElement instanceof ReentryAfterSuper);
     74  assert_equals(shadowElement.localName, 'shadow-test-element-2');
     75 
     76  let mainDocElement = document.getElementById('test-container-2').firstChild;
     77  assert_true(mainDocElement instanceof ReentryAfterSuper);
     78  assert_equals(mainDocElement.localName, 'test-element-2');
     79 }, 'Re-entry via upgrade after calling super()');
     80 
     81 test(t => {
     82  let needsTest = true;
     83  let elementByNestedCall;
     84  class ReentryByDirectCall extends HTMLElement {
     85    constructor() {
     86      if (needsTest) {
     87        needsTest = false;
     88        elementByNestedCall = new ReentryByDirectCall;
     89      }
     90      super();
     91    }
     92  }
     93  window.customElements.define('test-element-3', ReentryByDirectCall);
     94 
     95  let registry = new CustomElementRegistry;
     96  registry.define('shadow-test-element-3', ReentryByDirectCall);
     97 
     98  let shadow = createShadowForTest(t, registry);
     99  shadow.innerHTML = '<shadow-test-element-3></shadow-test-element-3>';
    100 
    101  let shadowElement = shadow.firstChild;
    102  assert_true(shadowElement instanceof ReentryByDirectCall);
    103  assert_equals(shadowElement.localName, 'shadow-test-element-3');
    104 
    105  // Nested constructor call makes the following `super()` fail, and we should
    106  // end up creating only one element.
    107  assert_equals(elementByNestedCall, shadowElement);
    108 }, 'Re-entry via direct constructor call before calling super()');
    109 
    110 test(t => {
    111  let needsTest = true;
    112  let elementByNestedCall;
    113  class ReentryByDirectCall extends HTMLElement {
    114    constructor() {
    115      super();
    116      if (needsTest) {
    117        needsTest = false;
    118        elementByNestedCall = new ReentryByDirectCall;
    119      }
    120    }
    121  }
    122  window.customElements.define('test-element-4', ReentryByDirectCall);
    123 
    124  let registry = new CustomElementRegistry;
    125  registry.define('shadow-test-element-4', ReentryByDirectCall);
    126 
    127  let shadow = createShadowForTest(t, registry);
    128  shadow.innerHTML = '<shadow-test-element-4></shadow-test-element-4>';
    129 
    130  let shadowElement = shadow.firstChild;
    131  assert_true(shadowElement instanceof ReentryByDirectCall);
    132  assert_equals(shadowElement.localName, 'shadow-test-element-4');
    133 
    134  // Nested constructor call should be blocked.
    135  assert_false(elementByNestedCall instanceof ReentryByDirectCall);
    136 }, 'Re-entry via direct constructor call after calling super()');
    137 </script>