tor-browser

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

newtarget.html (4612B)


      1 <!DOCTYPE html>
      2 <title>Custom Elements: [HTMLConstructor] derives prototype from NewTarget</title>
      3 <meta name="author" title="Domenic Denicola" href="mailto:d@domenic.me">
      4 <meta name="help" content="https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="../resources/custom-elements-helpers.js"></script>
      8 <body>
      9 <script>
     10 "use strict";
     11 
     12 test_with_window(w => {
     13  let beforeDefinition = true;
     14  const proto1 = { "proto": "number one" };
     15  const proto2 = { "proto": "number two" };
     16 
     17  function TestElement() {
     18    const o = Reflect.construct(w.HTMLElement, [], new.target);
     19    assert_equals(Object.getPrototypeOf(o), proto2,
     20      "Must use the value returned from new.target.prototype");
     21    assert_not_equals(Object.getPrototypeOf(o), proto1,
     22      "Must not use the prototype stored at definition time");
     23  }
     24 
     25  const ElementWithDynamicPrototype = new Proxy(TestElement, {
     26      get: function (target, name) {
     27        if (name == "prototype")
     28          return beforeDefinition ? proto1 : proto2;
     29        return target[name];
     30      }
     31  });
     32 
     33  w.customElements.define("test-element", ElementWithDynamicPrototype);
     34 
     35  beforeDefinition = false;
     36  new ElementWithDynamicPrototype();
     37 }, "Use NewTarget's prototype, not the one stored at definition time");
     38 
     39 test_with_window(w => {
     40  // We have to not throw during define(), but throw during super()
     41  let throws = false;
     42 
     43  let err = { name: "prototype throws" };
     44  function TestElement() {
     45    throws = true;
     46    assert_throws_exactly(err, () => {
     47      Reflect.construct(w.HTMLElement, [], new.target);
     48    });
     49  }
     50 
     51  const ElementWithDynamicPrototype = new Proxy(TestElement, {
     52    get: function (target, name) {
     53      if (throws && name == "prototype")
     54        throw err;
     55      return target[name];
     56    }
     57  });
     58 
     59  w.customElements.define("test-element", ElementWithDynamicPrototype);
     60 
     61  new ElementWithDynamicPrototype();
     62 
     63 }, "Rethrow any exceptions thrown while getting the prototype");
     64 
     65 [null, undefined, 5, "string"].forEach(function (notAnObject) {
     66  test_with_window(w => {
     67    // We have to return an object during define(), but not during super()
     68    let returnNotAnObject = false;
     69 
     70    function TestElement() {
     71      const o = Reflect.construct(w.HTMLElement, [], new.target);
     72 
     73      assert_equals(Object.getPrototypeOf(new.target), window.Function.prototype);
     74      assert_equals(Object.getPrototypeOf(o), window.HTMLElement.prototype,
     75        "Must use the HTMLElement from the realm of NewTarget");
     76      assert_not_equals(Object.getPrototypeOf(o), w.HTMLElement.prototype,
     77        "Must not use the HTMLElement from the realm of the active function object (w.HTMLElement)");
     78 
     79      return o;
     80    }
     81 
     82    const ElementWithDynamicPrototype = new Proxy(TestElement, {
     83      get: function (target, name) {
     84        if (name == "prototype")
     85          return returnNotAnObject ? notAnObject : {};
     86        return target[name];
     87      }
     88    });
     89 
     90    w.customElements.define("test-element", ElementWithDynamicPrototype);
     91 
     92    returnNotAnObject = true;
     93    new ElementWithDynamicPrototype();
     94  }, "If prototype is not object (" + notAnObject + "), derives the fallback from NewTarget's realm (autonomous custom elements)");
     95 
     96  test_with_window(w => {
     97    // We have to return an object during define(), but not during super()
     98    let returnNotAnObject = false;
     99 
    100    function TestElement() {
    101      const o = Reflect.construct(w.HTMLElement, [], new.target);
    102 
    103      assert_equals(Object.getPrototypeOf(new.target), window.Function.prototype);
    104      assert_equals(Object.getPrototypeOf(o), window.HTMLElement.prototype,
    105        "Must use the HTMLElement from the realm of NewTarget");
    106      assert_not_equals(Object.getPrototypeOf(o), w.HTMLElement.prototype,
    107        "Must not use the HTMLElement from the realm of the active function object (w.HTMLElement)");
    108 
    109      return o;
    110    }
    111 
    112    // Create the proxy in the subframe, which should not affect what our
    113    // prototype ends up as.
    114    const ElementWithDynamicPrototype = new w.Proxy(TestElement, {
    115      get: function (target, name) {
    116        if (name == "prototype")
    117          return returnNotAnObject ? notAnObject : {};
    118        return target[name];
    119      }
    120    });
    121 
    122    w.customElements.define("test-element", ElementWithDynamicPrototype);
    123 
    124    returnNotAnObject = true;
    125    new ElementWithDynamicPrototype();
    126  }, "If prototype is not object (" + notAnObject + "), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)");
    127 });
    128 
    129 </script>
    130 </body>