tor-browser

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

dynamic-module-map-key.html (4004B)


      1 <!DOCTYPE html>
      2 <html>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script>
      6  const dynamicScript = document.createElement("script");
      7  dynamicScript.type = "importmap";
      8  dynamicScript.innerText = "{ \"imports\": { \"./resources/log.js?pipe=sub&name=A\": \"./resources/log.js?pipe=sub&name=B\" } }";
      9  document.head.appendChild(dynamicScript);
     10 </script>
     11 
     12 <script>
     13 let log = [];
     14 
     15 promise_test(() => {
     16  return import("./resources/log.js?pipe=sub&name=A")
     17    .then(() => import("./resources/log.js?pipe=sub&name=B"))
     18    .then(() => assert_array_equals(log, ["log:B"]))
     19  },
     20  "Module map's key is the URL after import map resolution");
     21 </script>
     22 
     23 <script>
     24  // Ensure that the Already Started flag is passed through to clones,
     25  // ensuring the type cannot be changed after it is set to true.
     26  const dynamicScriptTypeStatic = document.createElement("script");
     27  dynamicScriptTypeStatic.type = "text/javascript";
     28  dynamicScriptTypeStatic.type = "importmap";
     29  dynamicScriptTypeStatic.innerText = "{ \"imports\": { \"./resources/log.js?pipe=sub&name=C\": \"./resources/log.js?pipe=sub&name=D\" } }";
     30  document.head.appendChild(dynamicScriptTypeStatic);
     31 
     32  // Because the contents aren't empty, once it's connected as an import
     33  // map, the Already Started flag is set to true and it can't be changed
     34  // into a classic script.
     35  document.head.removeChild(dynamicScriptTypeStatic);
     36  dynamicScriptTypeStatic.type = "text/javascript";
     37  dynamicScriptTypeStatic.innerText = "test(function() { assert_unreached('Script should not be able to execute after Already Started is set.'); }";
     38  document.head.appendChild(dynamicScriptTypeStatic);
     39 
     40  // The Already Started flag is copied through to clones, even though
     41  // `type` is set to "text/javascript" when it is connected.
     42  const clonedScriptNode = dynamicScriptTypeStatic.cloneNode(/*deep=*/true);
     43  test(function() {
     44    assert_equals(clonedScriptNode.type, "text/javascript");
     45    assert_equals(clonedScriptNode.innerText, "test(function() { assert_unreached('Script should not be able to execute after Already Started is set.'); }");
     46  }, "Cloned script node copies attribute and text content.");
     47  document.head.appendChild(clonedScriptNode);
     48 
     49  // Script tags with empty contents do not set Already Started to true,
     50  // so the type can be changed later and on clones, even if they have
     51  // been connected.
     52  const dynamicScriptEmpty = document.createElement("script");
     53  dynamicScriptEmpty.type = "importmap";
     54  document.head.appendChild(dynamicScriptEmpty);
     55  document.head.removeChild(dynamicScriptEmpty);
     56 
     57  // The Already Started flag is copied onto clones.
     58  dynamicScriptEmpty.type = "text/javascript";
     59  const clonedEmptyScript = dynamicScriptEmpty.cloneNode(/*deep=*/true);
     60  test(function() {
     61    assert_equals(clonedEmptyScript.type, "text/javascript");
     62    assert_equals(clonedEmptyScript.innerText, "");
     63  }, "Cloned script node copies attributes and text content.");
     64 
     65  // Because Already Started is false, The clone can be set to a different
     66  // type than the original element and both can be inserted as their
     67  // respective types.
     68  clonedEmptyScript.setAttribute("type", "importmap");
     69  clonedEmptyScript.innerText = "{ \"imports\": { \"./resources/log.js?pipe=sub&name=E\": \"./resources/log.js?pipe=sub&name=F\" } }";
     70  document.head.appendChild(clonedEmptyScript);
     71 
     72  const t_evaluate = async_test("The Already Started flag is set when a non-empty <script> tag is connected.");
     73  dynamicScriptEmpty.innerText = "t_evaluate.done();";
     74  document.head.appendChild(dynamicScriptEmpty);
     75 </script>
     76 
     77 <script>
     78 promise_test(() => {
     79  return import("./resources/log.js?pipe=sub&name=C")
     80    .then(() => import("./resources/log.js?pipe=sub&name=D"))
     81    .then(() => import("./resources/log.js?pipe=sub&name=E"))
     82    .then(() => assert_array_equals(log, ["log:B", "log:D", "log:F"]))
     83  },
     84  "The script tag's Already Started flag is passed to clones.");
     85 </script>
     86 </html>