tor-browser

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

form.html (9408B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <script src="/resources/testharness.js"></script>
      5  <script src="/resources/testharnessreport.js"></script>
      6  <script src="/resources/testdriver.js"></script>
      7  <script src="/resources/testdriver-vendor.js"></script>
      8  <script src="/resources/testdriver-actions.js"></script>
      9 </head>
     10 
     11 <body>
     12  <div>
     13    <template shadowrootmode="open">
     14      <!-- This button shouldn't link to the real form in fancy-form-1 as it's in a different tree scope -->
     15      <button id="button-in-shadow" form="fancy-form-1"></button>
     16    </template>
     17  </div>
     18 
     19  <button id="reset-button-1" type="reset" form="fancy-form-1"></button>
     20  <fancy-form-1 id="fancy-form-1">
     21    <template shadowrootmode="open" shadowrootreferencetarget="real-form">
     22      <form id="real-form">
     23        <input type="text" value="default value">
     24      </form>
     25    </template>
     26  </fancy-form-1>
     27 
     28  <button id="reset-button-2" type="reset" form="fancy-form-2"></button>
     29  <fancy-form-2 id="fancy-form-2"></fancy-form-2>
     30  <script>
     31    const fancyForm2 = document.querySelector('fancy-form-2');
     32    fancyForm2.attachShadow({ mode: 'open', referenceTarget: 'real-form' });
     33    fancyForm2.shadowRoot.innerHTML = '<form id="real-form"><input type="text" value="default value"></form>';
     34  </script>
     35 
     36  <button id="reset-button-3" type="reset"></button>
     37  <fancy-form-3 id="fancy-form-3">
     38    <template shadowrootmode="open" shadowrootreferencetarget="real-form">
     39      <form id="real-form">
     40        <input type="text" value="default value">
     41      </form>
     42    </template>
     43  </fancy-form-3>
     44 
     45  <script>
     46    function testFormWithReferenceTarget(formId, resetButtonId, name) {
     47      test(function () {
     48        const fancyForm = document.getElementById(formId);
     49        const realForm = fancyForm.shadowRoot.getElementById("real-form");
     50        const input = realForm.firstElementChild;
     51 
     52        input.value = "new value";
     53        const resetButton = document.getElementById(resetButtonId);
     54        assert_equals(realForm.elements.length, 2, "The .elements property should have 2 elements.");
     55        assert_equals(realForm.elements[0], resetButton, "The first element should be the referencing element.");
     56        assert_equals(realForm.elements[1], input, "The 2nd element should be the input inside the real form.");
     57        assert_equals(input.value, "new value", "The input value should be updated to the new value.");
     58        resetButton.click();
     59        assert_equals(input.value, "default value", "The input value should be reset to the default value.");
     60      }, name);
     61    }
     62 
     63    testFormWithReferenceTarget('fancy-form-1', 'reset-button-1', "Reference target works with form attribute.");
     64    testFormWithReferenceTarget('fancy-form-2', 'reset-button-2', "Reference target works with form attribute via options.");
     65 
     66    document.getElementById('reset-button-3').setAttribute('form', "fancy-form-3");
     67    testFormWithReferenceTarget('fancy-form-3', 'reset-button-3', "Reference target works with setAttribute('form')");
     68  </script>
     69 
     70  <form-associated-custom-button id="custom-button" form="fancy-form-4"></form-associated-custom-button>
     71  <fancy-form-4 id="fancy-form-4">
     72    <template shadowrootmode="open" shadowrootreferencetarget="real-form">
     73      <form id="real-form">
     74        <input type="text" value="default value">
     75        <!-- The internal button of the custom button below shouldn't be associated with real-form -->
     76        <form-associated-custom-button id="custom-button-in-shadow"></form-associated-custom-button>
     77      </form>
     78    </template>
     79  </fancy-form-4>
     80  <script>
     81    class FormAssociatedCustomButton extends HTMLElement {
     82      static formAssociated = true;
     83      constructor() {
     84        super();
     85        this.internals_ = this.attachInternals();
     86        const shadow = this.attachShadow({ mode: 'open' });
     87        shadow.innerHTML = `<button>fancy button</button>`;
     88      }
     89    }
     90    window.customElements.define("form-associated-custom-button", FormAssociatedCustomButton);
     91    test(function () {
     92        const customElement = document.getElementById("custom-button");
     93        const fancyForm = document.getElementById("fancy-form-4");
     94        const realForm = fancyForm.shadowRoot.getElementById("real-form");
     95        const customElementInShadow = fancyForm.shadowRoot.getElementById("custom-button-in-shadow");
     96        const input = realForm.firstElementChild;
     97 
     98        assert_equals(realForm.elements.length, 3, "The .elements property should have 3 elements.");
     99        assert_equals(realForm.elements[0], customElement, "The first element should be the form-associated custom element.");
    100        assert_equals(realForm.elements[1], input, "The 2nd element should be the input inside the real form.");
    101        assert_equals(realForm.elements[2], customElementInShadow, "The 3rd element should be the custom element inside the real form.");
    102 
    103        // Swap the input and the custom element in real-form.
    104        realForm.moveBefore(customElementInShadow, input);
    105        assert_equals(realForm.elements.length, 3, "The .elements property should have 3 elements.");
    106        assert_equals(realForm.elements[0], customElement, "The first element should be the form-associated custom element.");
    107        assert_equals(realForm.elements[1], customElementInShadow, "The 2nd element should be the custom element inside the real form.");
    108        assert_equals(realForm.elements[2], input, "The 3rd element should be the input inside the real form.");
    109 
    110        // Swap the referencing element and the fancy form
    111        customElement.parentNode.moveBefore(fancyForm, customElement);
    112        assert_equals(realForm.elements.length, 3, "The .elements property should have 3 elements.");
    113        assert_equals(realForm.elements[0], customElementInShadow, "The first element should be the custom element inside the real form.");
    114        assert_equals(realForm.elements[1], input, "The 2nd element should be the input inside the real form.");
    115        assert_equals(realForm.elements[2], customElement, "The 3rd element should be the form-associated custom element.");
    116      }, "Reference target works with form-associated custom element.");
    117  </script>
    118 
    119  <button id="reset-button-5" type="reset" form="fancy-form-5"></button>
    120  <fancy-form-5 id="fancy-form-5">
    121    <template shadowrootmode="open" shadowrootreferencetarget="nested-element">
    122      <nested-element id="nested-element">
    123        <template shadowrootmode="open" shadowrootreferencetarget="real-form">
    124          <form id="real-form">
    125            <input type="text" value="default value">
    126          </form>
    127        </template>
    128      </nested-element>
    129      <button id="button-in-shadow" form="nested-element"></button>
    130      <div>
    131        <template shadowrootmode="open">
    132          <!-- This button shouldn't link to the real form in nested-element as it's in a different tree scope -->
    133          <button id="button-in-different-shadow" form="nested-element"></button>
    134        </template>
    135      </div>
    136    </template>
    137  </fancy-form-5>
    138  <script>
    139      test(function () {
    140        const fancyForm = document.getElementById("fancy-form-5");
    141        const nestedElement = fancyForm.shadowRoot.getElementById("nested-element");
    142        const buttonInShadow = fancyForm.shadowRoot.getElementById("button-in-shadow");
    143        const realForm = nestedElement.shadowRoot.getElementById("real-form");
    144        const input = realForm.firstElementChild;
    145 
    146        input.value = "new value";
    147        const resetButton = document.getElementById("reset-button-5");
    148        assert_equals(realForm.elements.length, 3, "The .elements property should have 3 elements.");
    149        // The elements in .elements property should be in tree order (preorder, depth-first).
    150        assert_equals(realForm.elements[0], resetButton, "The first element should be the referencing element.");
    151        assert_equals(realForm.elements[1], input, "The 2nd element should be the input inside the real form.");
    152        assert_equals(realForm.elements[2], buttonInShadow, "The 3rd element should be the button in the shadow dom.");
    153        assert_equals(input.value, "new value", "The input value should be updated to the new value.");
    154        resetButton.click();
    155        assert_equals(input.value, "default value", "The input value should be reset to the default value.");
    156 
    157        // Remove the button that's using reference target in the 1st level shadow.
    158        buttonInShadow.remove();
    159        assert_equals(realForm.elements.length, 2, "The .elements property should have 2 elements after removing the button.");
    160 
    161        // Add a new button using reference target in the 1st level shadow.
    162        const newButtonInShadow = document.createElement("button");
    163        newButtonInShadow.setAttribute("form", "nested-element");
    164        nestedElement.parentNode.insertBefore(newButtonInShadow, nestedElement);
    165        assert_equals(realForm.elements.length, 3, "The .elements property should have 3 elements after a new button is inserted.");
    166        assert_equals(realForm.elements[0], resetButton, "The first element should be the referencing element.");
    167        assert_equals(realForm.elements[1], newButtonInShadow, "The 2nd element should be the button in the shadow dom.");
    168        assert_equals(realForm.elements[2], input, "The 3rd element should be the input inside the real form.");
    169      }, "Reference target works with nested shadow trees.");
    170  </script>
    171 </body>
    172 </html>