summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/scripting-1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/html/semantics/scripting-1
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/semantics/scripting-1')
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/META.yml2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/non-html-noscript.html16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/README.md16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm38
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm43
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm46
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm49
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm47
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-2.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-bom.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/content-type-checking.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/cors-crossorigin-requests.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/credentials.sub.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/css-module-worker-test.html54
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-basic.html83
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-dynamic.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/integrity.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/load-error-events.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/referrer-policies.sub.html84
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/relative-urls.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/atImported.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bad-import.css4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic-large.css7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16be.cssbin0 -> 64 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16le.cssbin0 -> 64 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-8.css1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/credentials-iframe.sub.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-parse-error-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-without-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/css-module-without-assertion-iframe.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-matches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-mismatches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-error-events.py14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-relative-url.css5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/malformed.css7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/parse-error.css2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/record-fetch.py20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/utf-8.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/windows-1250.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker-dynamic-import.sub.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker.sub.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/script-element-css-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-2.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-bom.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test.html54
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html83
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/integrity.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html84
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/relative-urls.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/atImported.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic-large.css7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16be.cssbin0 -> 64 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16le.cssbin0 -> 64 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-8.css1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-without-attribute-iframe.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-relative-url.css5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/record-fetch.py20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker-dynamic-import.sub.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker.sub.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/data-url.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/README.md7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script-2.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script-xml.xhtml40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/document-write.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/async-script-1.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-1.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-2.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write-close.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-close.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-iframe.sub.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/helper.js17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-1.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-2.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/support/async-script.html44
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/emptyish-script-elements.html75
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/001.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/002.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/003.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/004.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/005.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/006.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/007.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/008.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/009.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/010.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/011.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/012.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/013.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/014.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015a.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/016.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/017.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/018.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/019.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/020.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/021.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/022.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/023.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/024.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/025.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/026.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/027.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/028.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/030.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/031.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/032.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/033.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/034.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/035.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/036.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/037.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/038.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/039.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/040.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/041.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/046.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/047.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/048.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/049.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/050.html50
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/051.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/052.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/053.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/056.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/057.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/059.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/060.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/061.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/062.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/063.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/064.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/065.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/066.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/067.html38
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/068.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/069.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/070.html48
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/071.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/072.html50
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/073.html52
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/074.html49
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/075.html42
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/076.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/077.html41
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/078.html44
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/079.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/081.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/082.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/083.html48
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/084.html47
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/085.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/086.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/087.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/088.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/089.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/090.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/091.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/092.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/094.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/095.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/096.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/097.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/099.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/101.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/102.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/103.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/104.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/105.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-import.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-noimport.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-import.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-import.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-noimport.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-noimport.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import-xhtml.xhtml20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-import.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-noimport.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport-xhtml.xhtml20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-import.html21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-noimport.html21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/108.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/109.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/110.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/111.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/112.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/113.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/114.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/115.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/116.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/117.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/118.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/119.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/120.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/121.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/122.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/123.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/124.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/125.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/126.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/127.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/128.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/129.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/130.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/131.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/132.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/133.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/134.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/135.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/136.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/137.html21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/138.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/139.html30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/140.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/141.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/142.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/143.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/144.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/145.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146-href.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/147.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/148.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/149.html59
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import-xhtml.xhtml21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport-xhtml.xhtml20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/background.css1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/import.css1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/non-external-no-import.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld-postMessage.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/check-style-sheet.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/count-script-tags.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-body.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-foo.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-1.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-10.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-11.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-2.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-3.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-4.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-5.js7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-6.js6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-7.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-8.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-9.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/testlib/testlib.js43
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html53
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any.js18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-type-assertion.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/export-hello.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/hello.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-import-errors-order.html36
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion-error.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/javascript-type-assertion.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/js-type-assertion.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/dynamic-import-with-attributes-argument.any.js18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-type-attribute.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/export-hello.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/hello.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-import-errors-order.html36
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute-error.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/javascript-type-attribute.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/js-type-attribute.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-script-goal.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/array.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16be.jsonbin0 -> 40 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16le.jsonbin0 -> 40 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-8.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-2.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-bom.any.js17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cors-crossorigin-requests.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials-iframe.sub.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials.sub.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-parse-error-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-without-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/false.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-matches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-mismatches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/invalid-content-type.any.js17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/json-module-service-worker-test.https.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.py14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.json3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/non-object.any.js14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/null.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.html21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-policies.sub.html84
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/repeated-imports.any.js65
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/script-element-json-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker-dynamic-import.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/string.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/true.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/utf-8.json4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/valid-content-type.html46
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/windows-1250.json4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.jsonbin0 -> 40 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.jsonbin0 -> 40 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html33
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html84
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js65
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html46
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-1.html68
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror-module.html9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror.html9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.js40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-importScripts.any.js11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-static-import.any.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-importScripts.any.js22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-static-import.any.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.any.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.html8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.any.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.html8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-4.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker-module.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event.js89
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow-setup.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw-setup.js10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2-setup.js10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.1.mjs8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.2.mjs7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3-setup.js7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.1.mjs11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.2.mjs5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.1.mjs8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.2.mjs5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-setup.js30
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/resolve-then-throw.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/bad-module-specifier.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-01.html52
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-02.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-03.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html38
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-1.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-2.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html68
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-common.js8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-different.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-missingheader.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-same.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-wrongheader.sub.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-different.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-missingheader.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-same.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-wrongheader.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin.html43
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentScript-null.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentscript.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access-a.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable-a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-1.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-2.html23
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker-importScripts.html7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker.sub.html8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url.sub.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/code-cache.js9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/import.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/worker-importScripts.sub.js15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/code-cache.js9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/import.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/redirect.py19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url-workers.window.js60
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js66
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-base-url.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-nonce.html43
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/delay-load-event.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials-setTimeout.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html61
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-script-error.html53
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js58
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/code-cache.js9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/import.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/inline-event-handler.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.js32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/css-import-in-worker.any.js14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.css4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/serviceworker.any.js14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/ticker.js13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/with-import-assertions.any.js15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet-ref.https.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet.https.html43
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-classic-manual.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-module-manual.html55
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-classic.html5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-module.html5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external.js7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-classic.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-module.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/blob-url-worker.js11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce-iframe.sub.html4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce.js4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/empty-iframe.html9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/status-changing-script.py18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache-iframe.sub.html9
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache.js74
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/Function.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/eval.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/inline-event-handlers-UA-code.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/no-active-script.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/reflected-inline-event-handlers.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/setTimeout.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html63
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html64
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html73
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html73
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-classic.html54
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-module.html54
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html104
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html103
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html83
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-other-document.html79
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/v8-code-cache.html42
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-common.js10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.html16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-root.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype-import.js8
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype.js7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling.html60
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered2.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered3.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered4.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered1.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered2.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered2.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered4.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered1.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered2.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder.html106
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-default.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something-nested.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-1.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-dependent.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-object.any.js20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html57
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.js77
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.any.js38
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html34
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/postmessage-worker.js12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-1.mjs1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-2.mjs1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-import-meta.mjs2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/store-import-meta.html5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-something-namespace.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-a.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-b.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle.js6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-ab.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self-inner.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self.js6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports.html64
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-onload.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-defer-onload.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-no-async-onload.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-2.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-3.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4b.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4c.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4d.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5b.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5c.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5d.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5e.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6.html36
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6b.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6c.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6d.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7.html37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7a.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7b.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7c.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7d.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7e.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7f.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-8.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches-inner.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-namespace-request.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-star-export-request.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events-inline.html61
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events.html61
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export-nested.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.html48
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-1.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-2.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-a.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-b.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-c.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-d.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-e.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-f.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-g.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-h.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports.html29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-missing-export.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nomodule-attribute.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html68
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html82
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html71
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-policy-for-descendants.sub.html122
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html77
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-strict-policies.sub.html38
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html81
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/500-but-js.asis4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html50
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-helper.sub.js67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html51
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-setTimeout-iframe.sub.html56
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/fast-module.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8-with-charset-header.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js.headers1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js.headers1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-remote-origin-referrer-checker.sub.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-404-but-js.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-500-but-js.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-b-cross-origin.sub.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/slow-module.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/script-for-event.html93
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/set-currentScript-on-window.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-1.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-2.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-cycle.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/specifier-error.html22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror-nested.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this-nested.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-error.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-nested.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw2.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked.any.js11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-get-sync.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-set-async.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__parent.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-get-sync.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-set-async.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__parent.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/type.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents-during-evaluation.html59
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/README.md16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-module.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-inline-classic.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/README.md6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-1.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-2.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-iframe.html4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/helper.js31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/in-order.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/parser-blocking.html41
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-helper.js214
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py102
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/slow-flag-setter.py29
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/tools/generate.py61
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors-iframe.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors.sub.html85
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-reflect.html75
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html63
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script.html28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts.html56
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-module-script.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html41
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/promise-reject-and-remove.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16be.jsbin0 -> 156 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16le.jsbin0 -> 156 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-8.js2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cocoa-module.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/exports-cocoa.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/flag-setter.js3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events-helpers.js47
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events.py15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/promise-reject-and-remove-iframe.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/script-type-and-language-js.js141
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/set-script-executed.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/syntax-error.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/throw.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html89
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html41
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.sub.html120
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer-xhtml.xhtml31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html93
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml36
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-referrerpolicy-idl.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-supports.html52
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications-csp.html52
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html72
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-empty.html48
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-svg.svg37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml.xhtml42
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js.html35
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-with-params.html41
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-whitespace.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-json-then-js.py21
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html150
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/tag-name.xhtml16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html102
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html71
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html82
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html126
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html83
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html44
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html172
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html105
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html70
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html114
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html192
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html135
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-construction-in-inactive-document-crash.html5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy.html81
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html59
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html63
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html62
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-element-clone-into-inactive-document-crash.html7
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-set-inner-html-in-inactive-document-crash.html6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-table-crash.html13
909 files changed, 20456 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/META.yml b/testing/web-platform/tests/html/semantics/scripting-1/META.yml
new file mode 100644
index 0000000000..0f3cf59653
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/META.yml
@@ -0,0 +1,2 @@
+suggested_reviewers:
+ - domenic
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/non-html-noscript.html b/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/non-html-noscript.html
new file mode 100644
index 0000000000..2f85d1d47d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/non-html-noscript.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>noscript rules don't apply to non-html elements</title>
+<link rel="author" title="Emilio Cobos Ãlvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-noscript-element">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1470150">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+test(function() {
+ let non_html_noscript = document.createElementNS("http://www.w3.org/2000/svg", "noscript");
+ document.body.appendChild(non_html_noscript);
+ assert_not_equals(getComputedStyle(non_html_noscript).display, "none");
+}, "Non-HTML <noscript> element shouldn't be undisplayed by a UA rule");
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/README.md b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/README.md
new file mode 100644
index 0000000000..ab4a4820af
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/README.md
@@ -0,0 +1,16 @@
+# Script tests
+
+## Import attributes & JSON/CSS modules
+
+The import attributes proposal changed the keyword from `assert` to `with`, after that it was already been implemented and shipped in some browsers. Thus, there are some implementations that only support the `assert` syntax and others that only support the `with` syntax.
+
+For this reason, the import attributes, JSON modules and CSS modules are duplicated to use both keywords:
+| `with` keyword | `assert` keyword |
+|:----------------------|:---------------------------|
+| `./import-attributes` | `./import-assertions` |
+| `./json-module` | `./json-module-assertions` |
+| `./css-module` | `./css-module-assertions` |
+
+All changes in one folder should be reflected in the corresponding folder, because the two syntaxes have the same semantics.
+
+The web compatibility of removing the `assert` keyword is being investigated. If it will be deemed feasible, it will be removed from the proposal and the `assert` tests can be deleted.
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm
new file mode 100644
index 0000000000..370152683b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Async property on a dynamically-created script is true by default</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test checks the Async property on a dynamically-created script element. By default it should be true." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ test(function() {assert_true(document.createElement("script").async)}, "Async property on a dynamically-created script is true by default");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm
new file mode 100644
index 0000000000..e1850ff6e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Changes to the 'async' attribute are reflected in the async property</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures changes to the 'async' attribute are reflected in the async property." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ test(function() {
+ var s = document.createElement("script");
+ s.async = false;
+ s.setAttribute('async', ''); /*Should change s.async to true*/
+ assert_true(s.async)
+ }, "Test 'async' attribute are reflected in the async property with setAttribute");
+
+ test(function() {
+ var s = document.createElement("script");
+ s.async = false;
+ s.setAttribute('async', ''); /*Should change s.async to true*/
+ s.removeAttribute('async'); /*Should change s.async to false*/
+ assert_false(s.async)
+ }, "Test 'async' attribute are reflected in the async property with removeAttribute");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm
new file mode 100644
index 0000000000..c6d84f9a87
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An async script does not block the parser while downloading</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script does not block the parser while downloading." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("An async script does not block the parser while downloading");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "21")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script src="log.py?sec=3&id=1" async></script>
+ <script>
+ log('2');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm
new file mode 100644
index 0000000000..5d9df099b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An async script executes as soon as possible after a download is complete</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script executes as soon as possible after a download is complete." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("async script executes as soon as possible after a download is complete");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "21")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script src="log.py?sec=3&id=1" async></script>
+ <script src="log.py?sec=1&id=2" async></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm
new file mode 100644
index 0000000000..03f9adeb67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>A script element with both async and defer set should execute asynchronously</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures a script element with both async and defer set should execute asynchronously." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("A script element with both async and defer set should execute asynchronously");
+
+ function timeout()
+ {
+ t.step(function(){
+ var actual = document.getElementById("testresult").innerHTML;
+ assert_in_array(actual, ["2134", "2341"]);
+ });
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 5000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script type="text/javascript" src="log.py?sec=1&id=1" defer async></script>
+ <script type="text/javascript">log('2');</script>
+ <script type="text/javascript" src="log.py?sec=3&id=3"></script>
+ <script type="text/javascript">log('4');</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm
new file mode 100644
index 0000000000..ed3d8b22c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>A dynamically created external script executes asynchronously</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures a dynamically created external script executes asynchronously." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#force-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("dynamically created external script executes asynchronously");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "321")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var one = document.createElement("script");
+ one.src="log.py?sec=3&id=1";
+ document.head.appendChild(one);
+
+ var two = document.createElement("script");
+ two.src="log.py?sec=1&id=2";
+ document.head.appendChild(two);
+
+ log('3');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm
new file mode 100644
index 0000000000..6c4ae29e06
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Ordered async script execution when script.async == false</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures Ordered async script execution when script.async == false" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#script-processing-src-sync"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("Ordered async script execution when script.async == false");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "312")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var one = document.createElement("script");
+ one.src="log.py?sec=3&id=1";
+ one.async = false;
+ document.head.appendChild(one);
+
+ var two = document.createElement("script");
+ two.src="log.py?sec=1&id=2";
+ two.async = false;
+ document.head.appendChild(two);
+ </script>
+ <script type="text/javascript">
+ log('3');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm
new file mode 100644
index 0000000000..73529cc318
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Async script element execution delays the window's load event</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script element's execution delays the window's load event." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#delay-the-load-event"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("Async script element execution delays the window's load event");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "213")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ window.addEventListener("load", function() {
+ log("3");
+ timeout();
+ }, false);
+
+ var s1 = document.createElement("script");
+ s1.src = "log.py?sec=2&id=1";
+ document.head.appendChild(s1);
+ </script>
+ <script type="text/javascript">
+ log('2');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm
new file mode 100644
index 0000000000..307aa46412
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Document.write() silently fails from an Async script</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures Document.write() silently fails from an Async script." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+ var t = async_test("Document.write() silently fails from an Async script");
+
+ var log = t.step_func(function() {
+ document.write("<span id='writtenText'></span>");
+ assert_equals(null, document.getElementById('writtenText'));
+ t.done();
+ });
+ </script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript" src="log.py?sec=1&id=1" async></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm
new file mode 100644
index 0000000000..c54defc00d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Removing an async script before execution</title>
+ <meta name="timeout" content="long">
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures that an async script still executes if it is removed from a markup before the download is complete. The other two scripts that come after it in insertion order should execute as well." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+ var t = async_test("Removing an async script before execution");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "4123")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+ </head>
+ <body>
+ <div id=log></div>
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var s1 = document.createElement("script");
+ s1.src="log.py?sec=2&id=1";
+ s1.async = false;
+ document.body.appendChild(s1);
+
+ var s2 = document.createElement("script");
+ s2.src="log.py?sec=1&id=2";
+ s2.async = false;
+ document.body.appendChild(s2);
+
+ var s3 = document.createElement("script");
+ s3.id = "s3";
+ s3.src="log.py?sec=0&id=3";
+ s3.async = false;
+ document.body.appendChild(s3);
+
+ //Remove s1 (Should still execute)
+ document.body.removeChild(s1);
+ </script>
+ <script type="text/javascript">log('4');</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm
new file mode 100644
index 0000000000..d80e463cee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An empty parser-inserted script element should return async=true</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="An empty parser-inserted script element should return async=true." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script></script>
+ <script type="text/javascript">
+ test(function() { assert_true(document.getElementsByTagName("script")[2].async)}, "An empty parser-inserted script element should return async=true");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py
new file mode 100644
index 0000000000..b315afed56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript"), (b"Cache-control", b"public, max-age=100")]
+ body = u"throw('fox');"
+ return 200, headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-2.html
new file mode 100644
index 0000000000..aaa2960aaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="windows-1250">
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/utf-8.css" assert { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"�湿�\"");
+ }, "CSS module should be loaded as utf-8 even though document's encoding is windows-1250");
+</script>
+<script type="module">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" assert { type: "css"};
+ test(() => {
+ assert_not_equals(styleSheet.rules[0].style.content, "\"�湿�\"",
+ 'Should be decoded as UTF-8');
+ }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-bom.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-bom.html
new file mode 100644
index 0000000000..e26ee08d31
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset-bom.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>CSS Module scripts should ignore BOMs and always use UTF-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+ import utf8BOMSheet from './resources/bom-utf-8.css' assert { type: 'css' };
+ test(function() {
+ assert_equals(utf8BOMSheet.rules[0].selectorText, 'div', 'No UTF-8 BOM expected in selector');
+ }, 'UTF-8 BOM should be stripped when decoding JSON module script');
+
+ import utf16BEBOMSheet from './resources/bom-utf-16be.css' assert { type: 'css' };
+ test(function() {
+ assert_equals(utf16BEBOMSheet.rules[0].selectorText, '\ufffd\ufffd\ufffdd\ufffdi\ufffdv\ufffd \ufffd', 'Expected UTF-8 decoded selectorText with 0xfffd replacement characters');
+ }, 'UTF-16BE BOM should be ignored, so CSS module should be UTF-8 decoded');
+
+ import utf16LEBOMSheet from './resources/bom-utf-16le.css' assert { type: 'css' };
+ test(function() {
+ assert_equals(utf16LEBOMSheet.rules[0].selectorText, '\ufffd\ufffdd\ufffdi\ufffdv\ufffd \ufffd', 'Expected UTF-8 decoded selectorText with 0xfffd replacement characters');
+ }, 'UTF-16LE BOM should be ignored, so CSS module should be UTF-8 decoded');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset.html
new file mode 100644
index 0000000000..2127ec7280
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/charset.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/utf-8.css&ct=text/css%3Bcharset=utf-8" assert { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=utf8 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/utf-8.css&ct=text/css%3Bcharset=shift-jis" assert { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=shift-jis is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/utf-8.css&ct=text/css%3Bcharset=windows-1252" assert { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=windows-1252 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/utf-8.css&ct=text/css%3Bcharset=utf-7" assert { type: "css"};;
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=utf-7 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" assert { type: "css"};
+ test(() => {
+ assert_not_equals(styleSheet.rules[0].style.content, "\"śćążź\"",
+ 'Should be decoded as UTF-8');
+ }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/content-type-checking.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/content-type-checking.html
new file mode 100644
index 0000000000..3ade863305
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/content-type-checking.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: Content-Type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function check(t, styleSheet) {
+ t.step(() => {
+ assert_equals(styleSheet.rules[0].cssText, "#test { background-color: rgb(255, 0, 0); }");
+ t.done();
+ });
+}
+const t1 = async_test("text/css");
+const t2 = async_test("application/css");
+const t3 = async_test("text/html+css");
+const t4 = async_test("text/css;boundary=something");
+const t5 = async_test("text/css;foo=bar");
+</script>
+<script type="module" onerror="t1.unreached_func()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/basic.css&ct=text/css" assert { type: "css"};
+ check(t1, styleSheet);
+</script>
+<script type="module" onerror="t2.step_func_done()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/basic.css&ct=application/css" assert { type: "css"};
+ t2.unreached_func("Should not have loaded with MIME type application/css")();
+</script>
+<script type="module" onerror="t3.step_func_done()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/basic.css&ct=text/html+css" assert { type: "css"};
+ t3.unreached_func("Should not have loaded with MIME type text/html+css")();
+</script>
+<script type="module" onerror="t4.unreached_func()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/basic.css&ct=text/css;boundary=something" assert { type: "css"};
+ check(t4, styleSheet);
+</script>
+<script type="module" onerror="t5.unreached_func()()">
+import styleSheet from "../serve-with-content-type.py?fn=css-module-assertions/resources/basic.css&ct=text/css;foo=bar" assert { type: "css"};
+check(t5, styleSheet);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/cors-crossorigin-requests.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/cors-crossorigin-requests.html
new file mode 100644
index 0000000000..b9de562b72
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/cors-crossorigin-requests.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+ <title>css-module-assertions-crossorigin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>css-module-assertions-crossorigin</h1>
+ <iframe id="import-WithCORS" src="resources/crossorigin-import-with-cors.sub.html"></iframe>
+ <iframe id="import-NoCORS" src="resources/crossorigin-import-without-cors.sub.html"></iframe>
+ <iframe id="import-parseerror-WithCors" src="resources/crossorigin-import-parse-error-with-cors.sub.html"></iframe>
+ <script>
+
+ var tests = [
+ { "obj": async_test("Imported CSS module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported CSS: #test { background-color: rgb(255, 0, 0); }" },
+ { "obj": async_test("Imported CSS module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+ { "obj": async_test("Imported CSS module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "imported CSS rules count: 0" },
+ ];
+
+ window.addEventListener("load", function () {
+ tests.forEach(function (test) {
+ var target = document.getElementById(test.id);
+ test.obj.step(function () {
+ assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+ });
+ test.obj.done();
+ });
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/credentials.sub.html
new file mode 100644
index 0000000000..8c2f0f8073
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/credentials.sub.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'milk=1';
+
+const setCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/css-module-assertions/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+
+const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+});
+
+promise_test(t => {
+ const iframe = document.createElement('iframe');
+
+ return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+ const messagePromise = new Promise(resolve => {
+ window.addEventListener('message', event => {
+ resolve();
+ });
+ });
+
+ iframe.src = 'resources/credentials-iframe.sub.html';
+ document.body.appendChild(iframe);
+
+ return messagePromise;
+ }).then(() => {
+ const w = iframe.contentWindow;
+
+ assert_equals(w.sameOriginNoneDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymousDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentialsDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNoneDescendant, false,
+ 'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymousDescendant, false,
+ 'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentialsDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'CSS Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/css-module-worker-test.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/css-module-worker-test.html
new file mode 100644
index 0000000000..7ff672da6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/css-module-worker-test.html
@@ -0,0 +1,54 @@
+<!doctype html>
+
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+</head>
+
+<body>
+ <script>
+ setup({allow_uncaught_exception: true});
+ promise_test(function (test) {
+ const uuid = token();
+ const worker = new Worker(`./resources/worker.sub.js?key=${uuid}`, {
+ type: "module"
+ });
+ return new Promise((resolve, reject) => {
+ worker.addEventListener("error", resolve);
+ worker.addEventListener("message", reject);
+ }).then(async () => {
+ const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
+ const fetchData = await fetchResponse.json();
+ assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
+ });
+ }, "A static import CSS Module within a web worker should not load and should not attempt to fetch the module.");
+
+ promise_test(function (test) {
+ const uuid = token();
+ const worker = new Worker(`./resources/worker-dynamic-import.sub.js?key=${uuid}`, {
+ type: "module"
+ });
+
+ return new Promise(resolve => {
+ worker.addEventListener("message", resolve);
+ }).then(async (event) => {
+ assert_equals(event.data, "NOT LOADED");
+ const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
+ const fetchData = await fetchResponse.json();
+ assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
+ });
+ }, "A dynamic import CSS Module within a web worker should not load and should not attempt to fetch the module.");
+
+ promise_test(function (test) {
+ const worker = new Worker("./resources/basic.css", {
+ type: "module"
+ });
+ return new Promise(resolve => {
+ worker.onerror = resolve;
+ });
+ }, "An attempt to load a CSS module as a worker should fail.");
+
+ </script>
+
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-basic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-basic.html
new file mode 100644
index 0000000000..4ea1790aab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-basic.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="test">I am a test div.</div>
+ <div id="test2">I am a test div.</div>
+ <div id="test3">I am a test div.</div>
+ <div id="test3b">I am a test div.</div>
+ <div id="test4">I am a test div.</div>
+ <div id="test4b">I am a test div.</div>
+ <script>
+ window.errorCount = 0;
+ window.onerror = (errorMsg, url, lineNumber, column, errorObj) => {
+ window.errorCount++;
+ };
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/basic.css" assert { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(getComputedStyle(document.querySelector('#test'))
+ .backgroundColor, "rgb(255, 0, 0)", "CSS module import should succeed");
+ }, "A CSS Module should load");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/basic-large.css" assert { type: "css" };
+ test(() => {
+ // This tests potential streaming compilation of modules in
+ // Chromium that is triggered only for large (32>KiB) files in older
+ // versions.
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(getComputedStyle(document.querySelector('#test2'))
+ .backgroundColor, "rgb(255, 0, 0)",
+ "CSS module import should succeed");
+ }, "A large CSS Module should load");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/bad-import.css" assert { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(window.errorCount, 0);
+ assert_equals(sheet.cssRules.length, 1, "Parser should skip @import rule");
+ assert_equals(getComputedStyle(document.querySelector('#test3b'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "CSS module @import should not succeed");
+ assert_equals(getComputedStyle(document.querySelector('#test3'))
+ .backgroundColor, "rgb(0, 255, 0)",
+ "Rule after @import should still be applied");
+ }, "An @import CSS Module should not load, but should not throw an exception");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/malformed.css" assert { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(window.errorCount, 0);
+ assert_equals(sheet.cssRules.length, 1, "Import of malformed CSS should succeed and rules after the parse error should still be parsed");
+ assert_equals(getComputedStyle(document.querySelector('#test4'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "Malformed CSS rule should not be applied");
+ assert_equals(getComputedStyle(document.querySelector('#test4b'))
+ .backgroundColor, "rgb(0, 255, 0)",
+ "Parsing should recover and rules after malformed rules should be applied");
+ }, "A parse error should not prevent subsequent rules from being included in a CSS module");
+ </script>
+ <script type="module">
+ promise_test(function (test) {
+ const iframe = document.createElement("iframe");
+ iframe.src = "resources/css-module-without-assertion-iframe.html";
+ return new Promise(resolve => {
+ iframe.onload = resolve;
+ document.body.appendChild(iframe);
+ }).then(event => {
+ assert_equals(iframe.contentDocument.window_onerror, undefined);
+ assert_equals(iframe.contentDocument.script_onerror.type, "error");
+ assert_equals(getComputedStyle(iframe.contentDocument.querySelector('#test'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "CSS module without type assertion should result in a fetch error");
+ });
+ }, "CSS module without type assertion should result in a fetch error");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-dynamic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-dynamic.html
new file mode 100644
index 0000000000..13967858cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/import-css-module-dynamic.html
@@ -0,0 +1,23 @@
+<!doctype html>
+
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+ <script>
+ promise_test(async function (test) {
+ const css_module = await import("./resources/basic.css", { assert: { type: "css" }});
+ assert_true(css_module.default instanceof CSSStyleSheet);
+ assert_equals(css_module.default.cssRules[0].cssText,
+ "#test { background-color: rgb(255, 0, 0); }");
+ }, "Load a CSS module with dynamic import()");
+
+ promise_test(function (test) {
+ return promise_rejects_js(test, TypeError,
+ import("./resources/basic.css"),
+ "Attempting to import() a CSS module without a type assertion should fail");
+ }, "Ensure that loading a CSS module with dymnamic import() fails without a type assertion");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/integrity.html
new file mode 100644
index 0000000000..1dd0dad470
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/integrity.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity="" with CSS modules</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+<script type="module" src="resources/integrity-matches.js" integrity="sha384-xvbfmg9iJFHqmCoOS4VNMCwnFPPxEoIlW1Ojzl+fgEd+Wf8Pyez+SMWue+KNovjA" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="resources/integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+ assert_array_equals(window.matchesLog, ["integrity-matches,css:#test { background-color: rgb(255, 0, 0); }"], "The module and its dependency must have executed");
+ assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and allow it to execute when it matches");
+
+test(() => {
+ assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+ assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/load-error-events.html
new file mode 100644
index 0000000000..3457452c93
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/load-error-events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for CSS modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+ "use strict";
+
+ var test1_load = event_test('inline, 200, parser-inserted', false, false);
+ var test1_error = event_test('inline, 404, parser-inserted', false, true);
+
+ var test2_load = event_test('src, 200, parser-inserted', true, false);
+ var test2_error = event_test('src, 404, parser-inserted', false, true);
+
+ var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false);
+ var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true);
+
+ var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false);
+ var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true);
+
+ var script3_dynamic_load = document.createElement('script');
+ script3_dynamic_load.setAttribute('type', 'module');
+ script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+ script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+ script3_dynamic_load.src = "./resources/load-error-events.py?test=test3_dynamic_load";
+ document.head.appendChild(script3_dynamic_load);
+
+ var script3_dynamic_error = document.createElement('script');
+ script3_dynamic_error.setAttribute('type', 'module');
+ script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+ script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+ script3_dynamic_error.src = "./resources/load-error-events.py?test=test3_dynamic_error";
+ document.head.appendChild(script3_dynamic_error);
+
+ var script4_dynamic_load = document.createElement('script');
+ script4_dynamic_load.setAttribute('type', 'module');
+ script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+ script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+ script4_dynamic_load.async = true;
+ script4_dynamic_load.appendChild(document.createTextNode(`
+ import "./resources/basic.css" assert { type: "css" };
+ onExecute(test4_dynamic_load);`
+ ));
+ document.head.appendChild(script4_dynamic_load);
+
+ var script4_dynamic_error = document.createElement('script');
+ script4_dynamic_error.setAttribute('type', 'module');
+ script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+ script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+ script4_dynamic_error.async = true;
+ script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.css" assert { type: "css" };`));
+ document.head.appendChild(script4_dynamic_error);
+</script>
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">
+ import "./resources/basic.css" assert { type: "css"};
+ onExecute(test1_load);
+</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">
+ import "./not_found.css" assert { type: "css"};
+ onExecute(test1_error);
+</script>
+<script src="./resources/load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script>
+<script src="./resources/load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/referrer-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/referrer-policies.sub.html
new file mode 100644
index 0000000000..f078437e09
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/referrer-policies.sub.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrers with CSS module requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+ // "name" parameter is necessary for bypassing the module map.
+ import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicy" assert { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py?name=remoteNoReferrerPolicy" assert { type: "css"};
+
+ const origin = (new URL(location.href)).origin + "/";
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the default referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the default referrer policy.");
+</script>
+<script type="module" referrerpolicy="origin">
+ import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyOrigin" assert { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py?name=remoteReferrerPolicyOrigin" assert { type: "css"};
+
+ const origin = (new URL(location.href)).origin + "/";
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the origin policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the origin policy.");
+
+</script>
+<script type="module" referrerpolicy="no-referrer">
+ import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyNoReferrer" assert { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" assert { type: "css"};
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '""',
+ "No referrer should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the no-referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '""',
+ "No referrer should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+</script>
+<script type="module" referrerpolicy="unsafe-url">
+ import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" assert { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" assert { type: "css"};
+
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the unsafe-url referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the unsafe-url referrer policy.");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/relative-urls.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/relative-urls.html
new file mode 100644
index 0000000000..22971d28d9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/relative-urls.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<head>
+ <title>Test resolution of relative URL in CSS module</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="target"></div>
+ <script type="module">
+ import styleSheet from "./resources/load-relative-url.css" assert { type: "css"};
+ test(() => {
+ const target = document.querySelector("#target");
+ document.adoptedStyleSheets = [ styleSheet ];
+ let backgroundStyle = window.getComputedStyle(target).background;
+ assert_not_equals(backgroundStyle.indexOf("css-module-assertions/resources/image.png"), -1);
+ }, "A relative URL in a CSS module should be resolved relative to the CSS file's URL, not the importing document's URL");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/atImported.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/atImported.css
new file mode 100644
index 0000000000..8629a846d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/atImported.css
@@ -0,0 +1,3 @@
+#test3b {
+ background-color: #FF0000;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bad-import.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bad-import.css
new file mode 100644
index 0000000000..a6e1a0f395
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bad-import.css
@@ -0,0 +1,4 @@
+@import "atImported.css";
+#test3 {
+ background-color:#00FF00;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic-large.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic-large.css
new file mode 100644
index 0000000000..555ab70d2e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic-large.css
@@ -0,0 +1,7 @@
+#test2 {
+ background-color:red;
+}
+
+#test:before {
+ content: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css
new file mode 100644
index 0000000000..e034ed9ac7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css
@@ -0,0 +1,3 @@
+#test {
+ background-color: #FF0000;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16be.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16be.css
new file mode 100644
index 0000000000..9e17902a1d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16be.css
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16le.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16le.css
new file mode 100644
index 0000000000..ef90843d8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-16le.css
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-8.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-8.css
new file mode 100644
index 0000000000..5cf81232b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/bom-utf-8.css
@@ -0,0 +1 @@
+div { background-color: blue; } \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/credentials-iframe.sub.html
new file mode 100644
index 0000000000..cf1d621ce3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/credentials-iframe.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module">
+ import styleSheet from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.sameOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+ import styleSheet from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.sameOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import styleSheet from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.sameOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.crossOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.crossOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+ window.crossOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+ window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py
new file mode 100644
index 0000000000..d744fc9514
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/cross-origin.py
@@ -0,0 +1,17 @@
+def main(request, response):
+
+ headers = [
+ (b"Content-Type", b"text/css"),
+ (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+ (b"Access-Control-Allow-Credentials", b"true")
+ ]
+
+ milk = request.cookies.first(b"milk", None)
+
+ # Send back
+ if milk is None:
+ return headers, u'.requestDidNotHaveCookies { }'
+ elif milk.value == b"1":
+ return headers, u'.requestHadCookies { }'
+
+ return headers, u'.requestDidNotHaveCookies { }'
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-parse-error-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-parse-error-with-cors.sub.html
new file mode 100644
index 0000000000..3afb8edeb1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-parse-error-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-assertions-import-cross-domain-parse-error-WithCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-assertions-import-cross-domain-parse-error-WithCORS</h1>
+ <script type="module" crossorigin>
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/parse-error.css?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS rules count: ${styleSheet.rules.length}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-with-cors.sub.html
new file mode 100644
index 0000000000..f8754c2a56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-assertions-import-cross-domain-WithCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-assertions-import-cross-domain-WithCORS</h1>
+ <script type="module" crossorigin>
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-without-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-without-cors.sub.html
new file mode 100644
index 0000000000..ab70b73573
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/crossorigin-import-without-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-assertions-import-cross-domain-NoCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-assertions-import-cross-domain-NoCORS</h1>
+ <script type="module" onerror="document._log.push('error');">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/basic.css" assert { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/css-module-without-assertion-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/css-module-without-assertion-iframe.html
new file mode 100644
index 0000000000..3d1be841ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/css-module-without-assertion-iframe.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<body>
+ <script>
+ window.onerror = function (errorMsg, url, lineNumber, column, errorObj)
+ {
+ document.window_onerror = errorObj.name;
+ return true;
+ };
+
+ function scriptErrorHandler(e) {
+ document.script_onerror = e;
+ }
+ </script>
+ <script type="module" onerror="scriptErrorHandler(event)">
+ import v from "./basic.css";
+ document.adoptedStyleSheets = [v];
+ </script>
+
+ <div id="test">
+ I am a test div.
+ </div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-matches.js
new file mode 100644
index 0000000000..95be445311
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-matches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" assert { type: "css" };
+window.matchesLog.push(`integrity-matches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-mismatches.js
new file mode 100644
index 0000000000..af6fc24de4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" assert { type: "css" };
+window.matchesLog.push(`integrity-mismatches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-error-events.py
new file mode 100644
index 0000000000..b61b1ca834
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-error-events.py
@@ -0,0 +1,14 @@
+import re
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ test = request.GET.first(b'test')
+ assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+ status = 200
+ if test.find(b'_load') >= 0:
+ content = b'import "./basic.css" assert { type: "css"}; %s.executed = true;' % test
+ else:
+ content = b'import "./not_found.css" assert { type: "css"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+ return status, headers, content
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-relative-url.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-relative-url.css
new file mode 100644
index 0000000000..27f2987610
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/load-relative-url.css
@@ -0,0 +1,5 @@
+
+#target {
+ /* image.png doesn't exist, but that's irrelevant to the test. */
+ background: url('./image.png');
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/malformed.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/malformed.css
new file mode 100644
index 0000000000..28819bfdf5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/malformed.css
@@ -0,0 +1,7 @@
+#test4 } {
+ background-color: #FF0000;
+}
+
+#test4b {
+ background-color: #00FF00;
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/parse-error.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/parse-error.css
new file mode 100644
index 0000000000..2bee3ff996
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/parse-error.css
@@ -0,0 +1,2 @@
+div /* Opening bracket skipped intentionally. */ }
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/record-fetch.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/record-fetch.py
new file mode 100644
index 0000000000..4928cb4acb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/record-fetch.py
@@ -0,0 +1,20 @@
+def main(request, response):
+ try:
+ stash_key = request.GET.first(b"key")
+ action = request.GET.first(b"action")
+
+ run_count = request.server.stash.take(stash_key)
+ if not run_count:
+ run_count = 0
+
+ if action == b"incCount":
+ request.server.stash.put(stash_key, run_count + 1)
+ response.headers.set(b"Content-Type", b"text/css")
+ response.content = b'#test { background-color: #FF0000; }'
+ elif action == b"getCount":
+ response.headers.set(b"Content-Type", b"text/json")
+ response.content = b'{"count": %d }' % run_count
+ else:
+ response.set_error(400, u"Invalid action")
+ except:
+ response.set_error(400, u"Not enough parameters")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py
new file mode 100644
index 0000000000..c1eaed8e46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/referrer-checker.py
@@ -0,0 +1,7 @@
+def main(request, response):
+ referrer = request.headers.get(b"referer", b"")
+ response_headers = [(b"Content-Type", b"text/css"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ # Put the referrer in a CSS rule that can be read by the importer through CSSOM
+ return (200, response_headers,
+ b'.referrer { content: "' + referrer + b'" }')
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/utf-8.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/utf-8.css
new file mode 100644
index 0000000000..0a8b46656f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/utf-8.css
@@ -0,0 +1,3 @@
+#test {
+ content: "śćążź";
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/windows-1250.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/windows-1250.css
new file mode 100644
index 0000000000..9beac4d618
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/windows-1250.css
@@ -0,0 +1,3 @@
+#test {
+ content: "�湿�";
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker-dynamic-import.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker-dynamic-import.sub.js
new file mode 100644
index 0000000000..791bd7d3f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker-dynamic-import.sub.js
@@ -0,0 +1,3 @@
+import("./record-fetch.py?key={{GET[key]}}&action=incCount", { assert: { type: "css" } })
+ .then(() => postMessage("LOADED"))
+ .catch(e => postMessage("NOT LOADED")); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker.sub.js
new file mode 100644
index 0000000000..ffee312d21
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/resources/worker.sub.js
@@ -0,0 +1,2 @@
+import "./record-fetch.py?key={{GET[key]}}&action=incCount" assert { type: "css" };
+postMessage("Unexpectedly loaded"); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/script-element-css-src.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/script-element-css-src.html
new file mode 100644
index 0000000000..231d02db47
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module-assertions/script-element-css-src.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>&lt;script&gt; with CSS src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that <script> doesn't load when the src is CSS.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["error"]);
+ }));
+</script>
+<script type="module" src="./resources/basic.css" onload="t.unreached_func('CSS src should fail to load')" onerror="log.push('error')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-2.html
new file mode 100644
index 0000000000..fb25b1ffb3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="windows-1250">
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css" with { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"�湿�\"");
+ }, "CSS module should be loaded as utf-8 even though document's encoding is windows-1250");
+</script>
+<script type="module">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" with { type: "css"};
+ test(() => {
+ assert_not_equals(styleSheet.rules[0].style.content, "\"�湿�\"",
+ 'Should be decoded as UTF-8');
+ }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-bom.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-bom.html
new file mode 100644
index 0000000000..113ae63ea4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset-bom.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>CSS Module scripts should ignore BOMs and always use UTF-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+ import utf8BOMSheet from './resources/bom-utf-8.css' with { type: 'css' };
+ test(function() {
+ assert_equals(utf8BOMSheet.rules[0].selectorText, 'div', 'No UTF-8 BOM expected in selector');
+ }, 'UTF-8 BOM should be stripped when decoding JSON module script');
+
+ import utf16BEBOMSheet from './resources/bom-utf-16be.css' with { type: 'css' };
+ test(function() {
+ assert_equals(utf16BEBOMSheet.rules[0].selectorText, '\ufffd\ufffd\ufffdd\ufffdi\ufffdv\ufffd \ufffd', 'Expected UTF-8 decoded selectorText with 0xfffd replacement characters');
+ }, 'UTF-16BE BOM should be ignored, so CSS module should be UTF-8 decoded');
+
+ import utf16LEBOMSheet from './resources/bom-utf-16le.css' with { type: 'css' };
+ test(function() {
+ assert_equals(utf16LEBOMSheet.rules[0].selectorText, '\ufffd\ufffdd\ufffdi\ufffdv\ufffd \ufffd', 'Expected UTF-8 decoded selectorText with 0xfffd replacement characters');
+ }, 'UTF-16LE BOM should be ignored, so CSS module should be UTF-8 decoded');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset.html
new file mode 100644
index 0000000000..e7010c2f57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/charset.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=utf-8" with { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=utf8 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=shift-jis" with { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=shift-jis is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=windows-1252" with { type: "css"};
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=windows-1252 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=utf-7" with { type: "css"};;
+ test(() => {
+ assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+ }, "CSS module should be loaded as utf-8 when charset=utf-7 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" with { type: "css"};
+ test(() => {
+ assert_not_equals(styleSheet.rules[0].style.content, "\"śćążź\"",
+ 'Should be decoded as UTF-8');
+ }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html
new file mode 100644
index 0000000000..5be0d50c38
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: Content-Type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function check(t, styleSheet) {
+ t.step(() => {
+ assert_equals(styleSheet.rules[0].cssText, "#test { background-color: rgb(255, 0, 0); }");
+ t.done();
+ });
+}
+const t1 = async_test("text/css");
+const t2 = async_test("application/css");
+const t3 = async_test("text/html+css");
+const t4 = async_test("text/css;boundary=something");
+const t5 = async_test("text/css;foo=bar");
+</script>
+<script type="module" onerror="t1.unreached_func()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css" with { type: "css"};
+ check(t1, styleSheet);
+</script>
+<script type="module" onerror="t2.step_func_done()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=application/css" with { type: "css"};
+ t2.unreached_func("Should not have loaded with MIME type application/css")();
+</script>
+<script type="module" onerror="t3.step_func_done()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/html+css" with { type: "css"};
+ t3.unreached_func("Should not have loaded with MIME type text/html+css")();
+</script>
+<script type="module" onerror="t4.unreached_func()()">
+ import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css;boundary=something" with { type: "css"};
+ check(t4, styleSheet);
+</script>
+<script type="module" onerror="t5.unreached_func()()">
+import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css;foo=bar" with { type: "css"};
+check(t5, styleSheet);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html
new file mode 100644
index 0000000000..e699ef927e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+ <title>css-module-crossorigin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>css-module-crossorigin</h1>
+ <iframe id="import-WithCORS" src="resources/crossorigin-import-with-cors.sub.html"></iframe>
+ <iframe id="import-NoCORS" src="resources/crossorigin-import-without-cors.sub.html"></iframe>
+ <iframe id="import-parseerror-WithCors" src="resources/crossorigin-import-parse-error-with-cors.sub.html"></iframe>
+ <script>
+
+ var tests = [
+ { "obj": async_test("Imported CSS module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported CSS: #test { background-color: rgb(255, 0, 0); }" },
+ { "obj": async_test("Imported CSS module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+ { "obj": async_test("Imported CSS module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "imported CSS rules count: 0" },
+ ];
+
+ window.addEventListener("load", function () {
+ tests.forEach(function (test) {
+ var target = document.getElementById(test.id);
+ test.obj.step(function () {
+ assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+ });
+ test.obj.done();
+ });
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html
new file mode 100644
index 0000000000..0da573dad2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'milk=1';
+
+const setCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/css-module/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+
+const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+});
+
+promise_test(t => {
+ const iframe = document.createElement('iframe');
+
+ return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+ const messagePromise = new Promise(resolve => {
+ window.addEventListener('message', event => {
+ resolve();
+ });
+ });
+
+ iframe.src = 'resources/credentials-iframe.sub.html';
+ document.body.appendChild(iframe);
+
+ return messagePromise;
+ }).then(() => {
+ const w = iframe.contentWindow;
+
+ assert_equals(w.sameOriginNoneDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymousDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentialsDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNoneDescendant, false,
+ 'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymousDescendant, false,
+ 'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentialsDescendant, true,
+ 'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'CSS Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test.html
new file mode 100644
index 0000000000..7ff672da6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test.html
@@ -0,0 +1,54 @@
+<!doctype html>
+
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+</head>
+
+<body>
+ <script>
+ setup({allow_uncaught_exception: true});
+ promise_test(function (test) {
+ const uuid = token();
+ const worker = new Worker(`./resources/worker.sub.js?key=${uuid}`, {
+ type: "module"
+ });
+ return new Promise((resolve, reject) => {
+ worker.addEventListener("error", resolve);
+ worker.addEventListener("message", reject);
+ }).then(async () => {
+ const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
+ const fetchData = await fetchResponse.json();
+ assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
+ });
+ }, "A static import CSS Module within a web worker should not load and should not attempt to fetch the module.");
+
+ promise_test(function (test) {
+ const uuid = token();
+ const worker = new Worker(`./resources/worker-dynamic-import.sub.js?key=${uuid}`, {
+ type: "module"
+ });
+
+ return new Promise(resolve => {
+ worker.addEventListener("message", resolve);
+ }).then(async (event) => {
+ assert_equals(event.data, "NOT LOADED");
+ const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
+ const fetchData = await fetchResponse.json();
+ assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
+ });
+ }, "A dynamic import CSS Module within a web worker should not load and should not attempt to fetch the module.");
+
+ promise_test(function (test) {
+ const worker = new Worker("./resources/basic.css", {
+ type: "module"
+ });
+ return new Promise(resolve => {
+ worker.onerror = resolve;
+ });
+ }, "An attempt to load a CSS module as a worker should fail.");
+
+ </script>
+
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html
new file mode 100644
index 0000000000..8e9b84691a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="test">I am a test div.</div>
+ <div id="test2">I am a test div.</div>
+ <div id="test3">I am a test div.</div>
+ <div id="test3b">I am a test div.</div>
+ <div id="test4">I am a test div.</div>
+ <div id="test4b">I am a test div.</div>
+ <script>
+ window.errorCount = 0;
+ window.onerror = (errorMsg, url, lineNumber, column, errorObj) => {
+ window.errorCount++;
+ };
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/basic.css" with { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(getComputedStyle(document.querySelector('#test'))
+ .backgroundColor, "rgb(255, 0, 0)", "CSS module import should succeed");
+ }, "A CSS Module should load");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/basic-large.css" with { type: "css" };
+ test(() => {
+ // This tests potential streaming compilation of modules in
+ // Chromium that is triggered only for large (32>KiB) files in older
+ // versions.
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(getComputedStyle(document.querySelector('#test2'))
+ .backgroundColor, "rgb(255, 0, 0)",
+ "CSS module import should succeed");
+ }, "A large CSS Module should load");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/bad-import.css" with { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(window.errorCount, 0);
+ assert_equals(sheet.cssRules.length, 1, "Parser should skip @import rule");
+ assert_equals(getComputedStyle(document.querySelector('#test3b'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "CSS module @import should not succeed");
+ assert_equals(getComputedStyle(document.querySelector('#test3'))
+ .backgroundColor, "rgb(0, 255, 0)",
+ "Rule after @import should still be applied");
+ }, "An @import CSS Module should not load, but should not throw an exception");
+ </script>
+ <script type="module" onerror="unreachable()">
+ import sheet from "./resources/malformed.css" with { type: "css" };
+ test(() => {
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
+ assert_equals(window.errorCount, 0);
+ assert_equals(sheet.cssRules.length, 1, "Import of malformed CSS should succeed and rules after the parse error should still be parsed");
+ assert_equals(getComputedStyle(document.querySelector('#test4'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "Malformed CSS rule should not be applied");
+ assert_equals(getComputedStyle(document.querySelector('#test4b'))
+ .backgroundColor, "rgb(0, 255, 0)",
+ "Parsing should recover and rules after malformed rules should be applied");
+ }, "A parse error should not prevent subsequent rules from being included in a CSS module");
+ </script>
+ <script type="module">
+ promise_test(function (test) {
+ const iframe = document.createElement("iframe");
+ iframe.src = "resources/css-module-without-attribute-iframe.html";
+ return new Promise(resolve => {
+ iframe.onload = resolve;
+ document.body.appendChild(iframe);
+ }).then(event => {
+ assert_equals(iframe.contentDocument.window_onerror, undefined);
+ assert_equals(iframe.contentDocument.script_onerror.type, "error");
+ assert_equals(getComputedStyle(iframe.contentDocument.querySelector('#test'))
+ .backgroundColor, "rgba(0, 0, 0, 0)",
+ "CSS module without type attribute should result in a fetch error");
+ });
+ }, "CSS module without type attribute should result in a fetch error");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html
new file mode 100644
index 0000000000..5774a31cb2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html
@@ -0,0 +1,23 @@
+<!doctype html>
+
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+ <script>
+ promise_test(async function (test) {
+ const css_module = await import("./resources/basic.css", { with: { type: "css" }});
+ assert_true(css_module.default instanceof CSSStyleSheet);
+ assert_equals(css_module.default.cssRules[0].cssText,
+ "#test { background-color: rgb(255, 0, 0); }");
+ }, "Load a CSS module with dynamic import()");
+
+ promise_test(function (test) {
+ return promise_rejects_js(test, TypeError,
+ import("./resources/basic.css"),
+ "Attempting to import() a CSS module without a type attribute should fail");
+ }, "Ensure that loading a CSS module with dymnamic import() fails without a type attribute");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/integrity.html
new file mode 100644
index 0000000000..1dd0dad470
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/integrity.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity="" with CSS modules</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+<script type="module" src="resources/integrity-matches.js" integrity="sha384-xvbfmg9iJFHqmCoOS4VNMCwnFPPxEoIlW1Ojzl+fgEd+Wf8Pyez+SMWue+KNovjA" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="resources/integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+ assert_array_equals(window.matchesLog, ["integrity-matches,css:#test { background-color: rgb(255, 0, 0); }"], "The module and its dependency must have executed");
+ assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and allow it to execute when it matches");
+
+test(() => {
+ assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+ assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html
new file mode 100644
index 0000000000..703a0734ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for CSS modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+ "use strict";
+
+ var test1_load = event_test('inline, 200, parser-inserted', false, false);
+ var test1_error = event_test('inline, 404, parser-inserted', false, true);
+
+ var test2_load = event_test('src, 200, parser-inserted', true, false);
+ var test2_error = event_test('src, 404, parser-inserted', false, true);
+
+ var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false);
+ var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true);
+
+ var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false);
+ var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true);
+
+ var script3_dynamic_load = document.createElement('script');
+ script3_dynamic_load.setAttribute('type', 'module');
+ script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+ script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+ script3_dynamic_load.src = "./resources/load-error-events.py?test=test3_dynamic_load";
+ document.head.appendChild(script3_dynamic_load);
+
+ var script3_dynamic_error = document.createElement('script');
+ script3_dynamic_error.setAttribute('type', 'module');
+ script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+ script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+ script3_dynamic_error.src = "./resources/load-error-events.py?test=test3_dynamic_error";
+ document.head.appendChild(script3_dynamic_error);
+
+ var script4_dynamic_load = document.createElement('script');
+ script4_dynamic_load.setAttribute('type', 'module');
+ script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+ script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+ script4_dynamic_load.async = true;
+ script4_dynamic_load.appendChild(document.createTextNode(`
+ import "./resources/basic.css" with { type: "css" };
+ onExecute(test4_dynamic_load);`
+ ));
+ document.head.appendChild(script4_dynamic_load);
+
+ var script4_dynamic_error = document.createElement('script');
+ script4_dynamic_error.setAttribute('type', 'module');
+ script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+ script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+ script4_dynamic_error.async = true;
+ script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.css" with { type: "css" };`));
+ document.head.appendChild(script4_dynamic_error);
+</script>
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">
+ import "./resources/basic.css" with { type: "css"};
+ onExecute(test1_load);
+</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">
+ import "./not_found.css" with { type: "css"};
+ onExecute(test1_error);
+</script>
+<script src="./resources/load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script>
+<script src="./resources/load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html
new file mode 100644
index 0000000000..a507ee52fc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrers with CSS module requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+ // "name" parameter is necessary for bypassing the module map.
+ import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicy" with { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteNoReferrerPolicy" with { type: "css"};
+
+ const origin = (new URL(location.href)).origin + "/";
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the default referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the default referrer policy.");
+</script>
+<script type="module" referrerpolicy="origin">
+ import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyOrigin" with { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteReferrerPolicyOrigin" with { type: "css"};
+
+ const origin = (new URL(location.href)).origin + "/";
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the origin policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + origin + '"',
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the origin policy.");
+
+</script>
+<script type="module" referrerpolicy="no-referrer">
+ import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyNoReferrer" with { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" with { type: "css"};
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '""',
+ "No referrer should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the no-referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '""',
+ "No referrer should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+</script>
+<script type="module" referrerpolicy="unsafe-url">
+ import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" with { type: "css"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" with { type: "css"};
+
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the unsafe-url referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.rules[0].style.content, '"' + originUrl + '"',
+ "Referrer URL should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the unsafe-url referrer policy.");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/relative-urls.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/relative-urls.html
new file mode 100644
index 0000000000..0aafb9aae5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/relative-urls.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<head>
+ <title>Test resolution of relative URL in CSS module</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="target"></div>
+ <script type="module">
+ import styleSheet from "./resources/load-relative-url.css" with { type: "css"};
+ test(() => {
+ const target = document.querySelector("#target");
+ document.adoptedStyleSheets = [ styleSheet ];
+ let backgroundStyle = window.getComputedStyle(target).background;
+ assert_not_equals(backgroundStyle.indexOf("css-module/resources/image.png"), -1);
+ }, "A relative URL in a CSS module should be resolved relative to the CSS file's URL, not the importing document's URL");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/atImported.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/atImported.css
new file mode 100644
index 0000000000..8629a846d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/atImported.css
@@ -0,0 +1,3 @@
+#test3b {
+ background-color: #FF0000;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css
new file mode 100644
index 0000000000..a6e1a0f395
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css
@@ -0,0 +1,4 @@
+@import "atImported.css";
+#test3 {
+ background-color:#00FF00;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic-large.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic-large.css
new file mode 100644
index 0000000000..555ab70d2e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic-large.css
@@ -0,0 +1,7 @@
+#test2 {
+ background-color:red;
+}
+
+#test:before {
+ content: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css
new file mode 100644
index 0000000000..e034ed9ac7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css
@@ -0,0 +1,3 @@
+#test {
+ background-color: #FF0000;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16be.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16be.css
new file mode 100644
index 0000000000..9e17902a1d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16be.css
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16le.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16le.css
new file mode 100644
index 0000000000..ef90843d8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-16le.css
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-8.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-8.css
new file mode 100644
index 0000000000..5cf81232b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/bom-utf-8.css
@@ -0,0 +1 @@
+div { background-color: blue; } \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html
new file mode 100644
index 0000000000..c71b0e4bb7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module">
+ import styleSheet from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.sameOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+ import styleSheet from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.sameOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import styleSheet from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.sameOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.crossOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.crossOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "css" };
+ window.crossOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+ window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py
new file mode 100644
index 0000000000..d744fc9514
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py
@@ -0,0 +1,17 @@
+def main(request, response):
+
+ headers = [
+ (b"Content-Type", b"text/css"),
+ (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+ (b"Access-Control-Allow-Credentials", b"true")
+ ]
+
+ milk = request.cookies.first(b"milk", None)
+
+ # Send back
+ if milk is None:
+ return headers, u'.requestDidNotHaveCookies { }'
+ elif milk.value == b"1":
+ return headers, u'.requestHadCookies { }'
+
+ return headers, u'.requestDidNotHaveCookies { }'
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html
new file mode 100644
index 0000000000..59b4afa721
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-import-cross-domain-parse-error-WithCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-import-cross-domain-parse-error-WithCORS</h1>
+ <script type="module" crossorigin>
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css?pipe=header(Access-Control-Allow-Origin,*)" with { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS rules count: ${styleSheet.rules.length}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html
new file mode 100644
index 0000000000..2a383d8be9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-import-cross-domain-WithCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-import-cross-domain-WithCORS</h1>
+ <script type="module" crossorigin>
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css?pipe=header(Access-Control-Allow-Origin,*)" with { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html
new file mode 100644
index 0000000000..256a76a1d9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>css-module-import-cross-domain-NoCORS</title>
+ <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>css-module-import-cross-domain-NoCORS</h1>
+ <script type="module" onerror="document._log.push('error');">
+ import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css" with { type: "css" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-without-attribute-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-without-attribute-iframe.html
new file mode 100644
index 0000000000..3d1be841ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-without-attribute-iframe.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<body>
+ <script>
+ window.onerror = function (errorMsg, url, lineNumber, column, errorObj)
+ {
+ document.window_onerror = errorObj.name;
+ return true;
+ };
+
+ function scriptErrorHandler(e) {
+ document.script_onerror = e;
+ }
+ </script>
+ <script type="module" onerror="scriptErrorHandler(event)">
+ import v from "./basic.css";
+ document.adoptedStyleSheets = [v];
+ </script>
+
+ <div id="test">
+ I am a test div.
+ </div>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js
new file mode 100644
index 0000000000..4bd004ce96
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" with { type: "css" };
+window.matchesLog.push(`integrity-matches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js
new file mode 100644
index 0000000000..7f3bf54762
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" with { type: "css" };
+window.matchesLog.push(`integrity-mismatches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py
new file mode 100644
index 0000000000..490bdc42aa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py
@@ -0,0 +1,14 @@
+import re
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ test = request.GET.first(b'test')
+ assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+ status = 200
+ if test.find(b'_load') >= 0:
+ content = b'import "./basic.css" with { type: "css"}; %s.executed = true;' % test
+ else:
+ content = b'import "./not_found.css" with { type: "css"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+ return status, headers, content
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-relative-url.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-relative-url.css
new file mode 100644
index 0000000000..27f2987610
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/load-relative-url.css
@@ -0,0 +1,5 @@
+
+#target {
+ /* image.png doesn't exist, but that's irrelevant to the test. */
+ background: url('./image.png');
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css
new file mode 100644
index 0000000000..28819bfdf5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css
@@ -0,0 +1,7 @@
+#test4 } {
+ background-color: #FF0000;
+}
+
+#test4b {
+ background-color: #00FF00;
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css
new file mode 100644
index 0000000000..2bee3ff996
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css
@@ -0,0 +1,2 @@
+div /* Opening bracket skipped intentionally. */ }
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/record-fetch.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/record-fetch.py
new file mode 100644
index 0000000000..4928cb4acb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/record-fetch.py
@@ -0,0 +1,20 @@
+def main(request, response):
+ try:
+ stash_key = request.GET.first(b"key")
+ action = request.GET.first(b"action")
+
+ run_count = request.server.stash.take(stash_key)
+ if not run_count:
+ run_count = 0
+
+ if action == b"incCount":
+ request.server.stash.put(stash_key, run_count + 1)
+ response.headers.set(b"Content-Type", b"text/css")
+ response.content = b'#test { background-color: #FF0000; }'
+ elif action == b"getCount":
+ response.headers.set(b"Content-Type", b"text/json")
+ response.content = b'{"count": %d }' % run_count
+ else:
+ response.set_error(400, u"Invalid action")
+ except:
+ response.set_error(400, u"Not enough parameters")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py
new file mode 100644
index 0000000000..c1eaed8e46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py
@@ -0,0 +1,7 @@
+def main(request, response):
+ referrer = request.headers.get(b"referer", b"")
+ response_headers = [(b"Content-Type", b"text/css"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ # Put the referrer in a CSS rule that can be read by the importer through CSSOM
+ return (200, response_headers,
+ b'.referrer { content: "' + referrer + b'" }')
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css
new file mode 100644
index 0000000000..0a8b46656f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css
@@ -0,0 +1,3 @@
+#test {
+ content: "śćążź";
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css
new file mode 100644
index 0000000000..9beac4d618
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css
@@ -0,0 +1,3 @@
+#test {
+ content: "�湿�";
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker-dynamic-import.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker-dynamic-import.sub.js
new file mode 100644
index 0000000000..30dc8cde85
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker-dynamic-import.sub.js
@@ -0,0 +1,3 @@
+import("./record-fetch.py?key={{GET[key]}}&action=incCount", { with: { type: "css" } })
+ .then(() => postMessage("LOADED"))
+ .catch(e => postMessage("NOT LOADED")); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker.sub.js
new file mode 100644
index 0000000000..dc85c13ed9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/resources/worker.sub.js
@@ -0,0 +1,2 @@
+import "./record-fetch.py?key={{GET[key]}}&action=incCount" with { type: "css" };
+postMessage("Unexpectedly loaded"); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html
new file mode 100644
index 0000000000..231d02db47
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>&lt;script&gt; with CSS src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that <script> doesn't load when the src is CSS.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["error"]);
+ }));
+</script>
+<script type="module" src="./resources/basic.css" onload="t.unreached_func('CSS src should fail to load')" onerror="log.push('error')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/data-url.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/data-url.html
new file mode 100644
index 0000000000..6fad505271
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/data-url.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Test data URL and scripts errors</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+ setup({allow_uncaught_exception:true});
+ async_test(function(t) {
+ var counter = 1
+ window.onerror = t.step_func((message, url, lineno, colno, e) => {
+ // Test that error is not muted as data URLs have a response type of "default"
+ // and errors should only be muted if the response type is "opaque" or "opaqueredirect"
+ assert_not_equals(message, "Script error.")
+ assert_not_equals(url, null);
+ assert_not_equals(url, "");
+ assert_equals(typeof lineno, "number");
+ assert_not_equals(lineno, 0);
+ assert_equals(typeof colno, "number");
+ assert_not_equals(colno, 0);
+ assert_equals(typeof e, "number")
+ assert_equals(e, counter)
+ if (counter == 3) {
+ t.done()
+ }
+ counter++
+ });
+ });
+</script>
+<script src="data:,throw 1"></script>
+<script src="data:,throw 2" crossorigin></script>
+<script src="data:,throw 3" crossorigin=use-credentials></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/README.md b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/README.md
new file mode 100644
index 0000000000..ac5c91c9a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/README.md
@@ -0,0 +1,7 @@
+The tests in this directory is intended for Chromium's DeferAllScript
+experiment https://crbug.com/1339112, containing scenarios that would be
+affected by DeferAllScript, to monitor the behavior on Chromium and other
+browsers.
+
+The same set of expectations (when async/defer scripts are evaluated) should
+already be covered somewhere in WPT.
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script-2.html
new file mode 100644
index 0000000000..f7377d847a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script-2.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>Async Script Execution Order</title>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/helper.js"></script>
+</head>
+<body>
+ <script>
+ setup({single_test: true});
+ function finish() {
+ assert_array_equals(
+ window.result,
+ ["Inline1", "Sync1", "Async1", "Sync2", "EndOfBody",
+ "DOMContentLoaded"],
+ "Execution order");
+ // Chromium's force-defer order would be:
+ // ["EndOfBody", "Inline1", "Sync1", "Sync2",
+ // "DOMContentLoaded", "Async1"]
+ //
+ // If we delay async script e.g. after DOMContentLoaded,
+ // the order would be:
+ // ["Inline1", "Sync1", "Sync2", "EndOfBody",
+ // "DOMContentLoaded", "Async1"]
+ done();
+ }
+ logScript("Inline1");
+ window.addEventListener("load", finish);
+ </script>
+ <script src="resources/sync-script-1.js"></script>
+ <!-- To test the async script loaded before force-deferred scripts
+ should be evaluated after the force-deferred scripts
+ in Chromium's force-defer order. -->
+ <script src="resources/async-script-1.js?pipe=trickle(d1)" async></script>
+ <script src="resources/sync-script-2.js?pipe=trickle(d2)"></script>
+ <pre id="bodyend">End</pre>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script.html
new file mode 100644
index 0000000000..90f657679f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/async-script.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>Async Script Execution Order</title>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name=variant content="?default">
+ <meta name=variant content="?reload">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/helper.js"></script>
+</head>
+<body>
+ <script>
+ let child_path = 'support/async-script.html';
+ if (location.search == '?reload') {
+ child_path += '?reload';
+ }
+ const child_window = window.open(child_path);
+ fetch_tests_from_window(child_window);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script-xml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script-xml.xhtml
new file mode 100644
index 0000000000..9d02ff39f5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script-xml.xhtml
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Defer Script Execution Order</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/helper.js"></script>
+</head>
+<body>
+ <div id="scriptlog"/>
+ <input id="testElement"/>
+ <script>
+ setup({single_test: true});
+ function finish() {
+ assert_array_equals(
+ window.result,
+ ["Inline1", "Sync1", "Inline2", "Sync2", "EndOfBody",
+ "Defer1", "Defer2", "DOMContentLoaded"],
+ "Execution order");
+ // Chromium order is (due to https://crbug.com/874749):
+ // ["Inline1", "Sync1", "Defer1", "Inline2", "Defer2", "Sync2",
+ // "EndOfBody", "DOMContentLoaded"]
+ done();
+ }
+ logScript("Inline1");
+ window.addEventListener("load", finish);
+ </script>
+
+ <script src="resources/sync-script-1.js"></script>
+ <script src="resources/defer-script-1.js" defer="defer"></script>
+ <script>
+ logScript("Inline2");
+ </script>
+ <script src="resources/defer-script-2.js" defer="defer"></script>
+ <script src="resources/sync-script-2.js"></script>
+ <pre id="bodyend">End</pre>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script.html
new file mode 100644
index 0000000000..62c3a74014
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/defer-script.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<title>Defer Script Execution Order</title>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/helper.js"></script>
+</head>
+<body>
+ <script>
+ setup({single_test: true});
+ function finish() {
+ assert_array_equals(
+ window.result,
+ ["Inline1", "Sync1", "Inline2", "Sync2", "EndOfBody",
+ "Defer1", "Defer2", "DOMContentLoaded"],
+ "Execution order");
+ // Chromium's force defer order would be:
+ // ["EndOfBody", "Inline1", "Sync1", "Inline2", "Sync2",
+ // "Defer1", "Defer2", "DOMContentLoaded"]
+ done();
+ }
+ logScript("Inline1");
+ window.addEventListener("load", finish);
+ </script>
+
+ <script src="resources/sync-script-1.js"></script>
+ <script src="resources/defer-script-1.js" defer></script>
+ <script>
+ logScript("Inline2");
+ </script>
+ <script src="resources/defer-script-2.js" defer></script>
+ <script src="resources/sync-script-2.js"></script>
+ <pre id="bodyend">End</pre>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/document-write.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/document-write.html
new file mode 100644
index 0000000000..63e251bae5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/document-write.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<title>DeferAllScript: document.write()</title>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ const t1 = async_test("document.write()");
+ const t2 = async_test("document.write(),close()");
+ const t3 = async_test("document.open(),write()");
+ const t4 = async_test("document.open(),write(),close()");
+ function finish() {
+ const expected = ["Inline1", "Sync2", "Async1", "Sync1",
+ "EndOfBody", "DOMContentLoaded", "WindowLoad"];
+ t1.step_func_done(() => {
+ assert_array_equals(
+ document.getElementById("document-write").contentWindow.result,
+ expected,
+ "Execution order");
+ })();
+
+ t2.step_func_done(() => {
+ assert_array_equals(
+ document.getElementById("document-write-close").contentWindow.result,
+ expected,
+ "Execution order");
+ })();
+
+ t3.step_func_done(() => {
+ assert_array_equals(
+ document.getElementById("document-open-write").contentWindow.result,
+ expected,
+ "Execution order");
+ })();
+
+ t4.step_func_done(() => {
+ assert_array_equals(
+ document.getElementById(
+ "document-open-write-close").contentWindow.result,
+ expected,
+ "Execution order");
+ })();
+ // For cases where documents are kept open, call `document.close()` here
+ // to finish the test harness.
+ for (const iframe of document.querySelectorAll("iframe")) {
+ iframe.contentDocument.close();
+ }
+ }
+
+ // For cases where documents are kept open (that should never occur in
+ // non-intervention cases), schedule `finish()` because Window load events
+ // might be not fired.
+ setTimeout(finish, 5000);
+ </script>
+</head>
+<body onload="finish()">
+<iframe id="document-write"
+ src="resources/document-write-iframe.sub.html?script=document-write.js"></iframe>
+<iframe id="document-write-close"
+ src="resources/document-write-iframe.sub.html?script=document-write-close.js"></iframe>
+<iframe id="document-open-write"
+ src="resources/document-write-iframe.sub.html?script=document-open-write.js"></iframe>
+<iframe id="document-open-write-close"
+ src="resources/document-write-iframe.sub.html?script=document-open-write-close.js"></iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/async-script-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/async-script-1.js
new file mode 100644
index 0000000000..267f324aa6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/async-script-1.js
@@ -0,0 +1 @@
+logScript("Async1");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-1.js
new file mode 100644
index 0000000000..1a0524f4fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-1.js
@@ -0,0 +1 @@
+logScript("Defer1");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-2.js
new file mode 100644
index 0000000000..d644e37f18
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/defer-script-2.js
@@ -0,0 +1 @@
+logScript("Defer2");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write-close.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write-close.js
new file mode 100644
index 0000000000..80703d5c0e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write-close.js
@@ -0,0 +1,3 @@
+document.open();
+document.write(`<script src="sync-script-2.js"></script>`);
+document.close();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write.js
new file mode 100644
index 0000000000..178c374df6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-open-write.js
@@ -0,0 +1,2 @@
+document.open();
+document.write(`<script src="sync-script-2.js"></script>`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-close.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-close.js
new file mode 100644
index 0000000000..7cdde0d78f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-close.js
@@ -0,0 +1,2 @@
+document.write(`<script src="sync-script-2.js"></script>`);
+document.close();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-iframe.sub.html
new file mode 100644
index 0000000000..e3022e3bf1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write-iframe.sub.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<body>
+<script src="helper.js"></script>
+<script>
+logScript("Inline1");
+window.addEventListener("load", () => logScript("WindowLoad"));
+</script>
+<script src="{{GET[script]}}?pipe=trickle(d1)"></script>
+<script src="async-script-1.js" async></script>
+<script src="sync-script-1.js?pipe=trickle(d2)"></script>
+<pre id="bodyend">End</pre>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write.js
new file mode 100644
index 0000000000..413a9bc621
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/document-write.js
@@ -0,0 +1 @@
+document.write(`<script src="sync-script-2.js"></script>`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/helper.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/helper.js
new file mode 100644
index 0000000000..89c6d1e828
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/helper.js
@@ -0,0 +1,17 @@
+window.result = [];
+function log(msg) {
+ window.result.push(msg);
+}
+function checkIfReachedBodyEnd() {
+ const endelement = document.getElementById("bodyend");
+ // `<pre id="bodyend">End</pre>` is needed at the end of HTML.
+ if (endelement && endelement.textContent === "End") {
+ log("EndOfBody");
+ endelement.textContent = "Detected";
+ }
+}
+function logScript(msg) {
+ checkIfReachedBodyEnd();
+ log(msg);
+}
+document.addEventListener("DOMContentLoaded", function() { logScript("DOMContentLoaded"); });
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-1.js
new file mode 100644
index 0000000000..726b56346e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-1.js
@@ -0,0 +1 @@
+logScript("Sync1");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-2.js
new file mode 100644
index 0000000000..ba2edfbf27
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/resources/sync-script-2.js
@@ -0,0 +1 @@
+logScript("Sync2");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/support/async-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/support/async-script.html
new file mode 100644
index 0000000000..d513bafe4f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer-script/support/async-script.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>Child Async Script Execution Order</title>
+<html>
+
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="../resources/helper.js"></script>
+</head>
+
+<body>
+ <script>
+ const reload_key = 'run-after-reload';
+ if (location.search == '?reload' && !window.localStorage.getItem(reload_key)) {
+ window.localStorage.setItem(reload_key, true);
+ location.reload();
+ } else {
+ window.localStorage.clear();
+ test();
+ }
+
+ function test() {
+ setup({ single_test: true });
+ function finish() {
+ assert_array_equals(
+ window.result,
+ ["Inline1", "Sync1", "EndOfBody", "DOMContentLoaded", "Async1"],
+ "Execution order");
+ // Chromium's force-defer order would be:
+ // ["EndOfBody", "Inline1", "Sync1", "DOMContentLoaded", "Async1"]
+ done();
+ }
+ logScript("Inline1");
+ window.addEventListener("load", finish);
+ }
+ </script>
+ <script src="../resources/sync-script-1.js"></script>
+ <!-- Delays are added to make DOMContentLoaded be fired before
+ async script load completion -->
+ <script src="../resources/async-script-1.js?pipe=trickle(d1)" async></script>
+ <pre id="bodyend">End</pre>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer.js
new file mode 100644
index 0000000000..c4449ca7c8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/defer.js
@@ -0,0 +1,4 @@
+t.step(() => {
+ assert_equals(script_run_status, "deferred", "the script run status");
+});
+t.done();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/emptyish-script-elements.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/emptyish-script-elements.html
new file mode 100644
index 0000000000..37f4a87c95
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/emptyish-script-elements.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Treatment of various empty-ish script elements</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#already-started">
+<link rel="help" href="https://github.com/whatwg/html/issues/3419">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script id="no-children"></script>
+<script id="whitespace-child"> </script>
+
+<script id="gets-a-no-text-child"></script>
+<script id="gets-an-empty-text-child"></script>
+<script id="gets-a-text-child"></script>
+<script id="gets-a-comment-child"></script>
+<script id="gets-a-text-descendant"></script>
+
+<script>
+"use strict";
+
+test(() => {
+ const el = document.querySelector("#no-children");
+ el.appendChild(document.createTextNode("window.noChildrenExecuted = true;"));
+ assert_true(window.noChildrenExecuted);
+}, "A script with no children bails early, before setting already-started, so can be executed when adding text");
+
+test(() => {
+ const el = document.querySelector("#whitespace-child");
+ el.appendChild(document.createTextNode("window.whitespaceChildExecuted = true;"));
+ assert_equals(window.whitespaceChildExecuted, undefined);
+}, "A script with a whitespace child executes, setting already-started, so adding text is a no-op");
+
+test(() => {
+ const el = document.querySelector("#gets-a-no-text-child");
+ el.appendChild(document.createElement("span"));
+ el.appendChild(document.createTextNode("window.getsANoTextChildExecuted = true;"));
+ assert_true(window.getsANoTextChildExecuted);
+}, "A script with an empty element inserted bails early, before setting already-started, so can be executed when adding text");
+
+test(() => {
+ const el = document.querySelector("#gets-an-empty-text-child");
+ el.appendChild(document.createTextNode(""));
+ el.appendChild(document.createTextNode("window.getsAnEmptyTextChildExecuted = true;"));
+ assert_true(window.getsAnEmptyTextChildExecuted);
+}, "A script with an empty text node inserted bails early, before setting already-started, so can be executed when adding text");
+
+test(() => {
+ const el = document.querySelector("#gets-a-text-child");
+ el.appendChild(document.createTextNode("window.getsATextChildExecuted1 = true;"));
+ el.appendChild(document.createTextNode("window.getsATextChildExecuted2 = true;"));
+ assert_true(window.getsATextChildExecuted1);
+ assert_equals(window.getsATextChildExecuted2, undefined);
+}, "A script with a text child inserted executes, setting already-started, so adding text is a no-op");
+
+test(() => {
+ const el = document.querySelector("#gets-a-comment-child");
+ el.appendChild(document.createComment("window.getsACommentChild1 = true;"));
+ el.appendChild(document.createTextNode("window.getsACommentChild2 = true;"));
+ assert_equals(window.getsACommentChild1, undefined);
+ assert_true(window.getsACommentChild2);
+}, "A script with a comment child inserted bails early, before setting already-started, so can be executed when adding text");
+
+test(() => {
+ const el = document.querySelector("#gets-a-text-descendant");
+ const child = document.createElement("span");
+ child.appendChild(document.createTextNode("window.getsATextDescendantExecuted1 = true;"));
+ el.appendChild(child);
+ el.appendChild(document.createTextNode("window.getsATextDescendantExecuted2 = true;"));
+ assert_equals(window.getsATextDescendantExecuted1, undefined);
+ assert_true(window.getsATextDescendantExecuted2);
+}, "A script with an element containing text inserted bails early, before setting already-started, so can be executed when adding text");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/001.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/001.html
new file mode 100644
index 0000000000..3f54f764f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: inline in markup </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');</script>
+ <script>log('inline script #2');</script>
+
+ <script type="text/javascript">
+
+ var t = async_test()
+
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/002.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/002.html
new file mode 100644
index 0000000000..df7ca95799
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/002.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: external in markup </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js"></script>
+ <script src="scripts/include-2.js"></script>
+
+ <script type="text/javascript">
+
+ var t = async_test()
+
+
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'external script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/003.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/003.html
new file mode 100644
index 0000000000..9c23b7e715
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/003.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: inline+external in markup </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1')</script>
+ <script src="scripts/include-2.js"></script>
+
+ <script type="text/javascript">
+
+ var t = async_test()
+
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'external script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/004.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/004.html
new file mode 100644
index 0000000000..a21dd388eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/004.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: external+inline in markup </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js"></script>
+ <script>log('inline script #2')</script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'inline script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/005.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/005.html
new file mode 100644
index 0000000000..ff4a66d25e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/005.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write inline in markup </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script>log(\'doc write script\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'doc write script', 'end script #1' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/006.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/006.html
new file mode 100644
index 0000000000..b8785a60c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/006.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write inline - multiple</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script>log(\'doc write script 1\')<\/script>' );
+ document.write( '<script>log(\'doc write script 2\')<\/script>' );
+ eval('log(\'eval 1\')');
+ document.write( '<script>log(\'doc write script 3\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'doc write script 1','doc write script 2', 'eval 1','doc write script 3', 'end script #1' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/007.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/007.html
new file mode 100644
index 0000000000..edd9920757
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/007.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/008.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/008.html
new file mode 100644
index 0000000000..dce763987f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/008.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external - multiple</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ document.write( '<script src="scripts/include-2.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1', 'external script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/009.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/009.html
new file mode 100644
index 0000000000..9d5b2de081
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/009.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external - multiple with doc.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ document.write( '<script src="scripts/include-3.js">log(\'ignore this\')<\/script>' );
+ document.write( '<script src="scripts/include-2.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1', 'external script before doc write', 'document.write external script', 'external script after doc write', 'external script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/010.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/010.html
new file mode 100644
index 0000000000..69a462c301
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/010.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external + inline - multiple with doc.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ document.write( '<script>log(\'inline with doc.write #1\')<\/script>' );
+ document.write( '<script src="scripts/include-2.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1', 'inline with doc.write #1', 'external script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/011.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/011.html
new file mode 100644
index 0000000000..33024ba59e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/011.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external + inline - multiple with doc.write + subsequent markup</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ document.write( '<script>log(\'inline with doc.write #1\')<\/script>' );
+ document.write( '<script src="scripts/include-2.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1', 'inline with doc.write #1', 'external script #2', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/012.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/012.html
new file mode 100644
index 0000000000..01c9293b20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/012.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write external and onload events </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script src="scripts/include-1.js" onload = "log(\'include-1 load\')">log(\'ignore this\')<\/script>' )
+ document.write( '<script src="scripts/include-3.js" onload = "log(\'include-3 load\')"><\/script>' )
+ document.write( '<script src="scripts/include-2.js" onload = "log(\'include-2 load\')">log(\'ignore this\')<\/script>' )
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1', 'include-1 load', 'external script before doc write', 'document.write external script', 'external script after doc write', 'include-3 load', 'external script #2', 'include-2 load', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/013.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/013.html
new file mode 100644
index 0000000000..09616a67d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/013.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added inline script earlier in document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1','end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 100); })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/014.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/014.html
new file mode 100644
index 0000000000..41c90a3421
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/014.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: SCRIPT elements that move themselves in DOM </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.getElementsByTagName('head')[0].appendChild(document.getElementsByTagName('script')[2]);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log('script #2');
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015.html
new file mode 100644
index 0000000000..1fa67e22ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added inline+external+inline script earlier in document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false);
+ var s = testlib.addScript('', { 'src':'scripts/include-1.js' }, document.getElementsByTagName('head')[0], false);
+ testlib.addScript('log(\'head script #2\')', {}, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ ///XXX I think the spec allows this case to race
+ onload = function(){
+ setTimeout(t.step_func(
+ function() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'head script #1', 'head script #2', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'head script #1', 'head script #2', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ }),
+ 100);}
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015a.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015a.html
new file mode 100644
index 0000000000..94763c3542
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/015a.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added inline+external+inline script earlier in document</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false);
+ var s = testlib.addScript('', { 'src':'scripts/include-1.js?pipe=trickle(d1)' }, document.getElementsByTagName('head')[0], false);
+ testlib.addScript('log(\'head script #2\')', {}, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'head script #2', 'end script #1', 'inline script #2', 'external script #1']);
+ t.done();
+ }
+ onload = function(){setTimeout(t.step_func(function() {test.apply(t)}), 2000); }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/016.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/016.html
new file mode 100644
index 0000000000..1149dcc752
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/016.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added inline script later in document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'body script #1\')', {}, document.body, false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'body script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 100); })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/017.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/017.html
new file mode 100644
index 0000000000..66675bcf11
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/017.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: multiple DOM added scripts later in document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'body script #1\')', {}, document.getElementsByTagName('body')[0], false);
+ testlib.addScript('', { 'src':'scripts/include-1.js' }, document.getElementsByTagName('body')[0], false);
+ testlib.addScript('log(\'body script #2\')', {}, document.getElementsByTagName('body')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ //The order of the external script vs the second inline script is undefined because the added script is async by default
+ //But we expect most UAs to have the second order
+ onload = function() {setTimeout(t.step_func(function() {
+ assert_any(assert_array_equals, eventOrder, [
+ ['inline script #1', 'body script #1', 'body script #2', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'body script #1', 'body script #2', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ }), 100);}
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/018.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/018.html
new file mode 100644
index 0000000000..5a349bf556
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/018.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added scripts and doc.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('', { 'src':'scripts/include-3.js' }, document.getElementsByTagName('head')[0], false);
+ testlib.addScript('log(\'body script #2\')', {}, document.getElementsByTagName('body')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ //XXX Need to test this delaying the document after we insert the external script and delaying the external script itself; afaict the spec allows us to race here on whether the document.write
+ //ever actually happens or not according to whether the insertion point is defined at the point at which the script is executed.
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [
+ ['inline script #1', 'body script #2', 'end script #1', 'external script before doc write', 'document.write external script', 'external script after doc write', 'inline script #2'],
+ ['inline script #1', 'body script #2', 'end script #1', 'inline script #2', 'external script before doc write', 'document.write external script', 'external script after doc write'],
+ ['inline script #1', 'body script #2', 'end script #1', 'inline script #2', 'external script before doc write', 'external script after doc write']
+ ]);
+ t.done();
+}
+ onload = t.step_func(function(){setTimeout(test.apply(t), 100); })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/019.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/019.html
new file mode 100644
index 0000000000..64ee4f1c52
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/019.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added scripts and event handling </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script onload="log('inline #1 load')">
+ log('inline script #1');
+ testlib.addScript('', {'src':'scripts/include-1.js', 'onload':function(){log("external #1 load")}}, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'external #1 load', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'external script #1', 'external #1 load']
+ ]);
+ t.done();
+ }
+ onload = function(){setTimeout(t.step_func(test), 100); }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/020.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/020.html
new file mode 100644
index 0000000000..7d8f953e40
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/020.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script with data: URL </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ testlib.addScript('', { 'src':'data:text/javascript,log("data URL script")' }, document.getElementsByTagName('body')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'data URL script', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'data URL script']]);
+ t.done();
+ }
+ onload = function() {setTimeout( t.step_func(test), 100); }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/021.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/021.html
new file mode 100644
index 0000000000..34fdc95cb1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/021.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script with javascript: URL </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ testlib.addScript('', { 'src':'javascript:log("JS URL script")' }, document.getElementsByTagName('body')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', /*'JS URL script',*/ 'inline script #2']);
+ t.done();
+ /* pass condition changed 2010-12-01 due to CT-198 */
+ }
+ onload = t.step_func(function(){setTimeout( test, 100); })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/022.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/022.html
new file mode 100644
index 0000000000..ccbcb347dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/022.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script, late .src </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('', { }, document.getElementsByTagName('body')[0], false);
+ script.src='scripts/include-1.js';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ onload = function() {setTimeout(t.step_func(
+ function() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done()
+ }),
+ 100)}
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/023.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/023.html
new file mode 100644
index 0000000000..dc687ffe4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/023.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script, even later .src </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('', { }, document.getElementsByTagName('body')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2', 'external script #1']);
+ t.done();
+}
+ onload = t.step_func(function(){
+ script.src='scripts/include-1.js';
+ script.onload = t.step_func(test);
+ })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/024.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/024.html
new file mode 100644
index 0000000000..ee807b56f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/024.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script, .src set twice</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('', { }, document.getElementsByTagName('body')[0], false);
+ script.src='scripts/include-1.js';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ script.src='scripts/include-2.js'; // needs to be ignored, script already "is executed"
+ setTimeout(t.step_func(test), 100);
+ })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/025.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/025.html
new file mode 100644
index 0000000000..05c6a97284
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/025.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM added script, .src set on script with content</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('log("inline DOM script #1")', { }, document.getElementsByTagName('body')[0], false);
+ script.src='scripts/include-1.js';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline DOM script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ setTimeout(t.step_func(test), 100);
+ })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/026.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/026.html
new file mode 100644
index 0000000000..34110ff5ba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/026.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: doc write added script, .src set later</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ var t = async_test();
+ document.write('<script><\/script>');
+ var scripts = document.getElementsByTagName('script');
+ scripts[scripts.length - 1].src = 'scripts/include-1.js';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+
+ onload = function() {
+ setTimeout(
+ t.step_func(function() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ }),
+ 100);
+ }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/027.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/027.html
new file mode 100644
index 0000000000..e9fbe7f15c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/027.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: doc write added script with content, .src set later</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ document.write('<script>log(\'doc.write script\')<\/script>');
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ document.getElementsByTagName('script')[4].src='scripts/include-1.js';
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'doc.write script', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ setTimeout(t.step_func(test), 100);
+ })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/028.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/028.html
new file mode 100644
index 0000000000..e383d4f1a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/028.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: javascript: URL</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <script>log('inline script #1');
+ window.location.replace('javascript:log(\'JS URL\')');
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [
+ ['inline script #1', 'end script #1', 'JS URL', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'JS URL']]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/030.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/030.html
new file mode 100644
index 0000000000..f01c257e0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/030.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: javascript: URL in HREF, onclick handler</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <p><a href="javascript:log('JS URL')" onclick="log('click event');return true;"></a></p>
+ <script>log('inline script #1');
+ if(document.links[0].click){
+ document.links[0].click();
+ }else{
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window,
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ document.links[0].dispatchEvent(evt);
+ }
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ var w = window;
+ onload = function() {setTimeout(
+ t.step_func(function() {
+ w.assert_any(w.assert_array_equals, w.eventOrder,
+ [['inline script #1', 'click event', 'end script #1', 'JS URL', 'inline script #2'],
+ ['inline script #1', 'click event', 'end script #1', 'inline script #2', 'JS URL']]);
+ t.done();
+ }), 200);
+ }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/031.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/031.html
new file mode 100644
index 0000000000..3ddb36ab8d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/031.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: focus and blur events</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <form><input type="button" onclick="log('click event')" onfocus="log('focus event')" onblur="log('blur event')"><input type="button" onfocus="log('focus el 2 event')" onblur="log('blur event')"></form>
+ <script>log('inline script #1');
+ document.forms[0][0].focus();
+ document.forms[0][1].click();
+ document.forms[0][1].focus();
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log('inline script #2');
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'focus event', 'blur event', 'focus el 2 event', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 200);})
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/032.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/032.html
new file mode 100644
index 0000000000..da3969740c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/032.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: innerHTML and scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ // script added with innerHTML should not run..
+ document.getElementsByTagName('div')[1].innerHTML = '<script>log("innerHTML script runs")<\/script><script src="scripts/include-1.js"><\/script>';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 200);})
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/033.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/033.html
new file mode 100644
index 0000000000..5c41effcde
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/033.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: innerHTML and scripts moved in DOM</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ // script added with innerHTML should not run..
+ document.getElementsByTagName('div')[0].innerHTML = '<script>log("innerHTML script runs")<\/script><script src="scripts/include-1.js"><\/script>';
+ try{
+ document.body.appendChild( document.getElementsByTagName('div')[0].firstChild );
+ document.body.appendChild( document.getElementsByTagName('div')[0].firstChild );
+ }catch(e){
+ log('ERROR while testing');
+ }
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 200);})
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/034.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/034.html
new file mode 100644
index 0000000000..13664253a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/034.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: innerHTML adding frames with JS in</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ document.getElementsByTagName('div')[1].innerHTML = '<iframe src="pages/helloworld.html"></iframe>';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2', 'frame/popup script']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 200);})
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/035.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/035.html
new file mode 100644
index 0000000000..406c3c548f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/035.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: innerHTML adding frames with JS in and moving scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ document.getElementsByTagName('div')[1].innerHTML = '<iframe src="pages/helloworld.html"></iframe>';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2', 'frame/popup script']);
+ t.done();
+ /*, ['inline script #1', 'end script #1', 'frame/popup script', 'inline script #2'] */
+ }
+ onload = t.step_func(function(){
+ try{
+ document.body.appendChild(document.importNode( top.frames[0].document.getElementsByTagName('script')[0], true ));
+ }catch(e){ log('ERROR - tested functionality not supported'); }
+ setTimeout(t.step_func(test), 200);
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/036.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/036.html
new file mode 100644
index 0000000000..113541dab9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/036.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM cloning</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ try{
+ var script = document.getElementsByTagName('script')[0].cloneNode(true);
+ document.body.appendChild(script);
+ }catch(e){ log('ERROR - tested functionality not supported'); }
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'end script #1', 'inline script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ setTimeout(t.step_func(test), 200);
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/037.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/037.html
new file mode 100644
index 0000000000..15bd8a96e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/037.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM movement with appendChild, inline</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ try{
+ document.body.appendChild(script);
+ }catch(e){ log('ERROR - tested functionality not supported'); }
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'end script #1', 'inline script #2' ]);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ setTimeout(t.step_func(test), 200);
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/038.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/038.html
new file mode 100644
index 0000000000..db6cec3520
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/038.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM movement with appendChild, external</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ var script = testlib.addScript('', { 'src':'scripts/include-1.js' }, document.getElementsByTagName('head')[0], true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ try{
+ document.body.appendChild(script);
+ }catch(e){ log('ERROR - tested functionality not supported'); }
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ }
+ onload = function() {
+ setTimeout(t.step_func(test), 200);
+ };
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/039.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/039.html
new file mode 100644
index 0000000000..3720e24866
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/039.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: IFRAMEs added with DOM</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ for( var i=0; i<2; i++ ){
+ var iframe=document.createElement('iframe');
+ document.getElementsByTagName('div')[1].appendChild(iframe);
+ iframe.src='pages/helloworld.html?'+i+'&'+Math.random();
+ }
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ promise_test(() => {
+ const frames = document.querySelectorAll("iframe");
+ return Promise.all([
+ new Promise(resolve => window.addEventListener('load', resolve)),
+ new Promise(resolve => frames[0].addEventListener('load', resolve)),
+ new Promise(resolve => frames[1].addEventListener('load', resolve)),
+ ]).then(() => {
+ assert_equals(eventOrder.length, 5);
+ assert_array_equals(
+ eventOrder.slice(0, 3),
+ ['inline script #1', 'end script #1', 'inline script #2'],
+ "inline scripts should run first");
+ assert_in_array('frame/popup script 0', eventOrder.slice(3, 5), 'iframe should have loaded');
+ assert_in_array('frame/popup script 1', eventOrder.slice(3, 5), 'iframe should have loaded');
+ });
+ }, 'iframes should load asynchronously after inline script run');
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/040.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/040.html
new file mode 100644
index 0000000000..3cdf87f07b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/040.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: IFRAMEs added with DOM (innerHTML), javascript: URL</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>log('inline script #1');
+ document.getElementsByTagName('div')[1].innerHTML = '<iframe src="javascript:parent.log(\'JS URL\');\'<html><script>parent.log(\\\'frame script\\\')<\/script></html>\'"></iframe>';
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [
+ ['inline script #1', 'end script #1', 'JS URL', 'inline script #2', 'frame script'],
+ /* the following combination seems quite unlikely? */
+ ['inline script #1', 'end script #1', 'JS URL', 'frame script', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'JS URL', 'frame script']]);
+ t.done();
+ }
+ onload = t.step_func(function(){
+ setTimeout(t.step_func(test), 200);
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/041.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/041.html
new file mode 100644
index 0000000000..bce7041185
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/041.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write scripts that write scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.write( '<script>log(\'inline with doc.write #1\'); document.write(\'<script src="scripts/include-4.js"><\\\/script>\');log(\'end inline with doc.write\');<\/script>' );
+ document.write( '<script src="scripts/include-1.js">log(\'ignore this\')<\/script>' );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline with doc.write #1', 'end inline with doc.write', 'end script #1', 'include-4 before doc write', 'include-4 after doc write', 'external script before doc write', 'document.write external script', 'external script after doc write', 'external script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html
new file mode 100644
index 0000000000..df3a2f88f2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM mutation events when adding scripts: DOMNodeInserted </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false );
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html
new file mode 100644
index 0000000000..bcfd90cba4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInserted </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false );
+ testlib.addScript('', { src: 'scripts/include-1.js' }, document.getElementsByTagName('head')[0], false);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2', 'external script #1']]
+ );
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html
new file mode 100644
index 0000000000..8d412079e4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false ); } );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html
new file mode 100644
index 0000000000..254e0d1366
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('', {src:'scripts/include-1.js'}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false);});
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ onload = t.step_func(function() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/046.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/046.html
new file mode 100644
index 0000000000..4f145d63e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/046.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: no readystatechange events when adding external scripts </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('', {src:'scripts/include-1.js', onreadystatechange:function() {log( 'readystatechange '+ this.readyState );}}, document.getElementsByTagName('head')[0], false );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/047.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/047.html
new file mode 100644
index 0000000000..88509e9d43
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/047.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding and removing external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('', {src:'scripts/include-1.js'}, document.getElementsByTagName('head')[0], false );
+ script.parentNode.removeChild(script);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/048.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/048.html
new file mode 100644
index 0000000000..8879f035d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/048.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding inline script which sets its own .src </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('log(\'HEAD script start\');document.getElementsByTagName(\'script\')[0].src=\'scripts/include-1.js\';log(\'HEAD script end\')', {}, document.getElementsByTagName('head')[0], true );
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'HEAD script start', 'HEAD script end', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/049.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/049.html
new file mode 100644
index 0000000000..455a20c549
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/049.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding external script but removeAttribute( src ) before it runs</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('log(\'HEAD script\');', { src:'scripts/include-1.js' }, document.getElementsByTagName('head')[0], false );
+ script.removeAttribute('src');
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/050.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/050.html
new file mode 100644
index 0000000000..a400749f18
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/050.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding external script that removes all scripts from document</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('', { src:'scripts/include-5.js' }, document.getElementsByTagName('head')[0], false );
+ // caching might affect whether the below script runs or not. Adding Math.random() makes the test a bit more predictable? :-p
+ var script=testlib.addScript('', { src:'scripts/include-1.js?pipe=trickle(d1)&'+Math.random() }, document.getElementsByTagName('head')[0], false );
+ log('end script #1');
+ </script>
+ <script src="scripts/include-2.js?pipe=trickle(d4)"></script>
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ // Per-spec, non-blocking/async scripts can execute at any time.
+ // Therefore, there are two possibilities for the script order here.
+ // 1. inline script first, followed by include-5 (async), then
+ // external script #1 (slow async) and finally external #2
+ // (inline).
+ // 2. inline script, external '2, 'include 5', then include-1.
+ assert_array_equals(eventOrder.slice(0, 2), [
+ 'inline script #1', 'end script #1'
+ ]);
+ if (eventOrder[2] == 'include-5 before removing scripts') {
+ assert_array_equals(eventOrder.slice(3), [
+ 'include-5 after removing scripts', 'external script #1',
+ 'external script #2'
+ ]);
+ } else {
+ assert_array_equals(eventOrder.slice(2), ['external script #2',
+ 'include-5 before removing scripts',
+ 'include-5 after removing scripts',
+ 'external script #1'
+ ]);
+ }
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/051.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/051.html
new file mode 100644
index 0000000000..a0b674304f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/051.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: interaction of parsing and script execution - script added through DOM</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ testlib.addScript('', { src: 'scripts/count-script-tags.js' }, document.body, true);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'script tags in DOM: 5', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'inline script #2', 'script tags in DOM: 6']]);
+ t.done();
+ }
+ onload = function(){setTimeout(t.step_func(test), 100); }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/052.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/052.html
new file mode 100644
index 0000000000..21a151cb79
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/052.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: interaction of parsing and script execution - external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/count-script-tags.js"></script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['script tags in DOM: 4', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(function(){setTimeout(t.step_func(test), 100); })
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/053.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/053.html
new file mode 100644
index 0000000000..810197437d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/053.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding external script that removes itself from document when loading</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('', { src:'scripts/include-1.js', onload:function() {this.parentNode.removeChild(this);log('removed ' + this.localName);} }, document.getElementsByTagName('body')[0], true );
+ log('end script #1');
+ </script>
+ <script src="scripts/include-2.js"></script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'end script #1', 'external script #1', 'removed script', 'external script #2', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'external script #2', 'external script #1', 'removed script', 'inline script #2'],
+ ['inline script #1', 'end script #1', 'external script #2', 'inline script #2', 'external script #1', 'removed script']]
+ );
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html
new file mode 100644
index 0000000000..29ede23414
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing newly inserted script from DOMNodeInserted handler - external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.addEventListener( 'DOMNodeInserted', function listener(e){
+ log('DOMNodeInserted event');
+ e.target.parentNode.removeChild(e.target);
+ document.removeEventListener('DOMNodeInserted', listener);
+ }, false );
+ var script=testlib.addScript('', { src:'scripts/include-1.js?'+Math.random() }, document.getElementsByTagName('body')[0], true );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted event', 'end script #1', 'inline script #2', 'external script #1'],
+ ['inline script #1', 'DOMNodeInserted event', 'end script #1', 'external script #1', 'inline script #2']]);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html
new file mode 100644
index 0000000000..c837d78174
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing newly inserted script from DOMNodeInserted handler - inline script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ document.addEventListener( 'DOMNodeInserted', function listener(e){
+ log('DOMNodeInserted event');
+ e.target.parentNode.removeChild(e.target);
+ document.removeEventListener('DOMNodeInserted', listener);
+ }, false );
+ var script=testlib.addScript('log(\'added script\')', { }, document.getElementsByTagName('body')[0], true );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'added script', 'DOMNodeInserted event', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/056.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/056.html
new file mode 100644
index 0000000000..e2d0868034
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/056.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: appending code to initially empty SCRIPT tag in DOM </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ script.appendChild( document.createTextNode('log("injected script code");') );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ // Test asserts the injected script should run
+ assert_array_equals(eventOrder, ['inline script #1', 'injected script code', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/057.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/057.html
new file mode 100644
index 0000000000..4dc8e1384e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/057.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: appending code to initially non-empty SCRIPT tag in DOM (whitespace only) </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>
+ </script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ script.appendChild( document.createTextNode('log("injected script code");') );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html
new file mode 100644
index 0000000000..15deb785c2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/058.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: appending code to initially non-empty SCRIPT tag in DOM (comment only) </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>/**/</script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ script.appendChild( document.createTextNode('log("injected script code");') );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/059.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/059.html
new file mode 100644
index 0000000000..b3a34367b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/059.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: appending code to initially non-empty SCRIPT tag in DOM after removing its initial child </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>/**/</script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ script.removeChild(script.firstChild);
+ script.appendChild( document.createTextNode('log("injected script code");') );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/060.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/060.html
new file mode 100644
index 0000000000..905dfe233f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/060.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: appending code to initially non-empty SCRIPT tag in DOM after setting textContent/innerHTML</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>log('HEAD script');</script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ script.innerHTML='';
+ script.appendChild( document.createTextNode('log("injected script code 1");') );
+ script.textContent='';
+ script.appendChild( document.createTextNode('log("injected script code 2");') );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['HEAD script', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/061.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/061.html
new file mode 100644
index 0000000000..9950b1c7ac
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/061.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode and script execution</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>log('HEAD script');</script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ document.body.appendChild( script.cloneNode(true) );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['HEAD script', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/062.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/062.html
new file mode 100644
index 0000000000..c5e0ee2d46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/062.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode (shallow) and script execution</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>log('HEAD script');</script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ document.body.appendChild( script.cloneNode(false) ).appendChild(document.createTextNode('log("clone");'));
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['HEAD script', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/063.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/063.html
new file mode 100644
index 0000000000..6824074a8c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/063.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode (deep) of the currently executing script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>log('HEAD script');
+ if( !window.already_cloned ){
+ window.already_cloned=true;
+ var script=document.getElementsByTagName('script')[3];
+ document.getElementsByTagName('head')[0].appendChild( script.cloneNode(true) );
+ }
+ </script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['HEAD script', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/064.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/064.html
new file mode 100644
index 0000000000..ceedc3da2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/064.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode with external script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script src="scripts/include-1.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3];
+ document.body.appendChild( script.cloneNode(true) );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/065.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/065.html
new file mode 100644
index 0000000000..5859dc9e0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/065.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode with external script, changed .src</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script src="scripts/include-1.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3].cloneNode(true);
+ script.src='scripts/include-2.js'
+ document.body.appendChild( script );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/066.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/066.html
new file mode 100644
index 0000000000..a8e346dfd8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/066.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: cloneNode with external script, removing .src and adding content</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script src="scripts/include-1.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=document.getElementsByTagName('script')[3].cloneNode(true);
+ script.removeAttribute('src');
+ script.appendChild(document.createTextNode( 'log("cloned script");' ));
+ document.body.appendChild( script );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/067.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/067.html
new file mode 100644
index 0000000000..7be0fd0ab0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/067.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: is a script with syntax error marked as "has run"? </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>setup({allow_uncaught_exception:true})
+ var t = async_test()
+ </script>
+ <script>
+ log(This script will never run..
+ </script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>t.step(function() {
+ log('inline script #1');
+ var script=document.getElementsByTagName('script')[3].cloneNode(true);
+ script.removeChild(script.firstChild);
+ script.appendChild(document.createTextNode( 'log("cloned script");' ));
+ document.body.appendChild( script );
+ log('end script #1');
+ })
+ </script>
+ <script type="text/javascript">
+ t.step(function() {
+ log( 'inline script #2' );
+ });
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+</script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/068.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/068.html
new file mode 100644
index 0000000000..a58158b6c0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/068.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: external script and parsing of markup added with document.write </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ log('inline script #1');
+ document.write('<script src="scripts/find-foo.js">log(\'inline code in external script (not expected to run!!)\')<\/script>' + '<div id="foo"></div>');
+ log('end script #1');
+
+ var t = async_test()
+
+
+ function test() {
+ if(!window.findFooLoaded) {
+ return setTimeout(t.step_func(test),200);
+ }
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'found #foo element: NO']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/069.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/069.html
new file mode 100644
index 0000000000..4d4aed2658
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/069.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external files added through DOM should not block further parsing while loading</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>
+ testlib.addScript('',{src:'scripts/find-body.js?pipe=trickle(d1)'},document.getElementsByTagName('head')[0], true );
+ </script>
+</head>
+<body>
+ <script>
+ testlib.addScript('', {src:'scripts/find-foo.js?pipe=trickle(d1)'}, document.getElementsByTagName('head')[0], true);
+ </script>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <p><span id="foo"></span></p>
+
+ <script type="text/javascript">
+ var t = async_test()
+
+ function test() {
+ if(!(window.findFooLoaded && window.findBodyLoaded)) {
+ return setTimeout(t.step_func(test), 200);
+ }
+ assert_any(assert_array_equals, eventOrder,
+ [['document.body: <BODY>', 'found #foo element: YES'],
+ ['found #foo element: YES', 'document.body: <BODY>']]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/070.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/070.html
new file mode 100644
index 0000000000..4b82a9e83f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/070.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write into IFRAME a script that adds a SCRIPT through DOM</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe></iframe>
+
+ <script type="text/javascript">
+ var doc = document.getElementsByTagName('iframe')[0].contentDocument;
+ doc.open();
+
+ log("calling document.write");
+ doc.write('<script>top.log("inline script #1");'+
+ 'var s=document.createElement("script");'+
+ 's.src="scripts/include-6.js?'+new Date().getTime()+'";'+
+ 'document.getElementsByTagName("head")[0].appendChild(s);'+
+ '<\/script>'+
+ '<div id="foo"></div>'+
+ '<script>top.log("inline script #2");<\/script>'
+ );
+
+ log("calling document.close");
+ doc.close();
+
+ var t = async_test()
+
+
+ function test() {
+ if(!window.include6Loaded) {
+ return setTimeout(t.step_func(test),200);
+ }
+ assert_array_equals(eventOrder, ['calling document.write', 'inline script #1', 'inline script #2', 'calling document.close', 'external script (#foo found? YES)']);
+ t.done();
+ }
+
+ onload = t.step_func(test)
+ </script>
+</head>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/071.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/071.html
new file mode 100644
index 0000000000..802c4a8ce3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/071.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write several scripts into IFRAME </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe style="width:1px;height:1px"></iframe>
+
+ <script type="text/javascript">
+ var doc = document.getElementsByTagName('iframe')[0].contentDocument;
+ doc.open();
+
+ var html = '<html><head><title>test</title></head>'+
+ '<script>top.log("inline script #1");'+
+ '<\/script>'+
+ /* made url unique because Chrome will change
+ order depending on file cached status */
+ '<script src="scripts/include-6.js?'+new Date().getTime()+'"><\/script>'+
+ '</head>'+
+ '<body>'+
+ '<div id="foo"></div>'+
+ '</body></html>'+
+ '<script>top.log("inline script #2");<\/script>';
+ log("calling document.write");
+ doc.write(html);
+
+ log("calling document.close");
+ doc.close();
+
+ var t = async_test()
+
+
+ function test() {
+ if( !window.include6Loaded )return setTimeout(t.step_func(test),200); // try checking again if external script didn't run yet
+ assert_array_equals(eventOrder, ['calling document.write',
+ 'inline script #1',
+ 'calling document.close',
+ 'external script (#foo found? NO)',
+ 'inline script #2'
+ ]);
+ t.done();
+ }
+
+ onload = t.step_func(test)
+ </script>
+</head>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/072.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/072.html
new file mode 100644
index 0000000000..e502a35736
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/072.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write into IFRAME a script that creates new inline script in parent </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe style="width:1px;height:1px"></iframe>
+
+ <script type="text/javascript">
+ var doc = document.getElementsByTagName('iframe')[0].contentDocument;
+ doc.open();
+
+ var html = '<html><head><title>test</title></head>'+
+ '<script>top.log("inline script #1");'+
+ '<\/script>'+
+ '</head>'+
+ '<body>'+
+ '<div id="foo"></div>'+
+ '</body></html>'+
+ '<script>top.testlib.addScript( \'log("inline script added to parent")\', null, top.document.body, true )<\/script>';
+ log("calling document.write");
+ doc.write(html);
+
+ log("calling document.close");
+ doc.close();
+
+ var t = async_test()
+
+
+ function test() {
+ assert_array_equals(eventOrder, ['calling document.write',
+ 'inline script #1',
+ 'inline script added to parent',
+ 'calling document.close',
+ ]);
+ t.done();
+ }
+
+ onload = t.step_func(test)
+ </script>
+</head>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/073.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/073.html
new file mode 100644
index 0000000000..6f65c4ae19
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/073.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write into IFRAME a script that creates new external script in parent </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe style="width:1px;height:1px"></iframe>
+
+ <script type="text/javascript">
+ var doc = document.getElementsByTagName('iframe')[0].contentDocument;
+ doc.open();
+
+ var html = '<html><head><title>test</title></head>'+
+ '<script>top.log("inline script #1");'+
+ '<\/script>'+
+ '</head>'+
+ '<body>'+
+ '<div id="foo"></div>'+
+ '</body></html>'+
+ '<script>top.testlib.addScript( \'\', { src:\'scripts/include-1.js\' }, top.document.body, true )<\/script>';
+ log("calling document.write");
+ doc.write(html);
+
+ log("calling document.close");
+ doc.close();
+
+ var t = async_test()
+
+
+ function test() {
+
+ assert_array_equals(eventOrder, ['calling document.write',
+ 'inline script #1',
+ 'calling document.close',
+ 'external script #1'
+ ]);
+
+ t.done();
+ }
+
+ onload = t.step_func(test)
+ </script>
+</head>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/074.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/074.html
new file mode 100644
index 0000000000..70d7b88b74
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/074.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: document.write into IFRAME a script that creates new inline script in parent that again adds script to IFRAME </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe style="width:1px;height:1px"></iframe>
+
+ <script type="text/javascript">
+ var doc = document.getElementsByTagName('iframe')[0].contentDocument;
+ doc.open();
+ var str1='';
+ var html = '<html><head><title>test</title></head>'+
+ '<script>top.log("inline script #1");'+
+ '<\/script>'+
+ '</head>'+
+ '<body>'+
+ '<script>top.testlib.addScript( \'top.log("inline script added to parent");top.doc.write( "<script>top.log(\\\\"inline script added to iframe\\\\")<\\\/script>");\', null, top.document.body, true ) <\/script>'+
+ '</body></html>';
+ log("calling document.write");
+ doc.write(html);
+
+ log("calling document.close");
+ doc.close();
+
+ var t = async_test()
+
+
+ function test() {
+ assert_array_equals(eventOrder, ['calling document.write',
+ 'inline script #1',
+ 'inline script added to parent',
+ 'inline script added to iframe',
+ 'calling document.close',
+ ]);
+ t.done();
+ }
+
+ onload = t.step_func(test)
+ </script>
+</head>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/075.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/075.html
new file mode 100644
index 0000000000..40ec9bbb6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/075.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>dispatchEvent from child frame during document.write :-o </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ </head>
+ <body onclick="log('click event')">
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <iframe></iframe>
+ <script>
+ var doc = document.getElementsByTagName("iframe")[0].contentDocument;
+ doc.open("text/html");
+ doc.write('<html><head><title>event dispatcher</title></head><body>Before script<script>top.log("inline script before event");var ev = parent.document.createEvent("MouseEvents");ev.initMouseEvent("click", true, false, null, 0, 0, 0, 0, 0, false, false, false, false, 0, null);parent.document.body.dispatchEvent(ev);top.log("inline script after event");</sc'+'ript> After script</body>');
+ log( 'end main script' );
+
+
+ </script>
+
+<script>
+ var t = async_test()
+
+ function test() {
+ if(test.ran)return; test.ran=true;
+
+ assert_array_equals(eventOrder, ['inline script before event',
+ 'click event',
+ 'inline script after event',
+ 'end main script'
+ ]);
+ doc.close();
+ t.done();
+}
+
+ onload = t.step_func(test)
+ /* onload doesn't fire in this test, a fallback.. */
+ setTimeout(t.step_func(test), 800 );
+</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/076.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/076.html
new file mode 100644
index 0000000000..2b8b692d92
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/076.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding and removing external and inline scripts </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>log('inline script #1');
+ var script=testlib.addScript('', {src:'scripts/include-1.js', onload:function(e){ e.target.parentNode.removeChild(e.target); }}, document.getElementsByTagName('head')[0], false );
+ var script=testlib.addScript( 'log( "dynamically added inline script" )', null, document.getElementsByTagName('head')[0], false );
+ script.parentNode.removeChild(script);
+ log('end script #1');
+ </script>
+
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ }
+ onload = t.step_func(function() {
+ assert_any(assert_array_equals, eventOrder, [['inline script #1', 'dynamically added inline script', 'end script #1', 'external script #1', 'inline script #2'],
+ ['inline script #1', 'dynamically added inline script', 'end script #1', 'inline script #2', 'external script #1']]);
+ t.done();
+ })
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/077.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/077.html
new file mode 100644
index 0000000000..dbcd16bea5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/077.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title> adding several types of scripts through the DOM and removing some of them confuses scheduler </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script type="text/javascript">
+ var head = document.getElementsByTagName('head')[0];
+ function createScript(url, contents) {
+ props = {};
+ if (url) {
+ props.src = url;
+ }
+ return testlib.addScript(contents, props, head, false);
+ }
+ var t = async_test()
+
+ function test() {
+ var script = createScript('data:text\/javascript,log("Script %231 ran")');
+ var script2 = createScript('','log("Script #2 ran")');
+ if(script2) {
+ head.removeChild(script2);
+ }
+ var script3 = createScript('data:text\/javascript, log("Script %233 ran"); createScript(\'\', \'log("Script %234 ran")\')');
+ if(script3) {
+ head.removeChild(script3);
+ }
+ setTimeout(t.step_func(function(){
+ assert_array_equals(eventOrder, ['Script #2 ran', 'Script #1 ran', 'Script #3 ran','Script #4 ran']);
+ t.done();
+ }), 400);
+
+ };
+ onload = t.step_func(test)
+ </script>
+ </head>
+ <body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ </body>
+</html*>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/078.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/078.html
new file mode 100644
index 0000000000..da4db4a2e6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/078.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title> adding several types of scripts through the DOM and removing some of them confuses scheduler (slow-loading scripts) </title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="testlib/testlib.js"></script>
+<script type="text/javascript">
+ setup({ explicit_done: true });
+ var head = document.getElementsByTagName('head')[0];
+ function createScript(url, contents) {
+ props = {};
+ if (url) {
+ props.src = url;
+ }
+ return testlib.addScript(contents, props, head, false);
+ }
+ var t = async_test()
+
+ function test() {
+ document.getElementById("log").textContent = "Please wait..."
+ var url = 'scripts/include-1.js?pipe=trickle(d1)';
+ var script = createScript(url);
+ var script2 = createScript('', 'log("Script #2 ran")');
+ head.removeChild(script2);
+ var url = 'scripts/include-2.js?pipe=trickle(d2)';
+ var script3 = createScript(url);
+ head.removeChild(script3);
+
+ setTimeout(t.step_func(function () {
+ done();
+ assert_array_equals(eventOrder, ['Script #2 ran', 'external script #1', 'external script #2']);
+ t.done();
+ }), 5500);
+
+ };
+ onload = t.step_func(test)
+</script>
+</head>
+<body>
+<div id="log">FAILED (This TC requires JavaScript enabled)</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/079.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/079.html
new file mode 100644
index 0000000000..8d684cebf2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/079.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title> setting location to javascript URL from event handler </title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="testlib/testlib.js"></script>
+<script type="text/javascript">
+log('inline script #1');
+var t = async_test()
+
+onload = t.step_func(function() {
+ log('onload handler');
+ document.getElementById("log").textContent = 'please wait...';
+ window.location='javascript:log("javascript: URL")';
+ setTimeout(t.step_func(function(){
+ log('timeout');
+ assert_array_equals(eventOrder, ['inline script #1', 'onload handler', 'onload ends', 'javascript: URL', 'timeout']);
+ t.done();
+ }), 200);
+ log('onload ends');
+});
+</script>
+</head>
+<body>
+<div id="log">FAILED (This TC requires JavaScript enabled)</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/081.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/081.html
new file mode 100644
index 0000000000..1b9bc991c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/081.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: slow loading external script added with DOM (appendChild)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>
+ var t = async_test()
+ log('inline script #1');
+ testlib.addScript('', { src:'scripts/include-1.js?pipe=trickle(d1)&'+Math.random() }, document.getElementsByTagName('head')[0], false );
+ log('end script #1');
+ </script>
+ <script src="scripts/include-2.js"></script>
+ <script>
+ log( 'inline script #2' );
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'external script #2', 'inline script #2', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(function() {
+ setTimeout(t.step_func(test), 12);
+ });
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/082.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/082.html
new file mode 100644
index 0000000000..3e88fc73d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/082.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: multiple slow loading external scripts added with DOM (appendChild)</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div></div>
+ <script>
+
+ log('inline script #1');
+ function scriptLoadListener(){
+ log( 'load on '+this.src.match( /include-\d\.js/ ) );
+ }
+ var script=testlib.addScript('', { src:'scripts/include-1.js?pipe=trickle(d1)&' + Math.random(), onload:scriptLoadListener }, document.getElementsByTagName('head')[0], false );
+ var script=testlib.addScript('', { src:'scripts/include-2.js?pipe=trickle(d3)&' + Math.random(), onload:scriptLoadListener }, document.getElementsByTagName('head')[0], false );
+ var script=testlib.addScript('', { src:'scripts/include-7.js?pipe=trickle(d2)&' + Math.random() , onload:scriptLoadListener }, document.getElementsByTagName('head')[0], false );
+ log('end script #1');
+ </script>
+ <script type="text/javascript">
+ log('inline script #2');
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end script #1', 'inline script #2', 'external script #1', 'load on include-1.js', 'external script #7', 'load on include-7.js', 'external script #2', 'load on include-2.js']);
+ t.done();
+ }
+ onload = function() {setTimeout(t.step_func(test), 12)};
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/083.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/083.html
new file mode 100644
index 0000000000..2ac0015c8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/083.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: event listener defined by script in a document in history</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <iframe src="about:blank"></iframe>
+ <script>
+ log('inline script #1');
+ function fireFooEvent(){
+ var evt=document.createEvent('Event');
+ evt.initEvent('foo', true, true);
+ document.dispatchEvent(evt);
+ }
+ var doc = frames[0].document;
+ doc.open('text/html');
+ doc.write('<script>top.log("IFRAME script");top.document.addEventListener("foo", function(e){ top.log("event: "+e.type); }, false)<\/script>');
+ log('end script #1');
+ </script>
+ <script>
+ fireFooEvent();
+ frames[0].location='about:blank'; // returning to about:blank should de-activate document that defined event listener..?
+ </script>
+ <script>
+ fireFooEvent();
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_equals(frames[0].location.toString(), "about:blank");
+ assert_array_equals(eventOrder, ['inline script #1',
+ 'IFRAME script',
+ 'end script #1',
+ 'event: foo',
+ 'inline script #2'
+ ]);
+ t.done();
+ }
+ onload = function() {setTimeout(t.step_func(function() {fireFooEvent(); test()}), 80)};
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/084.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/084.html
new file mode 100644
index 0000000000..3027fa1994
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/084.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: event listener defined by script in a removed IFRAME</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <iframe src="about:blank"></iframe>
+ <script>
+ log('inline script #1');
+ function fireFooEvent(){
+ var evt=document.createEvent('Event');
+ evt.initEvent('foo', true, true);
+ document.dispatchEvent(evt);
+ }
+ var doc=frames[0].document;
+ doc.open( 'text/html' );
+ doc.write( '<script>top.log("IFRAME script");top.document.addEventListener("foo", function(e){ top.log("event: "+e.type); }, false)<\/script>' );
+ log('end script #1');
+ </script>
+ <script>
+ fireFooEvent();
+ frames[0].frameElement.parentNode.removeChild( frames[0].frameElement ); // removing the IFRAME should de-activate document that defined event listener..?
+ </script>
+ <script>
+ fireFooEvent();
+ </script>
+ <script type="text/javascript">
+ log( 'inline script #2' );
+ var t = async_test()
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1',
+ 'IFRAME script',
+ 'end script #1',
+ 'event: foo',
+ 'inline script #2'
+ ]);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/085.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/085.html
new file mode 100644
index 0000000000..6577527a8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/085.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: async script and slow-loading defer script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js?pipe=trickle(d1)" defer></script>
+ <script src="scripts/include-2.js" async></script>
+
+ <script type="text/javascript">
+ var t = async_test();
+ function test() {
+ assert_array_equals(eventOrder, ['external script #2', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/086.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/086.html
new file mode 100644
index 0000000000..4ccd16de89
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/086.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: async script and slow-loading async script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js?pipe=trickle(d2)" async></script>
+ <script src="scripts/include-2.js" async></script>
+
+ <script type="text/javascript">
+ var t = async_test();
+ function test() {
+ assert_array_equals(eventOrder, ['external script #2', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/087.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/087.html
new file mode 100644
index 0000000000..8e225f48ae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/087.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: multiple defer scripts, one slow loading</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js?pipe=trickle(d2)" defer></script>
+ <script src="scripts/include-2.js" defer></script>
+
+ <script type="text/javascript">
+ var t = async_test();
+ function test() {
+ assert_array_equals(eventOrder, ['external script #1', 'external script #2']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/088.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/088.html
new file mode 100644
index 0000000000..f41f3d5be2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/088.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: multiple scripts with defer and async attributes</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script src="scripts/include-1.js?pipe=trickle(d2)" defer async></script>
+ <script src="scripts/include-2.js" defer async></script>
+
+ <script type="text/javascript">
+ var t = async_test();
+ function test() {
+ assert_array_equals(eventOrder, ['external script #2', 'external script #1']);
+ t.done();
+ }
+ onload = t.step_func(test);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/089.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/089.html
new file mode 100644
index 0000000000..9ed5e0e1da
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/089.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: async attribute on inline script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script async>
+ var t = async_test();
+ log('inline script #1');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1']);
+ });
+ </script>
+ <script async>
+ log('inline script #2');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline script #2']);
+ });
+ </script>
+
+ <script>
+ log('inline script #3');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline script #2', 'inline script #3']);
+ });
+ onload = function() {t.done()};
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/090.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/090.html
new file mode 100644
index 0000000000..17d1d1effe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/090.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer attribute on inline script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script defer>
+ var t = async_test();
+ log('inline script #1');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1']);
+ });
+ </script>
+ <script defer>
+ log('inline script #2');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline script #2']);
+ });
+ </script>
+
+ <script>
+ log('inline script #3');
+ t.step(function() {
+ assert_array_equals(eventOrder, ['inline script #1', 'inline script #2', 'inline script #3']);
+ });
+ onload = function() {t.done()};
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/091.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/091.html
new file mode 100644
index 0000000000..f706cd31f5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/091.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: force-async off on non-parser-inserted script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ var t = async_test();
+
+ sources = ["scripts/include-1.js?pipe=trickle(d2)", "scripts/include-2.js?pipe=trickle(d1)"];
+ sources.forEach(function(x) {
+ var script = document.createElement("script");
+ script.src = x;
+ t.step(function() {assert_equals(script.async, true, "async IDL attribute on script creation")});
+ script.async = false;
+ t.step(function() {assert_equals(script.async, false, "async IDL attribute after setting")});
+ t.step(function() {assert_equals(script.getAttribute("async"), null, "async content attribute after setting")});
+ document.head.appendChild(script);
+ });
+
+ onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ['external script #1', 'external script #2']);
+ t.done();
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/092.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/092.html
new file mode 100644
index 0000000000..40fda5a0c0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/092.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer script and slow-loading non-async external script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ var t = async_test();
+
+ var script = document.createElement("script");
+ script.src = "scripts/include-2.js?pipe=trickle(d2)";
+ script.async = false;
+ document.head.appendChild(script);
+
+ onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ['external script #1', 'external script #2']);
+ t.done();
+ });
+ </script>
+ <script defer src="scripts/include-1.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/094.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/094.html
new file mode 100644
index 0000000000..cc9d1bf0fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/094.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: parser-created defer script after document load</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <iframe id="myFrame"></iframe>
+
+ <script>
+ var t = async_test();
+ onload = t.step_func(function() {
+ var doc = document.getElementById("myFrame").contentDocument;
+ var win = document.getElementById("myFrame").contentWindow;
+ doc.open();
+ doc.write("<title> scheduler: parser-created defer script after document load</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><script>var t=async_test()<\/script><div id=log></div><script defer src='data:text/javascript,parent.t.done();'><\/script>");
+ doc.close();
+ })
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/095.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/095.html
new file mode 100644
index 0000000000..5e3b388cf1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/095.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: slow-loading script added from defer blocking load event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ var t = async_test();
+ function test() {
+ t.step(function() {
+ assert_array_equals(eventOrder, ['external script #8', 'external script #9']);
+ t.done();
+ });
+ }
+ //assert that the test is completed before onload fires
+ onload = t.step_func(function() {assert_unreached()});
+ </script>
+ <script defer src="scripts/include-8.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/096.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/096.html
new file mode 100644
index 0000000000..a2e15b782a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/096.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer script added from document.write relative to DOMContentLoaded</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ log("inline script #1");
+ document.write("<script defer src='scripts/include-1.js'><\/script>")
+ </script>
+ <script>
+ log("inline script #2");
+ var t = async_test();
+
+ addEventListener("DOMContentLoaded", t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "external script #1"]);
+ log("inline script #3");
+ }), false);
+
+ onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "external script #1", "inline script #3"]);
+ t.done();
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/097.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/097.html
new file mode 100644
index 0000000000..a31d49e5b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/097.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: slow-loading async script added from document.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ log("inline script #1");
+ document.write("<script async src='scripts/include-1.js?pipe=trickle(d2)'><\/script>")
+ </script>
+ <script>
+ log("inline script #2");
+ var t = async_test();
+
+ addEventListener("DOMContentLoaded", t.step_func(function() {assert_array_equals(eventOrder, ["inline script #1", "inline script #2"])}), false);
+
+ onload = t.step_func(
+ function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "external script #1"]);
+ t.done();
+ });
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/099.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/099.html
new file mode 100644
index 0000000000..987fcc7c71
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/099.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer adding iframe containing script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script defer src="scripts/include-11.js"></script>
+ <script>
+ var t = async_test();
+
+ onload = t.step_func(function() {assert_array_equals(eventOrder, ["external script before adding iframe", "script in iframe"]); t.done();});
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/101.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/101.html
new file mode 100644
index 0000000000..b868f9a447
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/101.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer script after initial onload event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <iframe id="myFrame"></iframe>
+
+ <script>
+ var t = async_test();
+ onload = t.step_func(
+ function() {
+ var doc = document.getElementById("myFrame").contentDocument;
+ var win = document.getElementById("myFrame").contentWindow;
+ doc.open();
+ doc.write("<title> scheduler: defer script after initial onload event</title><script src='testlib/testlib.js'><\/script><div id='log'>document.written content</div><script>log('inline script #1');<\/script><script src='scripts/include-1.js'><\/script><script defer src='scripts/include-2.js'><\/script>");
+ doc.close();
+ //Note that the *window* object has changed but the *global scope* of the script has not.
+ var run_t = window.t.step_func(function() {
+ if (!win.eventOrder || win.eventOrder.length != 3) {
+ window.setTimeout(run_t, 100);
+ return;
+ }
+ window.assert_array_equals(win.eventOrder, ['inline script #1', 'external script #1', 'external script #2']);
+ window.t.done();
+ });
+ run_t();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/102.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/102.html
new file mode 100644
index 0000000000..439023833f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/102.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: defer script after initial onload event</title>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ onload = function() {
+ document.open();
+ document.write("<title> scheduler: defer script after initial onload event</title><script src='/resources/testharness.js'><\/script><script src='/resources/testharnessreport.js'><\/script><script src='testlib/testlib.js'><\/script><div id='log'>document.written content</div><script>var t = async_test(); log('inline script #1')<\/script><script src='scripts/include-1.js'><\/script><script async src='scripts/include-2.js'><\/script>");
+ document.close();
+ window.setTimeout(function() {
+ window.t.step(function() {
+ window.assert_any(window.assert_array_equals, window.eventOrder,
+ [['inline script #1', 'external script #1', 'external script #2'],
+ ['inline script #1', 'external script #2', 'external script #1']]);
+ window.t.done();
+ })},
+ 1000);
+ };
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/103.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/103.html
new file mode 100644
index 0000000000..f619472a4f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/103.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing defer attribute at runtime</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="defer-script" defer src="scripts/include-2.js"></script>
+ <script src="scripts/include-1.js"></script>
+
+ <script>
+ var t = async_test();
+
+ t.step(function() {
+ document.getElementById("defer-script").removeAttribute("defer");
+ });
+
+ var ran_defer_check = false;
+
+ document.addEventListener("readystatechange", t.step_func(function () {
+ if (document.readyState == "interactive") {
+ ran_defer_check = true;
+ assert_array_equals(eventOrder, ["external script #1"]);
+ }
+ }), false);
+
+ addEventListener("load", t.step_func(function () {
+ assert_true(ran_defer_check);
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/104.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/104.html
new file mode 100644
index 0000000000..95a5a22237
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/104.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding defer attribute at runtime</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="defer-script" src="scripts/include-1.js"></script>
+ <script src="scripts/include-2.js"></script>
+
+ <script>
+ var t = async_test();
+
+ t.step(function() {
+ document.getElementById("defer-script").setAttribute("defer", "defer");
+ });
+
+ var ran_defer_check = false;
+
+ document.addEventListener("readystatechange", t.step_func(function () {
+ if (document.readyState == "interactive") {
+ ran_defer_check = true;
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ }
+ }), false);
+
+ addEventListener("load", t.step_func(function () {
+ assert_true(ran_defer_check);
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/105.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/105.html
new file mode 100644
index 0000000000..19be9e1d03
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/105.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: adding async attribute at runtime</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ var t = async_test();
+
+ var sources = ["scripts/include-1.js?pipe=trickle(d2)",
+ "scripts/include-2.js"]
+ var scripts = sources.map(function(x) {
+ var script = document.createElement("script");
+ script.src = x;
+ script.async = false;
+ document.body.appendChild(script);
+ return script;
+ });
+ scripts[0].async = true;
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-import.html
new file mode 100644
index 0000000000..451e218ef7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-import.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking defer scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script defer src="scripts/check-style-sheet.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-noimport.html
new file mode 100644
index 0000000000..704b880bcf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-defer-noimport.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking defer scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script defer src="scripts/check-style-sheet.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-import.html
new file mode 100644
index 0000000000..4fe526a274
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-import.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking external parser-blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script src="scripts/check-style-sheet.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-import.html
new file mode 100644
index 0000000000..ea873746e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-import.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking external module scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script src="scripts/check-style-sheet.js" type="module"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-noimport.html
new file mode 100644
index 0000000000..71c59fb4d6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-module-noimport.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking external module scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script src="scripts/check-style-sheet.js" type="module"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-noimport.html
new file mode 100644
index 0000000000..3694481b86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-external-noimport.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking external parser-blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script src="scripts/check-style-sheet.js"></script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import-xhtml.xhtml
new file mode 100644
index 0000000000..3b2e8b5296
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import-xhtml.xhtml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Stylesheet in XHTML HEAD with @import blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)" />
+</head>
+<body>
+ <div id="test">Test</div>
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import.html
new file mode 100644
index 0000000000..b8afeda135
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-import.html
new file mode 100644
index 0000000000..d3f02ffd19
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-import.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking module scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script type="module">
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-noimport.html
new file mode 100644
index 0000000000..83cd29f267
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-module-noimport.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking module scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script type="module">
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport-xhtml.xhtml
new file mode 100644
index 0000000000..1cae3c9965
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport-xhtml.xhtml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Stylesheet in XHTML HEAD blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)" />
+</head>
+<body>
+ <div id="test">Test</div>
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport.html
new file mode 100644
index 0000000000..bd8ec8633e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-import.html
new file mode 100644
index 0000000000..0b572b0724
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-import.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking scripts document.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <!-- this stylesheet blocks scripts -->
+ <script>
+ test(function() {
+ document.write("<link rel='stylesheet' href='css/import.css?pipe=trickle(d2)'>");
+ // note that the pass condition here is not per spec (but does match implementations) as of 2012-06-26
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "static");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-noimport.html
new file mode 100644
index 0000000000..ce57d1f1c5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-noimport.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: stylesheets blocking scripts document.write</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+
+ <!-- this stylesheet blocks scripts -->
+ <script>
+ test(function() {
+ document.write("<link rel='stylesheet' href='css/background.css?pipe=trickle(d2)'>");
+ // note that the pass condition here is not per spec (but does match implementations) as of 2012-06-26
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "static");
+ });
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/108.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/108.html
new file mode 100644
index 0000000000..79be9721d2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/108.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: javascript URL in iframe</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">Not tested</div>
+ <script>
+ var t = async_test();
+ var iframe_onload = false;
+
+ t.step(function() {
+ log('inline script #1');
+ document.write("<iframe src='javascript:void(top.log(&quot;iframe script #1&quot;));'></iframe>");
+ log('inline script #2')
+ })
+
+ onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "iframe script #1"]);
+ t.done();
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/109.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/109.html
new file mode 100644
index 0000000000..d103ffcbd7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/109.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: javascript URL in iframe, src set via DOM</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">Not tested</div>
+ <script>
+ var t = async_test();
+
+ t.step(function() {
+ var iframe_onload = false;
+ log("inline script #1");
+ var iframe = document.createElement("iframe");
+ iframe.src = "javascript:void(top.log('JS URL'));";
+ log("inline script #2");
+ iframe.onload = function () { log("iframe onload") };
+ document.body.appendChild(iframe);
+ log("inline script #3");
+ })
+
+ onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3", "JS URL", "iframe onload"]);
+ t.done();
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/110.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/110.html
new file mode 100644
index 0000000000..5affb9ed23
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/110.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing defer script at runtime</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="defer-script" defer src="scripts/include-2.js"></script>
+ <script src="scripts/include-1.js"></script>
+
+ <script>
+ var t = async_test();
+
+ t.step(function() {
+ var s = document.getElementById("defer-script");
+ s.parentNode.removeChild(s);
+ });
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/111.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/111.html
new file mode 100644
index 0000000000..c932a7b95c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/111.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing async attribute at runtime</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="async-script" async src="scripts/include-2.js?pipe=trickle(d3)"></script>
+
+ <script>
+ var t = async_test();
+
+ t.step(function() {
+ document.getElementById("async-script").removeAttribute("async");
+ var s = document.createElement("script");
+ s.async = false;
+ s.src = "scripts/include-1.js";
+ document.body.appendChild(s);
+ });
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/112.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/112.html
new file mode 100644
index 0000000000..a0cc647e0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/112.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: removing async attribute at runtime, script also has defer attribute</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="async-script" async defer src="scripts/include-1.js?pipe=trickle(d3)"></script>
+
+ <script>
+ var t = async_test();
+ document.getElementById("async-script").removeAttribute("async");
+
+ addEventListener("DOMContentLoaded", t.step_func(function () {
+ assert_array_equals(eventOrder, []);
+ }), false);
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1"]);
+ t.done();
+ }), false);
+
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/113.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/113.html
new file mode 100644
index 0000000000..32740be37e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/113.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: Altering DOM using innerHTML during parse </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script>
+ var t = async_test();
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2"]);
+ t.done();
+ }), false);
+
+ </script>
+ <div id="container">
+ <script>t.step(function() {
+ log("inline script #1");
+ document.getElementById("container").innerHTML = "";
+ });
+ </script>
+ <script>t.step(function() {log("inline script #2")});</script>
+ </div>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/114.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/114.html
new file mode 100644
index 0000000000..ce3733208b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/114.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: Changing src of defer script before it runs </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="defer-script" defer src="scripts/include-1.js"></script>
+
+ <script>
+ var t = async_test();
+
+ document.getElementById("defer-script").src = "scripts/include-2.js"
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1"]);
+ t.done();
+ }), false);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/115.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/115.html
new file mode 100644
index 0000000000..6234e02020
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/115.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title> scheduler: Removing src of defer script before it runs </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+
+ <div id="test"></div>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+
+ <script id="defer-script" defer src="scripts/include-1.js">t.step(function() {assert_unreached()})</script>
+
+ <script>
+ var t = async_test();
+
+ document.getElementById("defer-script").removeAttribute("src");
+
+ addEventListener("load", t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1"]);
+ t.done();
+ }), false);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/116.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/116.html
new file mode 100644
index 0000000000..62da398868
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/116.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: adding script to head of frameset document</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+ <script>
+ // add a script that looks for document.body as first child of HEAD
+ testlib.addScript('',{src:'scripts/find-body.js'},document.getElementsByTagName('head')[0], true );
+ var div = document.createElement("div");
+ div.id = "log";
+ var t = async_test();
+ function test() {
+ if(!(window.findBodyLoaded)) {
+ return setTimeout(t.step_func(test),200);
+ }
+ document.body.appendChild(div);
+ assert_array_equals(eventOrder, ['document.body: <FRAMESET>']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ </script>
+</head>
+<frameset>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/117.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/117.html
new file mode 100644
index 0000000000..46a9900c94
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/117.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: inline script created with createContextualFragment</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+ <div id="log"></div>
+ <script>
+ log('inline script #1');
+ var t = async_test();
+
+ t.step(function() {
+ var range = document.createRange();
+ var fragment = range.createContextualFragment("<script>log('fragment script #1')<\/script>");
+ document.body.appendChild(fragment.firstChild);
+ });
+
+ function test() {
+ assert_array_equals(eventOrder, ['inline script #1', 'fragment script #1', 'end inline script #1']);
+ t.done();
+ }
+ onload = t.step_func(test)
+ log('end inline script #1');
+ </script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/118.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/118.html
new file mode 100644
index 0000000000..e002ea9601
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/118.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external script created with createContextualFragment</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+ <div id="log"></div>
+ <script>
+ log('inline script #1');
+ var t = async_test();
+
+ t.step(function() {
+ var range = document.createRange();
+ var fragment = range.createContextualFragment("<script src='scripts/include-1.js'><\/script>");
+ document.body.appendChild(fragment.firstChild);
+ });
+
+ addEventListener("load", t.step_func(function() {
+ assert_array_equals(eventOrder, ['inline script #1', 'end inline script #1', 'external script #1']);
+ t.done();
+ }), false);
+
+ log('end inline script #1');
+ </script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/119.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/119.html
new file mode 100644
index 0000000000..d1ed823093
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/119.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external defer script created with createContextualFragment</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <script>
+ log('inline script #1');
+ var t = async_test();
+
+ t.step(function () {
+ var range = document.createRange();
+ var fragment = range.createContextualFragment("<script defer src='scripts/include-1.js?pipe=trickle(d1)'><\/script>");
+ document.body.appendChild(fragment.firstChild);
+ });
+
+ addEventListener("DOMContentLoaded", t.step_func(function () {
+ assert_array_equals(eventOrder, ['inline script #1', 'end inline script #1']);
+ }));
+
+ addEventListener("load", t.step_func_done(function () {
+ assert_array_equals(eventOrder, ['inline script #1', 'end inline script #1', 'external script #1']);
+ }));
+
+ log('end inline script #1');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/120.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/120.html
new file mode 100644
index 0000000000..2cfe5221dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/120.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: script created without a window </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+
+ var doc = document.implementation.createHTMLDocument("");
+ doc.write("<script>t.step(function() {assert_unreached()})<\/script>");
+
+ document.body.appendChild(doc.head.firstChild);
+
+ onload = function() {t.done()}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/121.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/121.html
new file mode 100644
index 0000000000..d6de27025f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/121.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain">t.step(function() {assert_unreached()}</script>
+<script>
+t.step(function() {
+ document.getElementById("test").removeAttribute("type");
+ setTimeout(t.step_func(function() {t.done()}), 100);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/122.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/122.html
new file mode 100644
index 0000000000..a8994c6aeb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/122.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute and adding/removing external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain" src="scripts/include-1.js?pipe=trickle(d1)"></script>
+<script>
+t.step(function() {
+ var script = document.getElementById("test");
+ script.removeAttribute("type");
+ var marker = document.createElement("script");
+ marker.src = "scripts/include-2.js?pipe=trickle(d2)";
+ marker.async = false;
+ script.parentNode.appendChild(marker);
+ script.parentNode.appendChild(script);
+ test(function() {assert_true(script.async)}, "Reinserted script async IDL attribute");
+});
+onload = t.step_func(function () {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/123.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/123.html
new file mode 100644
index 0000000000..dc145eb550
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/123.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute and adding/removing external script with async=false </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain" src="scripts/include-2.js?pipe=trickle(d1)"></script>
+<script>
+t.step(function() {
+ var script = document.getElementById("test");
+ script.removeAttribute("type");
+ script.async = false;
+ var marker = document.createElement("script");
+ marker.src = "scripts/include-1.js?pipe=trickle(d2)";
+ marker.async = false;
+ script.parentNode.appendChild(marker);
+ script.parentNode.appendChild(script);
+});
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/124.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/124.html
new file mode 100644
index 0000000000..5c7208dfde
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/124.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute and changing script data inline script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain">t.step(function() {log("inline script #1")});</script>
+<script>
+t.step(function() {
+ log("inline script #2");
+ var script = document.getElementById("test");
+ script.removeAttribute("type");
+ script.appendChild(document.createTextNode(""));
+ log("end inline script #2");
+});
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #2", "inline script #1", "end inline script #2"]);
+ t.done();
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/125.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/125.html
new file mode 100644
index 0000000000..5074f2a107
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/125.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute and changing script data external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain" src="scripts/include-1.js?pipe=trickle(d1)"></script>
+<script>
+t.step(function() {
+ var script = document.getElementById("test");
+ script.removeAttribute("type");
+ var marker = document.createElement("script");
+ marker.src = "scripts/include-2.js?pipe=trickle(d2)";
+ marker.async = false;
+ script.parentNode.appendChild(marker);
+ script.appendChild(document.createTextNode(""));
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/126.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/126.html
new file mode 100644
index 0000000000..1b2bb17634
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/126.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: altering the type attribute and changing script data external script async=false </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test" type="text/plain" src="scripts/include-2.js"></script>
+<script>
+t.step(function() {
+ var script = document.getElementById("test");
+ script.removeAttribute("type");
+ script.async = false;
+ var marker = document.createElement("script");
+ marker.src = "scripts/include-1.js?pipe=trickle(d2)";
+ marker.async = false;
+ script.parentNode.appendChild(marker);
+ script.appendChild(document.createTextNode(""));
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/127.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/127.html
new file mode 100644
index 0000000000..149078a327
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/127.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: appending non-text children to script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test"></script>
+<script>
+t.step(function() {
+ log("inline script #1");
+ var script = document.getElementById("test");
+
+ var frag = document.createDocumentFragment();
+ var div = document.createElement("div");
+
+ div.textContent = "assert_unreached();"
+ frag.appendChild(document.createTextNode("t.step(function() {log('inline script #2');\n"));
+ frag.appendChild(div);
+ frag.appendChild(document.createTextNode("log('end inline script #2');})"));
+
+ script.appendChild(frag);
+ log("end inline script #1");
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "end inline script #2", "end inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/128.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/128.html
new file mode 100644
index 0000000000..39ec24f681
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/128.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: appending script element to script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test"></script>
+<script>
+t.step(function() {
+ log("inline script #1");
+ var script = document.getElementById("test");
+
+ var frag = document.createDocumentFragment();
+ var inner_script = document.createElement("script");
+
+ inner_script.textContent = "t.step(function() {log('inline script #3');});"
+ frag.appendChild(document.createTextNode("t.step(function() {log('inline script #2');\n"));
+ frag.appendChild(inner_script);
+ frag.appendChild(document.createTextNode("log('end inline script #2');})"));
+
+ script.appendChild(frag);
+ log("end inline script #1");
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #3", "inline script #2", "end inline script #2", "end inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/129.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/129.html
new file mode 100644
index 0000000000..8c12735677
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/129.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: appending multiple script elements</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<div id="container"></div>
+<script>
+t.step(function() {
+ log("inline script #1");
+
+ var frag = document.createDocumentFragment();
+
+ scripts = ["2", "3", "4"].map(function(x) {
+ var s = document.createElement("script");
+ s.textContent = "t.step(function() {log('inline script #" + x + "')});";
+ return s
+ });
+
+
+ frag.appendChild(scripts[0]);
+ var div = document.createElement(div);
+ div.appendChild(scripts[1]);
+ frag.appendChild(div);
+ frag.appendChild(scripts[2]);
+
+ document.getElementById("container").appendChild(frag);
+ log("end inline script #1");
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3", "inline script #4", "end inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/130.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/130.html
new file mode 100644
index 0000000000..c6643d9fdf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/130.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: appending external script element to script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<script id="test"></script>
+<script>
+t.step(function() {
+ log("inline script #1");
+ var script = document.getElementById("test");
+
+ var frag = document.createDocumentFragment();
+ var inner_script = document.createElement("script");
+
+ inner_script.src = "scripts/include-1.js?pipe=trickle(d1)";
+ frag.appendChild(document.createTextNode("t.step(function() {log('inline script #2');\n"));
+ frag.appendChild(inner_script);
+ frag.appendChild(document.createTextNode("log('end inline script #2');})"));
+
+ script.appendChild(frag);
+ log("end inline script #1");
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "end inline script #2", "end inline script #1", "external script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/131.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/131.html
new file mode 100644
index 0000000000..541483ed6b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/131.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: inline svg script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ log("inline script #1")
+</script>
+<svg>
+<script>log("inline script #2")</script>
+</svg>
+<script>
+log("inline script #3");
+t.step(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/132.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/132.html
new file mode 100644
index 0000000000..3edb959594
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/132.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external svg script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ log("inline script #1")
+</script>
+<svg>
+<script xlink:href="scripts/include-1.js"></script>
+</svg>
+<script>
+log("inline script #2");
+t.step(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "external script #1", "inline script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/133.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/133.html
new file mode 100644
index 0000000000..e6b327f709
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/133.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: inline HTML script added by SVG script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ log("inline script #1")
+</script>
+<svg>
+<script>
+log("inline script #2")
+var s = document.createElement("script");
+s.textContent = "log('inline script #3');";
+document.getElementsByTagName("svg")[0].appendChild(s);
+log("end inline script #2");
+</script>
+</svg>
+<script>
+log("inline script #4");
+t.step(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3",
+ "end inline script #2", "inline script #4"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/134.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/134.html
new file mode 100644
index 0000000000..bb2ad4f66b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/134.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external HTML script added by SVG script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ log("inline script #1")
+</script>
+<svg>
+<script>
+log("inline script #2")
+var s = document.createElement("script");
+s.src = "scripts/include-1.js"
+document.getElementsByTagName("svg")[0].appendChild(s);
+log("end inline script #2");
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2",
+ "end inline script #2", "external script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/135.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/135.html
new file mode 100644
index 0000000000..dd8b895218
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/135.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: external SVG script added by SVG script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ log("inline script #1")
+</script>
+<svg>
+<script>
+log("inline script #2")
+var s = document.createElementNS("http://www.w3.org/2000/svg", "script");
+s.setAttributeNS("http://www.w3.org/1999/xlink", "href", "scripts/include-1.js");
+document.getElementsByTagName("svg")[0].appendChild(s);
+log("end inline script #2");
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2",
+ "end inline script #2", "external script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/136.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/136.html
new file mode 100644
index 0000000000..b08a8b9798
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/136.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: DOM added external SVG script, force-async? </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+
+var s1 = document.createElement("script");
+s1.src = "scripts/include-1.js";
+s1.async = false;
+
+var s = document.createElementNS("http://www.w3.org/2000/svg", "script");
+s.setAttributeNS("http://www.w3.org/1999/xlink", "href", "scripts/include-2.js?pipe=trickle(d2)");
+
+document.getElementsByTagName("svg")[0].appendChild(s);
+document.getElementsByTagName("svg")[0].appendChild(s1);
+
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ <!-- assumes that the SVg script should be async -->
+ assert_array_equals(eventOrder, ["external script #1", "external script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/137.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/137.html
new file mode 100644
index 0000000000..35a49b806d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/137.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script empty xlink:href</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script xlink:href="">
+t.step(function() {assert_unreached()});
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/138.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/138.html
new file mode 100644
index 0000000000..0ff25471e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/138.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script nested inlines</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+t.step(function() {
+log("inline script #2");
+var a = {
+ <script>
+ t.step(function() {log("inline script #1")})
+ </script>
+a:1}
+log("end inline script #2");
+});
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "end inline script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/139.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/139.html
new file mode 100644
index 0000000000..7bb703d8a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/139.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script nested external in inline</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+t.step(function() {
+log("inline script #1");
+var a = {
+ <script xlink:href="scripts/include-1.js">
+ t.step(function() {assert_unreached()})
+ </script>
+a:1}
+log("end inline script #1");
+});
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["external script #1", "inline script #1", "end inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/140.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/140.html
new file mode 100644
index 0000000000..9b54d09d58
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/140.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script nested inline in external</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script xlink:href="scripts/include-1.js">
+ <script>
+ t.step(function() {log("inline script #1")});
+ </script>
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "external script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/141.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/141.html
new file mode 100644
index 0000000000..54aa3f3686
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/141.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG inline script that document.writes inline script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+ t.step(function() {
+ log('inline script #1');
+ document.write("<" + "script>t.step(function() {log('inline script #2')})<" + "/script>");
+ log('end inline script #1');
+ });
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "end inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/142.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/142.html
new file mode 100644
index 0000000000..d314eddb90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/142.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG inline script that document.writes external script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+ t.step(function() {
+ log('inline script #1');
+ document.write("<" + "script xlink:href='scripts/include-1.js'><" + "/script>");
+ log('end inline script #1');
+ });
+</script>
+<script>t.step(function() {log("inline script #2")});</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "end inline script #1", "external script #1", "inline script #2"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/143.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/143.html
new file mode 100644
index 0000000000..a0d9012f68
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/143.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG nested inline script that document.writes inline script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script>
+ t.step(function() {
+ log('inline script #3');
+ });
+ <script>
+ log("inline script #1")
+ document.write("<" + "script>t.step(function() {log('inline script #2')})<" + "/script><" + "/script>");
+ </script>
+ t.step(function() {
+ assert_unreached():
+ });
+</script>
+</svg>
+<script>
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/144.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/144.html
new file mode 100644
index 0000000000..3962c4d692
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/144.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG inline script changing the type attribute </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script type="text/plain">
+t.step(function() {assert_unreached()});
+</script>
+</svg>
+<script>
+t.step(function() {
+ var s = document.querySelector("svg > script");
+ s.textContent = "t.step(function() {log('inline script #1')})";
+ s.type = "";
+ s.parentNode.appendChild(s);
+});
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/145.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/145.html
new file mode 100644
index 0000000000..9e2d73bafc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/145.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG inline script adding text to empty script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>
+ var t = async_test();
+</script>
+<svg>
+<script></script>
+</svg>
+<script>
+t.step(function() {
+ var s = document.querySelector("svg > script");
+ s.textContent = "t.step(function() {log('inline script #1')})";
+});
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146-href.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146-href.html
new file mode 100644
index 0000000000..6c0869db54
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146-href.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script adding src attribute </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>var t = async_test();</script>
+<svg>
+<script></script>
+</svg>
+<script>
+t.step(function() {
+ var s = document.querySelector("svg > script");
+ s.setAttribute("href", "scripts/include-1.js");
+});
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["external script #1"]);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146.html
new file mode 100644
index 0000000000..333ac3fa0f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/146.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: SVG script adding src attribute </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<div id="log"></div>
+<script>var t = async_test();</script>
+<svg>
+<script></script>
+</svg>
+<script>
+t.step(function() {
+ var s = document.querySelector("svg > script");
+ s.src = "scripts/include-1.js";
+});
+onload = t.step_func(function() {
+ // SVG <script> element uses href attribute, so src attribute is ignored.
+ assert_array_equals(eventOrder, []);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/147.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/147.html
new file mode 100644
index 0000000000..07dc4d97c9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/147.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: insert multiple inline scripts; first script moves subsequent scripts </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+var t = async_test();
+</script>
+<div id="container"></div>
+<script>
+t.step(function() {
+ log("inline script #1");
+ var container = document.getElementById("container");
+
+ var frag = document.createDocumentFragment();
+ var frag_script_1 = document.createElement("script");
+ var frag_script_2 = document.createElement("script");
+ frag_script_2.id = "movee";
+ var frag_script_3 = document.createElement("script");
+
+ frag_script_1.textContent = "t.step(function() {log('inline script #2'); var s = document.getElementById('movee'); s.parentNode.appendChild(s)});";
+ frag_script_2.textContent = "t.step(function() {log('inline script #3');})";
+ frag_script_3.textContent = "t.step(function() {log('inline script #4');})";
+
+ [frag_script_1, frag_script_2, frag_script_3].forEach(function(x) {frag.appendChild(x)});
+
+ container.appendChild(frag);
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3", "inline script #4"]);
+ t.done();
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/148.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/148.html
new file mode 100644
index 0000000000..e2da8e8f0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/148.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: insert multiple inline scripts; first script deletes subsequent script </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+var t = async_test();
+</script>
+<div id="container"></div>
+<script>
+t.step(function() {
+ log("inline script #1");
+ var container = document.getElementById("container");
+
+ var frag = document.createDocumentFragment();
+ var frag_script_1 = document.createElement("script");
+ var frag_script_2 = document.createElement("script");
+ frag_script_2.id = "delete";
+ var frag_script_3 = document.createElement("script");
+
+ frag_script_1.textContent = "t.step(function() {log('inline script #2'); var s = document.getElementById('delete'); s.parentNode.removeChild(s)});";
+ frag_script_2.textContent = "t.step(function() {log('inline script #3');})";
+ frag_script_3.textContent = "t.step(function() {log('inline script #4');})";
+
+ [frag_script_1, frag_script_2, frag_script_3].forEach(function(x) {frag.appendChild(x)});
+
+ container.appendChild(frag);
+});
+
+onload = t.step_func(function() {
+ assert_array_equals(eventOrder, ["inline script #1", "inline script #2", "inline script #3", "inline script #4"]);
+ t.done();
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/149.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/149.html
new file mode 100644
index 0000000000..40594d8048
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/149.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html><head>
+ <title>scheduler: event/for attribute on script</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+attributes = [
+ {for:"window", event:"onload()", expect:true},
+ {for:"window", event:"onload", expect:true},
+ {for:" WINdow\t\n", event:"ONload\t\n", expect:true},
+ {for:"window", event:"load", expect:false},
+ {for:"window", event:"onpageshow", expect:false},
+ {for:"document", event:"onload", expect:false},
+]
+
+function test_maker(array_name) {
+ return function(x, i) {
+ var title = "for='" + x.for + "' event='" + x.event + "' " + array_name.replace("_", " ") + " " + (x.expect ? "executes immediately" : "does not execute");
+ script_content = "var d =" + array_name + "[" + i + "];"
+ script_content += x.expect?"d[1].step(function() {d[3] = true});":"d[1].step(function() {assert_unreached()});"
+ return [x, async_test(title), script_content, false];
+ }
+}
+
+parser_inserted = attributes.map(test_maker("parser_inserted"));
+dom_inserted = attributes.map(test_maker("dom_inserted"));
+
+parser_inserted.forEach(function(x) {
+ var d = x[0];
+ document.write("<script for='" + d.for + "' event='" + d.event + "'>" + x[2] + "<\/script>");
+});
+
+dom_inserted.forEach(function(x) {
+ var d = x[0];
+ var s = document.createElement("script");
+ s.setAttribute("event", d.event);
+ s.setAttribute("for", d.for);
+ s.textContent = x[2];
+ document.body.appendChild(s);
+});
+</script>
+
+<script>
+var all_tests = parser_inserted.concat(dom_inserted);
+
+all_tests.filter(function(x) {return x[0]["expect"]}).forEach(function(x) {var t = x[1]; t.step(function() {assert_true(x[3])});})
+
+onload = function() {
+ all_tests.forEach(function(x) {var t = x[1]; t.step(function() {t.done()})});
+}
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import-xhtml.xhtml
new file mode 100644
index 0000000000..d6144795db
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import-xhtml.xhtml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Stylesheet in XHTML BODY with @import blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="log">FAILED (This TC requires JavaScript enabled)</div>
+ <div id="test">Test</div>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)" />
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import.html
new file mode 100644
index 0000000000..40223ed104
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-import.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Stylesheet in BODY with @import blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="test">Test</div>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/import.css?pipe=trickle(d2)">
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport-xhtml.xhtml
new file mode 100644
index 0000000000..fa587a2ddb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport-xhtml.xhtml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Stylesheet in XHTML BODY blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="test">Test</div>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)" />
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport.html
new file mode 100644
index 0000000000..b5829d4da5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/150-noimport.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Stylesheet in BODY blocking scripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="testlib/testlib.js"></script>
+</head>
+<body>
+ <div id="test">Test</div>
+ <!-- this stylesheet blocks scripts -->
+ <link rel="stylesheet" href="css/background.css?pipe=trickle(d2)">
+ <script>
+ test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/background.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/background.css
new file mode 100644
index 0000000000..86a155b811
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/background.css
@@ -0,0 +1 @@
+#test {position:fixed} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/import.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/import.css
new file mode 100644
index 0000000000..d1664c29a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/import.css
@@ -0,0 +1 @@
+@import url("background.css") \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/non-external-no-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/non-external-no-import.html
new file mode 100644
index 0000000000..50836e0d7b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/non-external-no-import.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Module scripts with no imports always execute asynchronously</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://github.com/whatwg/html/issues/3746">
+</head>
+<body>
+<script>
+async_test(t => {
+ window.results = [];
+ window.logExecution = msg => window.results.push(msg);
+
+ const script = document.createElement('script');
+ script.type = 'module';
+ script.textContent = "window.logExecution('module')";
+ document.body.append(script);
+ window.logExecution('classic');
+
+ window.onload = t.step_func_done(e => {
+ assert_array_equals(window.results, ['classic', 'module']);
+ });
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld-postMessage.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld-postMessage.html
new file mode 100644
index 0000000000..2ed8731ceb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld-postMessage.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html><head>
+ <title> TC component </title>
+</head>
+<body>
+
+ <p>This page should appear in popup or frame</p>
+
+ <script type="text/javascript">
+ var target = opener || top;
+ var id = location.search?' '+location.search.substring(1) : '';
+ target.log('frame/popup script'+id);
+ window.onload=function(){
+ target.log('load event inside frame/popup script'+id);
+ target.postMessage('msg evt frame/popup script'+id, '*');
+ }
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld.html
new file mode 100644
index 0000000000..271bc8f569
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/pages/helloworld.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html><head>
+ <title> TC component </title>
+</head>
+<body>
+
+ <p>This page should appear in popup or frame</p>
+
+ <script type="text/javascript">
+ var target = top || opener;
+ var id = location.search?' '+parseInt(location.search.substring(1)) : '';
+ target.log('frame/popup script'+id);
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/check-style-sheet.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/check-style-sheet.js
new file mode 100644
index 0000000000..cbab154f5a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/check-style-sheet.js
@@ -0,0 +1,4 @@
+test(function() {
+ assert_equals(getComputedStyle(document.getElementById("test")).position,
+ "fixed");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/count-script-tags.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/count-script-tags.js
new file mode 100644
index 0000000000..8fba4ecb3c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/count-script-tags.js
@@ -0,0 +1 @@
+log('script tags in DOM: '+document.getElementsByTagName('script').length); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-body.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-body.js
new file mode 100644
index 0000000000..1ce198f13e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-body.js
@@ -0,0 +1,4 @@
+log(
+ 'document.body: ' +
+ (document.body ? '<' + document.body.localName.toUpperCase() + '>' : null));
+var findBodyLoaded=true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-foo.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-foo.js
new file mode 100644
index 0000000000..52d0ec91cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-foo.js
@@ -0,0 +1,2 @@
+log('found #foo element: ' + ( document.getElementById('foo') ? 'YES' : 'NO' ));
+var findFooLoaded=true; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-1.js
new file mode 100644
index 0000000000..8ff291ad57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-1.js
@@ -0,0 +1 @@
+log('external script #1'); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-10.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-10.js
new file mode 100644
index 0000000000..8dc770ddc0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-10.js
@@ -0,0 +1 @@
+document.write("<script src='scripts/include-9.js?pipe=trickle(d2)' defer></script>");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-11.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-11.js
new file mode 100644
index 0000000000..016913c4b8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-11.js
@@ -0,0 +1,4 @@
+log("external script before adding iframe");
+var iframe = document.createElement("iframe");
+iframe.srcdoc = "<script>parent.log('script in iframe')</script>"
+document.body.appendChild(iframe);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-2.js
new file mode 100644
index 0000000000..31319423af
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-2.js
@@ -0,0 +1 @@
+log('external script #2'); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-3.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-3.js
new file mode 100644
index 0000000000..53352e0f83
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-3.js
@@ -0,0 +1,3 @@
+log('external script before doc write');
+document.write( '<script>log(\'document.write external script\');</script>');
+log('external script after doc write'); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-4.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-4.js
new file mode 100644
index 0000000000..0597a22624
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-4.js
@@ -0,0 +1,3 @@
+log('include-4 before doc write');
+document.write( '<script src="scripts/include-3.js"></script>');
+log('include-4 after doc write'); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-5.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-5.js
new file mode 100644
index 0000000000..52952d7379
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-5.js
@@ -0,0 +1,7 @@
+log('include-5 before removing scripts');
+var scripts=[].slice.call(document.getElementsByTagName('script'), 3);
+for(var i = 0; i < scripts.length; i++) {
+ var s = scripts[i];
+ s.parentNode.removeChild(s);
+}
+log('include-5 after removing scripts');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-6.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-6.js
new file mode 100644
index 0000000000..77da2af232
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-6.js
@@ -0,0 +1,6 @@
+top.log(
+ 'external script (#foo found? ' +
+ (document.getElementById('foo') ? 'YES' : 'NO' ) +
+ ')'
+);
+top.include6Loaded=true; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-7.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-7.js
new file mode 100644
index 0000000000..57c5508015
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-7.js
@@ -0,0 +1 @@
+log('external script #7'); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-8.js
new file mode 100644
index 0000000000..960f2129fe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-8.js
@@ -0,0 +1,4 @@
+log("external script #8");
+var s = document.createElement("script")
+s.src='scripts/include-9.js?pipe=trickle(d2)'
+document.body.appendChild(s);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-9.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-9.js
new file mode 100644
index 0000000000..9042882024
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-9.js
@@ -0,0 +1,2 @@
+log("external script #9");
+test(); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/testlib/testlib.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/testlib/testlib.js
new file mode 100644
index 0000000000..a6fd39426b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/testlib/testlib.js
@@ -0,0 +1,43 @@
+/*
+* Utility functions for script scheduler test
+*/
+(function(){ /* namespace hiding local variables like arOrderOfAllEvents from global scope */
+ window.testlib = {};
+ window.eventOrder = [];
+ var arNumberOfScriptsParsedPerEvent=[];
+ window.log = function (str){
+ eventOrder.push(str);
+ arNumberOfScriptsParsedPerEvent.push(document.getElementsByTagName('script').length);
+ }
+
+ window.testlib.addScript = function(source, attributes, parent, firstInParent,funcPrepare) {
+ try{
+ parent = parent||document.body;
+ var script = document.createElement('script');
+ if(funcPrepare) {
+ funcPrepare(script);
+ }
+ if(source)script.appendChild( document.createTextNode(source) );
+ for( var name in attributes){
+ if(/^on/i.test(name)) {
+ script[name] = attributes[name];
+ } else {
+ script.setAttribute(name, attributes[name]);
+ }
+ }
+ if (firstInParent && parent.firstChild) {
+ parent.insertBefore(script, parent.firstChild);
+ } else {
+ parent.appendChild(script);
+ }
+ } catch(e) {
+ log('ERROR when adding script to DOM!');
+ alert(e);
+ }
+ return script;
+ }
+
+ window.testlib.urlParam = function(relativeURL) {
+ return location.href.replace( /\d*\.html$/, relativeURL);
+ }
+})();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js
new file mode 100644
index 0000000000..eb442c97bc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js
@@ -0,0 +1,5 @@
+(function() {
+ window.getSomeString = function() {
+ return "śćążź"; //<- these are five Polish letters, similar to scazz. It can be read correctly only with windows 1250 encoding.
+ };
+})();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js
new file mode 100644
index 0000000000..50de6932ba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js
@@ -0,0 +1,5 @@
+(function() {
+ window.getSomeString = function() {
+ return "œæ¹¿Ÿ"; //<- these are five Polish letters, similar to scazz. It can be read correctly only with windows 1250 encoding.
+ };
+})();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html
new file mode 100644
index 0000000000..dc0fa9dabb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with a base URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<base href=../beta/>
+<div id=log></div>
+<script>
+function do_test(path) {
+ test(function() {
+ assert_equals(path, "beta");
+ });
+}
+</script>
+<script src=test.js></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js
new file mode 100644
index 0000000000..3cbbb12e2e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js
@@ -0,0 +1 @@
+do_test("alpha");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js
new file mode 100644
index 0000000000..4ce0f5338d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js
@@ -0,0 +1 @@
+do_test("beta");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html
new file mode 100644
index 0000000000..edc2c3d6f8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an empty URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<base href=unreachable.js>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ window.unreachable = this.unreached_func("Should not load unreachable.js");
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html
new file mode 100644
index 0000000000..d127f1eb3b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an empty URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+// For a better error message in case the UA tries to load "" (which resolves
+// to this document).
+setup({
+ "allow_uncaught_exception": true,
+});
+async_test(function(t) {
+ window.onerror = this.unreached_func("Should not get an error reported to " +
+ "the window before the script");
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html
new file mode 100644
index 0000000000..b49e51740f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an invalid URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "//[]");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js
new file mode 100644
index 0000000000..ca7fdba71f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js
@@ -0,0 +1 @@
+unreachable();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html
new file mode 100644
index 0000000000..1f1a91228c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>Historical script element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function t(property) {
+ test(function() {
+ assert_false(property in document.createElement('script'));
+ }, 'script.' + property + ' should not be supported');
+}
+// added in https://github.com/whatwg/html/commit/69f83cf2eacf4543860ccb7abab0ff5bb1e8b594
+// removed in https://github.com/whatwg/html/commit/1a0b5e8377d59462e05a5cffda4b8592324a2785
+t('onbeforescriptexecute');
+t('onafterscriptexecute');
+
+var t_onbeforescriptexecute_attr = async_test('onbeforescriptexecute content attribute should not be supported');
+var t_onafterscriptexecute_attr = async_test('onafterscriptexecute content attribute should not be supported');
+var t_beforescriptexecute_event = async_test(function() {
+ addEventListener('beforescriptexecute', this.step_func(function() {
+ assert_unreached();
+ }), true);
+}, 'beforescriptexecute event should not be supported');
+var t_afterscriptexecute_event = async_test(function() {
+ addEventListener('afterscriptexecute', this.step_func(function() {
+ assert_unreached();
+ }), true);
+}, 'afterscriptexecute event should not be supported');
+
+var a = false;
+
+onload = function() {
+ t_onbeforescriptexecute_attr.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_onafterscriptexecute_attr.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_beforescriptexecute_event.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_afterscriptexecute_event.step(function() {
+ assert_true(a);
+ this.done();
+ });
+};
+</script>
+<script onbeforescriptexecute="t_onbeforescriptexecute_attr.step(function() { assert_unreached(); });"
+ onafterscriptexecute="t_onafterscriptexecute_attr.step(function() { assert_unreached(); });">
+a = true;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any.js
new file mode 100644
index 0000000000..7efb2050b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any.js
@@ -0,0 +1,18 @@
+// META: global=window,dedicatedworker,sharedworker
+
+promise_test(async test => {
+ const result = await import("./export-hello.js", { assert: { } });
+ assert_equals(result.default, "hello");
+}, "Dynamic import with an empty assert clause should succeed");
+
+promise_test(async test => {
+ return promise_rejects_js(test, TypeError,
+ import("./export-hello.js", { assert: { unsupportedAssertionKey: "unsupportedAssertionValue"} }),
+ "Dynamic import with an unsupported import assertion should fail");
+}, "Dynamic import with an unsupported import assertion should fail");
+
+promise_test(test => {
+ return promise_rejects_js(test, TypeError,
+ import("./export-hello.js", { assert: { type: "notARealType"} } ),
+ "Dynamic import with an unsupported type assertion should fail");
+}, "Dynamic import with an unsupported type assertion should fail");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.html
new file mode 100644
index 0000000000..3a7c371189
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Handling of empty import assertion clause</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that no error occurs when an empty import assertion clause is provided.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(window.log, ["hello", "empty-assertion-clause"]);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./empty-assertion-clause.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.js
new file mode 100644
index 0000000000..6913dd61df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-assertion-clause.js
@@ -0,0 +1,2 @@
+import "./hello.js" assert { };
+log.push("empty-assertion-clause");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-type-assertion.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-type-assertion.js
new file mode 100644
index 0000000000..5bb9b1ddb8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/empty-type-assertion.js
@@ -0,0 +1,2 @@
+import "./hello.js#2" assert { type: "" };
+log.push("empty-type-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/export-hello.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/export-hello.js
new file mode 100644
index 0000000000..34b58e6e12
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/export-hello.js
@@ -0,0 +1 @@
+export default "hello";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/hello.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/hello.js
new file mode 100644
index 0000000000..2f34844460
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/hello.js
@@ -0,0 +1 @@
+log.push("hello"); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-import-errors-order.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-import-errors-order.html
new file mode 100644
index 0000000000..17c95faea0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-import-errors-order.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Handling of invalid module type import attributes</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ var log = [];
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that the errors order for invalid import declarations is" +
+ " specifier, then attribute key, and then type attribute value.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 3);
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1].constructor, SyntaxError);
+ assert_equals(log[2].constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before invalid specifier
+ import "INVALID" assert { unknown: "foo" };
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before unknown type
+ import "./valid" assert { unknown: "foo", type: "unknown" };
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before invalid specifier in subsequent import
+ import "./valid" assert { unknown: "foo" };
+ import "INVALID";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion-error.html
new file mode 100644
index 0000000000..0adcc47569
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion-error.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Handling of invalid module type import assertions</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that invalid module type assertion leads to TypeError on window.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4);
+ assert_equals(log[0].constructor, TypeError);
+ assert_equals(log[1].constructor, TypeError);
+ assert_equals(log[2].constructor, TypeError);
+ assert_equals(log[3].constructor, TypeError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./invalid-type-assertion.js" onerror="unreachable()"></script>
+<script type="module" src="./empty-type-assertion.js" onerror="unreachable()"></script>
+<script type="module" src="./js-type-assertion.js" onerror="unreachable()"></script>
+<script type="module" src="./javascript-type-assertion.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion.js
new file mode 100644
index 0000000000..e28c0176d5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/invalid-type-assertion.js
@@ -0,0 +1,2 @@
+import "./hello.js#1" assert { type: "notARealType" };
+log.push("invalid-type-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/javascript-type-assertion.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/javascript-type-assertion.js
new file mode 100644
index 0000000000..cc0f531026
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/javascript-type-assertion.js
@@ -0,0 +1,2 @@
+import "./hello.js#4" assert { type: "javascript" };
+log.push("javascript-type-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/js-type-assertion.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/js-type-assertion.js
new file mode 100644
index 0000000000..c649c95ffe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/js-type-assertion.js
@@ -0,0 +1,2 @@
+import "./hello.js#3" assert { type: "js" };
+log.push("js-type-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.html
new file mode 100644
index 0000000000..72977347a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Handling of unsupported assertion</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that invalid module assertion leads to SyntaxError on window.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 1);
+ assert_equals(log[0].constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./unsupported-assertion.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.js
new file mode 100644
index 0000000000..45f6d60c9d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-assertions/unsupported-assertion.js
@@ -0,0 +1,2 @@
+import "./hello.js" assert { unsupportedAssertionKey: "unsupportedAssertionValue" };
+log.push("unsupported-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/dynamic-import-with-attributes-argument.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/dynamic-import-with-attributes-argument.any.js
new file mode 100644
index 0000000000..2addb0fcb9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/dynamic-import-with-attributes-argument.any.js
@@ -0,0 +1,18 @@
+// META: global=window,dedicatedworker,sharedworker
+
+promise_test(async test => {
+ const result = await import("./export-hello.js", { with: { } });
+ assert_equals(result.default, "hello");
+}, "Dynamic import with an empty with clause should succeed");
+
+promise_test(async test => {
+ return promise_rejects_js(test, TypeError,
+ import("./export-hello.js", { with: { unsupportedAssertionKey: "unsupportedAssertionValue"} }),
+ "Dynamic import with an unsupported import attribute should fail");
+}, "Dynamic import with an unsupported import attribute should fail");
+
+promise_test(test => {
+ return promise_rejects_js(test, TypeError,
+ import("./export-hello.js", { with: { type: "notARealType"} } ),
+ "Dynamic import with an unsupported type attribute should fail");
+}, "Dynamic import with an unsupported type attribute should fail");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.html
new file mode 100644
index 0000000000..0a8868b2f4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Handling of empty import attributes clause</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that no error occurs when an empty import attributes clause is provided.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(window.log, ["hello", "empty-attributes-clause"]);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./empty-attributes-clause.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.js
new file mode 100644
index 0000000000..98c4573179
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-attributes-clause.js
@@ -0,0 +1,2 @@
+import "./hello.js" with { };
+log.push("empty-attributes-clause");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-type-attribute.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-type-attribute.js
new file mode 100644
index 0000000000..72272b5102
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/empty-type-attribute.js
@@ -0,0 +1,2 @@
+import "./hello.js#2" with { type: "" };
+log.push("empty-type-assertion");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/export-hello.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/export-hello.js
new file mode 100644
index 0000000000..34b58e6e12
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/export-hello.js
@@ -0,0 +1 @@
+export default "hello";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/hello.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/hello.js
new file mode 100644
index 0000000000..2f34844460
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/hello.js
@@ -0,0 +1 @@
+log.push("hello"); \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-import-errors-order.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-import-errors-order.html
new file mode 100644
index 0000000000..8c438f626b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-import-errors-order.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Handling of invalid module type import attributes</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ var log = [];
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that the errors order for invalid import declarations is" +
+ " specifier, then attribute key, and then type attribute value.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 3);
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1].constructor, SyntaxError);
+ assert_equals(log[2].constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before invalid specifier
+ import "INVALID" with { unknown: "foo" };
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before unknown type
+ import "./valid" with { unknown: "foo", type: "unknown" };
+</script>
+<script type="module" onerror="unreachable()">
+ // unknown attribute is reported before invalid specifier in subsequent import
+ import "./valid" with { unknown: "foo" };
+ import "INVALID";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute-error.html
new file mode 100644
index 0000000000..ac6d61a642
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute-error.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Handling of invalid module type import attributes</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that invalid module type attribute leads to TypeError on window.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4);
+ assert_equals(log[0].constructor, TypeError);
+ assert_equals(log[1].constructor, TypeError);
+ assert_equals(log[2].constructor, TypeError);
+ assert_equals(log[3].constructor, TypeError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./invalid-type-attribute.js" onerror="unreachable()"></script>
+<script type="module" src="./empty-type-attribute.js" onerror="unreachable()"></script>
+<script type="module" src="./js-type-attribute.js" onerror="unreachable()"></script>
+<script type="module" src="./javascript-type-attribute.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute.js
new file mode 100644
index 0000000000..10e35b6b56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-attribute.js
@@ -0,0 +1,2 @@
+import "./hello.js#1" with { type: "notARealType" };
+log.push("invalid-type-attribute");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/javascript-type-attribute.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/javascript-type-attribute.js
new file mode 100644
index 0000000000..568db18196
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/javascript-type-attribute.js
@@ -0,0 +1,2 @@
+import "./hello.js#4" with { type: "javascript" };
+log.push("javascript-type-attribute");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/js-type-attribute.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/js-type-attribute.js
new file mode 100644
index 0000000000..b7a454b4f2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/js-type-attribute.js
@@ -0,0 +1,2 @@
+import "./hello.js#3" with { type: "js" };
+log.push("js-type-attribute");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.html
new file mode 100644
index 0000000000..3656e465ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Handling of unsupported attribute</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that invalid module attribute leads to SyntaxError on window.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 1);
+ assert_equals(log[0].constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./unsupported-attribute.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.js
new file mode 100644
index 0000000000..2fc6829cfb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.js
@@ -0,0 +1,2 @@
+import "./hello.js" with { unsupportedAttributeKey: "unsupportedAttributeValue" };
+log.push("unsupported-attribute");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs
new file mode 100644
index 0000000000..b533fc2e90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-module-goal.mjs
@@ -0,0 +1 @@
+import "./serve-with-content-type.py?fn=is-module-goal.mjs&ct=text%2Fjavascript%3Bgoal=module"; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-script-goal.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-script-goal.js
new file mode 100644
index 0000000000..069363dd40
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/is-script-goal.js
@@ -0,0 +1,3 @@
+with ({}) {
+ ;
+}; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/array.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/array.json
new file mode 100644
index 0000000000..e77e32d338
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/array.json
@@ -0,0 +1 @@
+["en", "try"]
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16be.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16be.json
new file mode 100644
index 0000000000..d22a45a591
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16be.json
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16le.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16le.json
new file mode 100644
index 0000000000..4d1aa264a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-16le.json
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-8.json
new file mode 100644
index 0000000000..07ba933e86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/bom-utf-8.json
@@ -0,0 +1 @@
+{ "data": "hello" } \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-2.html
new file mode 100644
index 0000000000..686178bfe1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="windows-1250">
+<title>JSON modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/utf-8.json" assert { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 even though document's encoding is windows-1250");
+</script>
+<script type="module">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/windows-1250.json&ct=text/json%3Bcharset=windows-1250" assert { type: "json"};
+ test(() => {
+ assert_not_equals(json.data, "śćążź",
+ 'Should be decoded as UTF-8');
+ }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-bom.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-bom.any.js
new file mode 100644
index 0000000000..d2dbe3e468
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset-bom.any.js
@@ -0,0 +1,17 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=/common/utils.js
+
+promise_test(async () => {
+ const jsonModule = await import('./bom-utf-8.json', { assert: { type: 'json' } });
+ assert_equals(jsonModule.default.data, 'hello');
+}, 'UTF-8 BOM should be stripped when decoding JSON module script');
+
+promise_test(async test => {
+ await promise_rejects_js(test, SyntaxError,
+ import('./bom-utf-16be.json', { assert: { type: 'json' } }), 'Expected parse error from UTF-16BE BOM');
+}, 'UTF-16BE BOM should result in parse error in JSON module script');
+
+promise_test(async test => {
+ await promise_rejects_js(test, SyntaxError,
+ import('./bom-utf-16le.json', { assert: { type: 'json' } }), 'Expected parse error from UTF-16LE BOM');
+}, 'UTF-16LE BOM should result in parse error in JSON module script');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset.html
new file mode 100644
index 0000000000..7c74b9bf6c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/charset.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/utf-8.json&ct=text/json%3Bcharset=utf-8" assert { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=utf8 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/utf-8.json&ct=text/json%3Bcharset=shift-jis" assert { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=shift-jis is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/utf-8.json&ct=text/json%3Bcharset=windows-1252" assert { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=windows-1252 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/utf-8.json&ct=text/json%3Bcharset=utf-7" assert { type: "json"};;
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=utf-7 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module-assertions/windows-1250.json&ct=text/json%3Bcharset=windows-1250" assert { type: "json"};
+ test(() => {
+ assert_not_equals(json.data, "śćążź",
+ 'Should be decoded as UTF-8');
+ }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cors-crossorigin-requests.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cors-crossorigin-requests.html
new file mode 100644
index 0000000000..757af2901c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cors-crossorigin-requests.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+ <title>json-module-assertions-crossorigin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>json-module-assertions-crossorigin</h1>
+ <iframe id="import-WithCORS" src="crossorigin-import-with-cors.sub.html"></iframe>
+ <iframe id="import-NoCORS" src="crossorigin-import-without-cors.sub.html"></iframe>
+ <iframe id="import-parseerror-WithCors" src="crossorigin-import-parse-error-with-cors.sub.html"></iframe>
+ <script>
+
+ var tests = [
+ { "obj": async_test("Imported JSON module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported JSON: 42" },
+ { "obj": async_test("Imported JSON module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+ { "obj": async_test("Imported JSON module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "0-0" },
+ ];
+
+ window.addEventListener("load", function () {
+ tests.forEach(function (test) {
+ var target = document.getElementById(test.id);
+ test.obj.step(function () {
+ assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+ });
+ test.obj.done();
+ });
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials-iframe.sub.html
new file mode 100644
index 0000000000..44e6402faa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials-iframe.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module">
+ import json from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+ window.sameOriginNoneDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="anonymous">
+ import json from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+ window.sameOriginAnonymousDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import json from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+ window.sameOriginUseCredentialsDescendant = json.requestHadCookies;
+</script>
+<script type="module">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+ window.crossOriginNoneDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="anonymous">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+ window.crossOriginAnonymousDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="use-credentials">
+import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "json" };
+window.crossOriginUseCredentialsDescendant = json.requestHadCookies;
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+ window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials.sub.html
new file mode 100644
index 0000000000..d11d2f9589
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/credentials.sub.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'milk=1';
+
+const setCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/json-module-assertions/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+
+const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+});
+
+promise_test(t => {
+ const iframe = document.createElement('iframe');
+
+ return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+ const messagePromise = new Promise(resolve => {
+ window.addEventListener('message', event => {
+ resolve();
+ });
+ });
+
+ iframe.src = 'credentials-iframe.sub.html';
+ document.body.appendChild(iframe);
+
+ return messagePromise;
+ }).then(() => {
+ const w = iframe.contentWindow;
+
+ assert_equals(w.sameOriginNoneDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymousDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentialsDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNoneDescendant, false,
+ 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymousDescendant, false,
+ 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentialsDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'JSON Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py
new file mode 100644
index 0000000000..cd56c3628a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/cross-origin.py
@@ -0,0 +1,16 @@
+def main(request, response):
+
+ headers = [
+ (b"Content-Type", b"application/json"),
+ (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+ (b"Access-Control-Allow-Credentials", b"true")
+ ]
+
+ milk = request.cookies.first(b"milk", None)
+
+ if milk is None:
+ return headers, u'{"requestHadCookies": false}'
+ elif milk.value == b"1":
+ return headers, u'{"requestHadCookies": true}'
+
+ return headers, u'{"requestHadCookies": false}'
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-parse-error-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-parse-error-with-cors.sub.html
new file mode 100644
index 0000000000..7d044f8579
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-parse-error-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-assertions-import-cross-domain-parse-error-WithCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-assertions-import-cross-domain-parse-error-WithCORS</h1>
+ <script type="module" crossorigin>
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.json?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-with-cors.sub.html
new file mode 100644
index 0000000000..d71938dae4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-assertions-import-cross-domain-WithCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-assertions-import-cross-domain-WithCORS</h1>
+ <script type="module" crossorigin>
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-without-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-without-cors.sub.html
new file mode 100644
index 0000000000..9d07d6c727
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/crossorigin-import-without-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-assertions-import-cross-domain-NoCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-assertions-import-cross-domain-NoCORS</h1>
+ <script type="module" onerror="document._log.push('error');">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json" assert { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json
new file mode 100644
index 0000000000..14a0526ebb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/data.json
@@ -0,0 +1,3 @@
+{
+ "answer": 42
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/false.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/false.json
new file mode 100644
index 0000000000..c508d5366f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/false.json
@@ -0,0 +1 @@
+false
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-matches.js
new file mode 100644
index 0000000000..969c90c290
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-matches.js
@@ -0,0 +1,2 @@
+import json from "./data.json" assert { type: "json" };
+window.matchesLog.push(`integrity-matches,json:${json.answer}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-mismatches.js
new file mode 100644
index 0000000000..3c88a98dbc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import json "./data.json" assert { type: "json" };
+window.mismatchesLog.push(`integrity-mismatches,json:${json.answer}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity.html
new file mode 100644
index 0000000000..68a794b973
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/integrity.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity=""</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+<script type="module" src="integrity-matches.js" integrity="sha384-VmQQfGzBiLKdyzw4FA4kL4ohu4tyujV68ddgW1aN/1v3cBZNNBn2gDFdVQxfL7+a" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+ assert_array_equals(window.matchesLog, ["integrity-matches,json:42"], "The module and its dependency must have executed");
+ assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and allow it to execute when it matches");
+
+test(() => {
+ assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+ assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/invalid-content-type.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/invalid-content-type.any.js
new file mode 100644
index 0000000000..cbccbd4842
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/invalid-content-type.any.js
@@ -0,0 +1,17 @@
+// META: global=window,dedicatedworker,sharedworker
+
+const content_types = [
+ "application/json+protobuf",
+ "application/json+blah",
+ "text/x-json",
+ "text/json+blah",
+ "application/blahjson",
+ "image/json",
+];
+for (const content_type of content_types) {
+ promise_test(async test => {
+ await promise_rejects_js(test, TypeError,
+ import(`./module.json?pipe=header(Content-Type,${content_type})`, { assert: { type: "json"} }),
+ `Import of a JSON module with MIME type ${content_type} should fail`);
+ }, `Try importing JSON module with MIME type ${content_type}`);
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/json-module-service-worker-test.https.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/json-module-service-worker-test.https.html
new file mode 100644
index 0000000000..cc47da1499
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/json-module-service-worker-test.https.html
@@ -0,0 +1,29 @@
+<!doctype html>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+ promise_test(async (test) => {
+ const reg = await navigator.serviceWorker.register('./serviceworker.js', { type: 'module' });
+ test.add_cleanup(() => reg.unregister());
+ assert_not_equals(reg.installing, undefined);
+ }, "Javascript importing JSON Module should load within the context of a service worker");
+
+ promise_test(test => {
+ return promise_rejects_dom(test, "SecurityError",
+ navigator.serviceWorker.register('./module.json', { type: 'module' }),
+ "Attempting to load JSON as a service worker should fail");
+ }, "Trying to register a service worker with a top-level JSON Module should fail");
+
+ promise_test(async (test) => {
+ const reg = await navigator.serviceWorker.register('./serviceworker-dynamic-import.js', { type: 'module' });
+ test.add_cleanup(() => reg.unregister());
+ assert_not_equals(reg.installing, undefined);
+ reg.installing.postMessage("PING");
+ const msgEvent = await new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ });
+ assert_equals(msgEvent.data, "FAILED");
+ }, "JSON Module dynamic import should not load within the context of a service worker");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.html
new file mode 100644
index 0000000000..a9dfc1e691
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for JSON modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+ "use strict";
+
+ var test1_load = event_test('inline, 200, parser-inserted', false, false);
+ var test1_error = event_test('inline, 404, parser-inserted', false, true);
+
+ var test2_load = event_test('src, 200, parser-inserted', true, false);
+ var test2_error = event_test('src, 404, parser-inserted', false, true);
+
+ var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false);
+ var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true);
+
+ var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false);
+ var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true);
+
+ var script3_dynamic_load = document.createElement('script');
+ script3_dynamic_load.setAttribute('type', 'module');
+ script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+ script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+ script3_dynamic_load.src = "./load-error-events.py?test=test3_dynamic_load";
+ document.head.appendChild(script3_dynamic_load);
+
+ var script3_dynamic_error = document.createElement('script');
+ script3_dynamic_error.setAttribute('type', 'module');
+ script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+ script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+ script3_dynamic_error.src = "./load-error-events.py?test=test3_dynamic_error";
+ document.head.appendChild(script3_dynamic_error);
+
+ var script4_dynamic_load = document.createElement('script');
+ script4_dynamic_load.setAttribute('type', 'module');
+ script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+ script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+ script4_dynamic_load.async = true;
+ script4_dynamic_load.appendChild(document.createTextNode(`
+ import "./module.json" assert { type: "json" };
+ onExecute(test4_dynamic_load);`
+ ));
+ document.head.appendChild(script4_dynamic_load);
+
+ var script4_dynamic_error = document.createElement('script');
+ script4_dynamic_error.setAttribute('type', 'module');
+ script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+ script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+ script4_dynamic_error.async = true;
+ script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.json" assert { type: "json" };`));
+ document.head.appendChild(script4_dynamic_error);
+</script>
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">
+ import "./module.json" assert { type: "json"};
+ onExecute(test1_load);
+</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">
+ import "./not_found.json" assert { type: "json"};
+ onExecute(test1_error);
+</script>
+<script src="./load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script>
+<script src="./load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.py
new file mode 100644
index 0000000000..4018adcdf7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/load-error-events.py
@@ -0,0 +1,14 @@
+import re
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ test = request.GET.first(b'test')
+ assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+ status = 200
+ if test.find(b'_load') >= 0:
+ content = b'import "./module.json" assert { type: "json"}; %s.executed = true;' % test
+ else:
+ content = b'import "./not_found.json" assert { type: "json"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+ return status, headers, content
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.html
new file mode 100644
index 0000000000..a495d4ac18
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+const t = async_test();
+</script>
+<script type="module" onerror="t.step(() => assert_unreached(event))">
+import v from "./module.json" assert { type: "json" };
+t.step(() => {
+ assert_equals(typeof v, "object");
+ assert_array_equals(Object.keys(v), ["test"]);
+ assert_equals(v.test, true);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.json
new file mode 100644
index 0000000000..f834b2a4e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/module.json
@@ -0,0 +1,3 @@
+{
+ "test": true
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/non-object.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/non-object.any.js
new file mode 100644
index 0000000000..37fbcae9fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/non-object.any.js
@@ -0,0 +1,14 @@
+// META: global=window,dedicatedworker,sharedworker
+
+for (const value of [null, true, false, "string"]) {
+ promise_test(async t => {
+ const result = await import(`./${value}.json`, { assert: { type: "json" } });
+ assert_equals(result.default, value);
+ }, `Non-object: ${value}`);
+}
+
+promise_test(async t => {
+ const result = await import("./array.json", { assert: { type: "json" } });
+ assert_array_equals(result.default, ["en", "try"]);
+}, "Non-object: array");
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/null.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/null.json
new file mode 100644
index 0000000000..19765bd501
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/null.json
@@ -0,0 +1 @@
+null
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.html
new file mode 100644
index 0000000000..9d0e3284fe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: parse error</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({
+ allow_uncaught_exception: true,
+});
+async_test(t => {
+ window.addEventListener("error", t.step_func_done(e => {
+ assert_true(e instanceof ErrorEvent, "ErrorEvent");
+ assert_equals(e.filename, new URL("parse-error.json", location).href);
+ assert_true(e.error instanceof SyntaxError, "SyntaxError");
+ }));
+});
+</script>
+<script type="module">
+import v from "./parse-error.json" assert { type: "json" };
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.json
new file mode 100644
index 0000000000..98232c64fc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/parse-error.json
@@ -0,0 +1 @@
+{
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py
new file mode 100644
index 0000000000..e9f0f1789b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ referrer = request.headers.get(b"referer", b"")
+ response_headers = [(b"Content-Type", b"application/json"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ return (200, response_headers,
+ b'{"referrer": "' + referrer + b'"}')
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-policies.sub.html
new file mode 100644
index 0000000000..655c962ab7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-policies.sub.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrers with JSON module requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+ // "name" parameter is necessary for bypassing the module map.
+ import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicy" assert { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py?name=remoteNoReferrerPolicy" assert { type: "json"};
+
+ const origin = (new URL(location.href)).origin + "/";
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, originUrl,
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the default referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, origin,
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the default referrer policy.");
+</script>
+<script type="module" referrerpolicy="origin">
+ import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyOrigin" assert { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py?name=remoteReferrerPolicyOrigin" assert { type: "json"};
+
+ const origin = (new URL(location.href)).origin + "/";
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, origin,
+ "Referrer origin should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the origin policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, origin,
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the origin policy.");
+
+</script>
+<script type="module" referrerpolicy="no-referrer">
+ import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyNoReferrer" assert { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" assert { type: "json"};
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, "",
+ "No referrer should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the no-referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, "",
+ "No referrer should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+</script>
+<script type="module" referrerpolicy="unsafe-url">
+ import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" assert { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module-assertions/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" assert { type: "json"};
+
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, originUrl,
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the unsafe-url referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, originUrl,
+ "Referrer URL should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the unsafe-url referrer policy.");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/repeated-imports.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/repeated-imports.any.js
new file mode 100644
index 0000000000..5cc3ee5b7c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/repeated-imports.any.js
@@ -0,0 +1,65 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=/common/utils.js
+
+promise_test(async test => {
+ await promise_rejects_js(test, TypeError,
+ import("./module.json"),
+ "Dynamic import of a JSON module without a type assertion should fail");
+
+ // This time the import should succeed because we're using the correct
+ // import even though the previous attempt with the same specifier failed.
+ const result = await import("./module.json", { assert: { type: "json" } });
+ assert_true(result.default.test);
+}, "Importing a specifier that previously failed due to an incorrect type assertion can succeed if the correct assertion is later given");
+
+promise_test(async test => {
+ // Append a URL fragment to the specifier so that this is independent
+ // from the previous test.
+ const result = await import("./module.json#2", { assert: { type: "json" } });
+ assert_true(result.default.test);
+
+ await promise_rejects_js(test, TypeError,
+ import("./module.json#2"),
+ "Dynamic import should fail with the type assertion missing even if the same specifier previously succeeded");
+}, "Importing a specifier that previously succeeded with the correct type assertion should fail if the incorrect assertion is later given");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { assert: { type: "json" } });
+ assert_equals(result_json.default.hello, "world");
+
+ // Import using the same specifier again; this time we get JS, which
+ // should succeed since we're not asserting a non-JS type this time.
+ const result_js = await import(`../serve-json-then-js.py?key=${uuid_token}`);
+ assert_equals(result_js.default, "hello");
+}, "Two modules of different type with the same specifier can load if the server changes its responses");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ await promise_rejects_js(test, TypeError,
+ import(`../serve-json-then-js.py?key=${uuid_token}`),
+ "Dynamic import of JS with a JSON type assertion should fail");
+
+ // Import using the same specifier/module type pair again; this time we get JS,
+ // but the import should still fail because the module map entry for this
+ // specifier/module type pair already contains a failure.
+ await promise_rejects_js(test, TypeError,
+ import(`../serve-json-then-js.py?key=${uuid_token}`),
+ "import should always fail if the same specifier/type assertion pair failed previously");
+}, "An import should always fail if the same specifier/type assertion pair failed previously");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { assert: { type: "json" } });
+ assert_equals(result_json.default.hello, "world");
+
+ // If this were to do another fetch, the import would fail because
+ // serve-json-then-js.py would give us JS this time. But, the module map
+ // entry for this specifier/module type pair already exists, so we
+ // successfully reuse the entry instead of fetching again.
+ const result_json_2 = await import(`../serve-json-then-js.py?key=${uuid_token}`, { assert: { type: "json" } });
+ assert_equals(result_json_2.default.hello, "world");
+}, "If an import previously succeeded for a given specifier/type assertion pair, future uses of that pair should yield the same result");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/script-element-json-src.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/script-element-json-src.html
new file mode 100644
index 0000000000..c6d7c9a76e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/script-element-json-src.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>&lt;script&gt; with JSON src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that <script> doesn't load when the src is JSON.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["error"]);
+ }));
+</script>
+<script type="module" src="./module.json" onload="t.unreached_func('JSON src should fail to load')" onerror="log.push('error')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker-dynamic-import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker-dynamic-import.js
new file mode 100644
index 0000000000..9466c6fbe4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker-dynamic-import.js
@@ -0,0 +1,5 @@
+onmessage = e => {
+ e.waitUntil(import("./module.json", { assert: { type: "json" } })
+ .then(module => e.source.postMessage("LOADED"))
+ .catch(error => e.source.postMessage("FAILED")));
+ }; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker.js
new file mode 100644
index 0000000000..3f0a4d1664
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/serviceworker.js
@@ -0,0 +1 @@
+import './module.json' assert { type: "json" }; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/string.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/string.json
new file mode 100644
index 0000000000..ace2d72d9d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/string.json
@@ -0,0 +1 @@
+"string"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/true.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/true.json
new file mode 100644
index 0000000000..27ba77ddaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/true.json
@@ -0,0 +1 @@
+true
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/utf-8.json
new file mode 100644
index 0000000000..088d982358
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/utf-8.json
@@ -0,0 +1,4 @@
+{
+ "data": "śćążź",
+ "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with utf-8 encoding."
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/valid-content-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/valid-content-type.html
new file mode 100644
index 0000000000..162f2d6afc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/valid-content-type.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: Content-Type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function check(t, v) {
+ t.step(() => {
+ assert_equals(typeof v, "object");
+ assert_array_equals(Object.keys(v), ["test"]);
+ assert_equals(v.test, true);
+ t.done();
+ });
+}
+const t1 = async_test("text/json");
+const t2 = async_test("application/json");
+const t3 = async_test("text/html+json");
+const t4 = async_test("image/svg+json");
+const t5 = async_test("text/json;boundary=something");
+const t6 = async_test("text/json;foo=bar");
+</script>
+<script type="module" onerror="t1.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=text/json" assert { type: "json"};
+check(t1, v);
+</script>
+<script type="module" onerror="t2.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=application/json" assert { type: "json"};
+check(t2, v);
+</script>
+<script type="module" onerror="t3.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=text/html%2Bjson" assert { type: "json"};
+check(t3, v);
+</script>
+<script type="module" onerror="t4.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=image/svg%2Bjson" assert { type: "json"};
+check(t4, v);
+</script>
+<script type="module" onerror="t5.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=text/json;boundary=something" assert { type: "json"};
+check(t5, v);
+</script>
+<script type="module" onerror="t6.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module-assertions/module.json&ct=text/json;foo=bar" assert { type: "json"};
+check(t6, v);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/windows-1250.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/windows-1250.json
new file mode 100644
index 0000000000..490e752ce9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module-assertions/windows-1250.json
@@ -0,0 +1,4 @@
+{
+ "data": "�湿�",
+ "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with windows1250 encoding."
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json
new file mode 100644
index 0000000000..e77e32d338
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json
@@ -0,0 +1 @@
+["en", "try"]
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json
new file mode 100644
index 0000000000..d22a45a591
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json
new file mode 100644
index 0000000000..4d1aa264a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json
new file mode 100644
index 0000000000..07ba933e86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json
@@ -0,0 +1 @@
+{ "data": "hello" } \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html
new file mode 100644
index 0000000000..dfadaba4d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="windows-1250">
+<title>JSON modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module">
+ import json from "../serve-with-content-type.py?fn=json-module/utf-8.json" with { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 even though document's encoding is windows-1250");
+</script>
+<script type="module">
+ import json from "../serve-with-content-type.py?fn=json-module/windows-1250.json&ct=text/json%3Bcharset=windows-1250" with { type: "json"};
+ test(() => {
+ assert_not_equals(json.data, "śćążź",
+ 'Should be decoded as UTF-8');
+ }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js
new file mode 100644
index 0000000000..483936a4f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js
@@ -0,0 +1,17 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=/common/utils.js
+
+promise_test(async () => {
+ const jsonModule = await import('./bom-utf-8.json', { with: { type: 'json' } });
+ assert_equals(jsonModule.default.data, 'hello');
+}, 'UTF-8 BOM should be stripped when decoding JSON module script');
+
+promise_test(async test => {
+ await promise_rejects_js(test, SyntaxError,
+ import('./bom-utf-16be.json', { with: { type: 'json' } }), 'Expected parse error from UTF-16BE BOM');
+}, 'UTF-16BE BOM should result in parse error in JSON module script');
+
+promise_test(async test => {
+ await promise_rejects_js(test, SyntaxError,
+ import('./bom-utf-16le.json', { with: { type: 'json' } }), 'Expected parse error from UTF-16LE BOM');
+}, 'UTF-16LE BOM should result in parse error in JSON module script');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html
new file mode 100644
index 0000000000..ce72f0ef1b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=utf-8" with { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=utf8 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=shift-jis" with { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=shift-jis is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=windows-1252" with { type: "json"};
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=windows-1252 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=utf-7" with { type: "json"};;
+ test(() => {
+ assert_equals(json.data, "śćążź");
+ }, "JSON module should be loaded as utf-8 when charset=utf-7 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+ import json from "../serve-with-content-type.py?fn=json-module/windows-1250.json&ct=text/json%3Bcharset=windows-1250" with { type: "json"};
+ test(() => {
+ assert_not_equals(json.data, "śćążź",
+ 'Should be decoded as UTF-8');
+ }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html
new file mode 100644
index 0000000000..99ff2f67e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+ <title>json-module-crossorigin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>json-module-crossorigin</h1>
+ <iframe id="import-WithCORS" src="crossorigin-import-with-cors.sub.html"></iframe>
+ <iframe id="import-NoCORS" src="crossorigin-import-without-cors.sub.html"></iframe>
+ <iframe id="import-parseerror-WithCors" src="crossorigin-import-parse-error-with-cors.sub.html"></iframe>
+ <script>
+
+ var tests = [
+ { "obj": async_test("Imported JSON module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported JSON: 42" },
+ { "obj": async_test("Imported JSON module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+ { "obj": async_test("Imported JSON module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "0-0" },
+ ];
+
+ window.addEventListener("load", function () {
+ tests.forEach(function (test) {
+ var target = document.getElementById(test.id);
+ test.obj.step(function () {
+ assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+ });
+ test.obj.done();
+ });
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html
new file mode 100644
index 0000000000..b89edf8d31
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module">
+ import json from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+ window.sameOriginNoneDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="anonymous">
+ import json from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+ window.sameOriginAnonymousDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="use-credentials">
+ import json from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+ window.sameOriginUseCredentialsDescendant = json.requestHadCookies;
+</script>
+<script type="module">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+ window.crossOriginNoneDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="anonymous">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+ window.crossOriginAnonymousDescendant = json.requestHadCookies;
+</script>
+<script type="module" crossOrigin="use-credentials">
+import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" };
+window.crossOriginUseCredentialsDescendant = json.requestHadCookies;
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+ window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html
new file mode 100644
index 0000000000..a6df506e21
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'milk=1';
+
+const setCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/json-module/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+
+const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+});
+
+promise_test(t => {
+ const iframe = document.createElement('iframe');
+
+ return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+ const messagePromise = new Promise(resolve => {
+ window.addEventListener('message', event => {
+ resolve();
+ });
+ });
+
+ iframe.src = 'credentials-iframe.sub.html';
+ document.body.appendChild(iframe);
+
+ return messagePromise;
+ }).then(() => {
+ const w = iframe.contentWindow;
+
+ assert_equals(w.sameOriginNoneDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymousDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentialsDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNoneDescendant, false,
+ 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymousDescendant, false,
+ 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentialsDescendant, true,
+ 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'JSON Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py
new file mode 100644
index 0000000000..cd56c3628a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py
@@ -0,0 +1,16 @@
+def main(request, response):
+
+ headers = [
+ (b"Content-Type", b"application/json"),
+ (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+ (b"Access-Control-Allow-Credentials", b"true")
+ ]
+
+ milk = request.cookies.first(b"milk", None)
+
+ if milk is None:
+ return headers, u'{"requestHadCookies": false}'
+ elif milk.value == b"1":
+ return headers, u'{"requestHadCookies": true}'
+
+ return headers, u'{"requestHadCookies": false}'
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html
new file mode 100644
index 0000000000..9972c53d1b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-import-cross-domain-parse-error-WithCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-import-cross-domain-parse-error-WithCORS</h1>
+ <script type="module" crossorigin>
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/parse-error.json?pipe=header(Access-Control-Allow-Origin,*)" with { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html
new file mode 100644
index 0000000000..95fd156df2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-import-cross-domain-WithCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-import-cross-domain-WithCORS</h1>
+ <script type="module" crossorigin>
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/data.json?pipe=header(Access-Control-Allow-Origin,*)" with { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html
new file mode 100644
index 0000000000..b9318c8b20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>json-module-import-cross-domain-NoCORS</title>
+ <script src="../module/crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>json-module-import-cross-domain-NoCORS</h1>
+ <script type="module" onerror="document._log.push('error');">
+ import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/data.json" with { type: "json" };
+ // Push an event to the log indicating that the script was executed.
+ document._log.push(`imported JSON: ${json.answer}`);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json
new file mode 100644
index 0000000000..14a0526ebb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json
@@ -0,0 +1,3 @@
+{
+ "answer": 42
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json
new file mode 100644
index 0000000000..c508d5366f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json
@@ -0,0 +1 @@
+false
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js
new file mode 100644
index 0000000000..20459c17e3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js
@@ -0,0 +1,2 @@
+import json from "./data.json" with { type: "json" };
+window.matchesLog.push(`integrity-matches,json:${json.answer}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js
new file mode 100644
index 0000000000..0406dbcca5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import json "./data.json" with { type: "json" };
+window.mismatchesLog.push(`integrity-mismatches,json:${json.answer}`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html
new file mode 100644
index 0000000000..68a794b973
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity=""</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+<script type="module" src="integrity-matches.js" integrity="sha384-VmQQfGzBiLKdyzw4FA4kL4ohu4tyujV68ddgW1aN/1v3cBZNNBn2gDFdVQxfL7+a" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+ assert_array_equals(window.matchesLog, ["integrity-matches,json:42"], "The module and its dependency must have executed");
+ assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and allow it to execute when it matches");
+
+test(() => {
+ assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+ assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js
new file mode 100644
index 0000000000..4226c3dc03
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js
@@ -0,0 +1,17 @@
+// META: global=window,dedicatedworker,sharedworker
+
+const content_types = [
+ "application/json+protobuf",
+ "application/json+blah",
+ "text/x-json",
+ "text/json+blah",
+ "application/blahjson",
+ "image/json",
+];
+for (const content_type of content_types) {
+ promise_test(async test => {
+ await promise_rejects_js(test, TypeError,
+ import(`./module.json?pipe=header(Content-Type,${content_type})`, { with: { type: "json"} }),
+ `Import of a JSON module with MIME type ${content_type} should fail`);
+ }, `Try importing JSON module with MIME type ${content_type}`);
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html
new file mode 100644
index 0000000000..cc47da1499
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html
@@ -0,0 +1,29 @@
+<!doctype html>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+ promise_test(async (test) => {
+ const reg = await navigator.serviceWorker.register('./serviceworker.js', { type: 'module' });
+ test.add_cleanup(() => reg.unregister());
+ assert_not_equals(reg.installing, undefined);
+ }, "Javascript importing JSON Module should load within the context of a service worker");
+
+ promise_test(test => {
+ return promise_rejects_dom(test, "SecurityError",
+ navigator.serviceWorker.register('./module.json', { type: 'module' }),
+ "Attempting to load JSON as a service worker should fail");
+ }, "Trying to register a service worker with a top-level JSON Module should fail");
+
+ promise_test(async (test) => {
+ const reg = await navigator.serviceWorker.register('./serviceworker-dynamic-import.js', { type: 'module' });
+ test.add_cleanup(() => reg.unregister());
+ assert_not_equals(reg.installing, undefined);
+ reg.installing.postMessage("PING");
+ const msgEvent = await new Promise(resolve => {
+ navigator.serviceWorker.onmessage = resolve;
+ });
+ assert_equals(msgEvent.data, "FAILED");
+ }, "JSON Module dynamic import should not load within the context of a service worker");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html
new file mode 100644
index 0000000000..54c1892540
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for JSON modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+ "use strict";
+
+ var test1_load = event_test('inline, 200, parser-inserted', false, false);
+ var test1_error = event_test('inline, 404, parser-inserted', false, true);
+
+ var test2_load = event_test('src, 200, parser-inserted', true, false);
+ var test2_error = event_test('src, 404, parser-inserted', false, true);
+
+ var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false);
+ var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true);
+
+ var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false);
+ var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true);
+
+ var script3_dynamic_load = document.createElement('script');
+ script3_dynamic_load.setAttribute('type', 'module');
+ script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+ script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+ script3_dynamic_load.src = "./load-error-events.py?test=test3_dynamic_load";
+ document.head.appendChild(script3_dynamic_load);
+
+ var script3_dynamic_error = document.createElement('script');
+ script3_dynamic_error.setAttribute('type', 'module');
+ script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+ script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+ script3_dynamic_error.src = "./load-error-events.py?test=test3_dynamic_error";
+ document.head.appendChild(script3_dynamic_error);
+
+ var script4_dynamic_load = document.createElement('script');
+ script4_dynamic_load.setAttribute('type', 'module');
+ script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+ script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+ script4_dynamic_load.async = true;
+ script4_dynamic_load.appendChild(document.createTextNode(`
+ import "./module.json" with { type: "json" };
+ onExecute(test4_dynamic_load);`
+ ));
+ document.head.appendChild(script4_dynamic_load);
+
+ var script4_dynamic_error = document.createElement('script');
+ script4_dynamic_error.setAttribute('type', 'module');
+ script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+ script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+ script4_dynamic_error.async = true;
+ script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.json" with { type: "json" };`));
+ document.head.appendChild(script4_dynamic_error);
+</script>
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">
+ import "./module.json" with { type: "json"};
+ onExecute(test1_load);
+</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">
+ import "./not_found.json" with { type: "json"};
+ onExecute(test1_error);
+</script>
+<script src="./load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script>
+<script src="./load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py
new file mode 100644
index 0000000000..244552a693
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py
@@ -0,0 +1,14 @@
+import re
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ test = request.GET.first(b'test')
+ assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+ status = 200
+ if test.find(b'_load') >= 0:
+ content = b'import "./module.json" with { type: "json"}; %s.executed = true;' % test
+ else:
+ content = b'import "./not_found.json" with { type: "json"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+ return status, headers, content
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html
new file mode 100644
index 0000000000..05fc264f36
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+const t = async_test();
+</script>
+<script type="module" onerror="t.step(() => assert_unreached(event))">
+import v from "./module.json" with { type: "json" };
+t.step(() => {
+ assert_equals(typeof v, "object");
+ assert_array_equals(Object.keys(v), ["test"]);
+ assert_equals(v.test, true);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json
new file mode 100644
index 0000000000..f834b2a4e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json
@@ -0,0 +1,3 @@
+{
+ "test": true
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js
new file mode 100644
index 0000000000..ae78ddf072
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js
@@ -0,0 +1,14 @@
+// META: global=window,dedicatedworker,sharedworker
+
+for (const value of [null, true, false, "string"]) {
+ promise_test(async t => {
+ const result = await import(`./${value}.json`, { with: { type: "json" } });
+ assert_equals(result.default, value);
+ }, `Non-object: ${value}`);
+}
+
+promise_test(async t => {
+ const result = await import("./array.json", { with: { type: "json" } });
+ assert_array_equals(result.default, ["en", "try"]);
+}, "Non-object: array");
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json
new file mode 100644
index 0000000000..19765bd501
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json
@@ -0,0 +1 @@
+null
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html
new file mode 100644
index 0000000000..88fb23a00d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: parse error</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({
+ allow_uncaught_exception: true,
+});
+async_test(t => {
+ window.addEventListener("error", t.step_func_done(e => {
+ assert_true(e instanceof ErrorEvent, "ErrorEvent");
+ assert_equals(e.filename, new URL("parse-error.json", location).href);
+ assert_true(e.error instanceof SyntaxError, "SyntaxError");
+ }));
+});
+</script>
+<script type="module">
+import v from "./parse-error.json" with { type: "json" };
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json
new file mode 100644
index 0000000000..98232c64fc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json
@@ -0,0 +1 @@
+{
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py
new file mode 100644
index 0000000000..e9f0f1789b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ referrer = request.headers.get(b"referer", b"")
+ response_headers = [(b"Content-Type", b"application/json"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ return (200, response_headers,
+ b'{"referrer": "' + referrer + b'"}')
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html
new file mode 100644
index 0000000000..1509c853e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrers with JSON module requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+ // "name" parameter is necessary for bypassing the module map.
+ import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicy" with { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteNoReferrerPolicy" with { type: "json"};
+
+ const origin = (new URL(location.href)).origin + "/";
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, originUrl,
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the default referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, origin,
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the default referrer policy.");
+</script>
+<script type="module" referrerpolicy="origin">
+ import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyOrigin" with { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteReferrerPolicyOrigin" with { type: "json"};
+
+ const origin = (new URL(location.href)).origin + "/";
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, origin,
+ "Referrer origin should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the origin policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, origin,
+ "Referrer origin should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the origin policy.");
+
+</script>
+<script type="module" referrerpolicy="no-referrer">
+ import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyNoReferrer" with { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" with { type: "json"};
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, "",
+ "No referrer should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the no-referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, "",
+ "No referrer should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+</script>
+<script type="module" referrerpolicy="unsafe-url">
+ import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" with { type: "json"};
+ import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" with { type: "json"};
+
+ const originUrl = location.href;
+
+ test(t => {
+ assert_equals(
+ referrerSame.referrer, originUrl,
+ "Referrer URL should be sent for the same-origin top-level script.");
+ }, "Importing a same-origin top-level script with the unsafe-url referrer policy.");
+
+ test(t => {
+ assert_equals(
+ referrerRemote.referrer, originUrl,
+ "Referrer URL should be sent for the remote-origin top-level script.");
+ }, "Importing a remote-origin top-level script with the unsafe-url referrer policy.");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js
new file mode 100644
index 0000000000..722251b84d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js
@@ -0,0 +1,65 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=/common/utils.js
+
+promise_test(async test => {
+ await promise_rejects_js(test, TypeError,
+ import("./module.json"),
+ "Dynamic import of a JSON module without a type attribute should fail");
+
+ // This time the import should succeed because we're using the correct
+ // import even though the previous attempt with the same specifier failed.
+ const result = await import("./module.json", { with: { type: "json" } });
+ assert_true(result.default.test);
+}, "Importing a specifier that previously failed due to an incorrect type attribute can succeed if the correct attribute is later given");
+
+promise_test(async test => {
+ // Append a URL fragment to the specifier so that this is independent
+ // from the previous test.
+ const result = await import("./module.json#2", { with: { type: "json" } });
+ assert_true(result.default.test);
+
+ await promise_rejects_js(test, TypeError,
+ import("./module.json#2"),
+ "Dynamic import should fail with the type attribute missing even if the same specifier previously succeeded");
+}, "Importing a specifier that previously succeeded with the correct type attribute should fail if the incorrect attribute is later given");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } });
+ assert_equals(result_json.default.hello, "world");
+
+ // Import using the same specifier again; this time we get JS, which
+ // should succeed since we're not asserting a non-JS type this time.
+ const result_js = await import(`../serve-json-then-js.py?key=${uuid_token}`);
+ assert_equals(result_js.default, "hello");
+}, "Two modules of different type with the same specifier can load if the server changes its responses");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ await promise_rejects_js(test, TypeError,
+ import(`../serve-json-then-js.py?key=${uuid_token}`),
+ "Dynamic import of JS with a JSON type attribute should fail");
+
+ // Import using the same specifier/module type pair again; this time we get JS,
+ // but the import should still fail because the module map entry for this
+ // specifier/module type pair already contains a failure.
+ await promise_rejects_js(test, TypeError,
+ import(`../serve-json-then-js.py?key=${uuid_token}`),
+ "import should always fail if the same specifier/type attribute pair failed previously");
+}, "An import should always fail if the same specifier/type attribute pair failed previously");
+
+promise_test(async test => {
+ const uuid_token = token();
+ // serve-json-then-js.py gives us JSON the first time
+ const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } });
+ assert_equals(result_json.default.hello, "world");
+
+ // If this were to do another fetch, the import would fail because
+ // serve-json-then-js.py would give us JS this time. But, the module map
+ // entry for this specifier/module type pair already exists, so we
+ // successfully reuse the entry instead of fetching again.
+ const result_json_2 = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } });
+ assert_equals(result_json_2.default.hello, "world");
+}, "If an import previously succeeded for a given specifier/type attribute pair, future uses of that pair should yield the same result");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html
new file mode 100644
index 0000000000..c6d7c9a76e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>&lt;script&gt; with JSON src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that <script> doesn't load when the src is JSON.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["error"]);
+ }));
+</script>
+<script type="module" src="./module.json" onload="t.unreached_func('JSON src should fail to load')" onerror="log.push('error')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js
new file mode 100644
index 0000000000..cd39c789cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js
@@ -0,0 +1,5 @@
+onmessage = e => {
+ e.waitUntil(import("./module.json", { with: { type: "json" } })
+ .then(module => e.source.postMessage("LOADED"))
+ .catch(error => e.source.postMessage("FAILED")));
+ }; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js
new file mode 100644
index 0000000000..65210fe3e7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js
@@ -0,0 +1 @@
+import './module.json' with { type: "json" }; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json
new file mode 100644
index 0000000000..ace2d72d9d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json
@@ -0,0 +1 @@
+"string"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json
new file mode 100644
index 0000000000..27ba77ddaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json
@@ -0,0 +1 @@
+true
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json
new file mode 100644
index 0000000000..088d982358
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json
@@ -0,0 +1,4 @@
+{
+ "data": "śćążź",
+ "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with utf-8 encoding."
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html
new file mode 100644
index 0000000000..3232b84d27
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>JSON modules: Content-Type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function check(t, v) {
+ t.step(() => {
+ assert_equals(typeof v, "object");
+ assert_array_equals(Object.keys(v), ["test"]);
+ assert_equals(v.test, true);
+ t.done();
+ });
+}
+const t1 = async_test("text/json");
+const t2 = async_test("application/json");
+const t3 = async_test("text/html+json");
+const t4 = async_test("image/svg+json");
+const t5 = async_test("text/json;boundary=something");
+const t6 = async_test("text/json;foo=bar");
+</script>
+<script type="module" onerror="t1.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json" with { type: "json"};
+check(t1, v);
+</script>
+<script type="module" onerror="t2.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=application/json" with { type: "json"};
+check(t2, v);
+</script>
+<script type="module" onerror="t3.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/html%2Bjson" with { type: "json"};
+check(t3, v);
+</script>
+<script type="module" onerror="t4.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=image/svg%2Bjson" with { type: "json"};
+check(t4, v);
+</script>
+<script type="module" onerror="t5.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;boundary=something" with { type: "json"};
+check(t5, v);
+</script>
+<script type="module" onerror="t6.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;foo=bar" with { type: "json"};
+check(t6, v);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json
new file mode 100644
index 0000000000..490e752ce9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json
@@ -0,0 +1,4 @@
+{
+ "data": "�湿�",
+ "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with windows1250 encoding."
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-1.html
new file mode 100644
index 0000000000..45571550e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-1.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for classic scripts</title>
+<!-- For module scripts see module/load-error-events*.html -->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+"use strict";
+var test1_load = event_test('src, 200, parser-inserted, defer, no async', true, false);
+var test2_load = event_test('src, 200, parser-inserted, no defer, no async', true, false);
+var test4_load = event_test('src, 200, parser-inserted, no defer, async', true, false);
+
+var test3_dynamic_load = event_test('src, 200, not parser-inserted, no defer, no async, no non-blocking', true, false);
+var test4_dynamic_load = event_test('src, 200, not parser-inserted, no defer, async', true, false);
+
+var test1_error = event_test('src, 404, parser-inserted, defer, no async', false, true);
+var test2_error = event_test('src, 404, parser-inserted, no defer, no async', false, true);
+var test4_error = event_test('src, 404, parser-inserted, no defer, async', false, true);
+
+var test3_dynamic_error = event_test('src, 404, not parser-inserted, no defer, no async, no non-blocking', false, true);
+var test4_dynamic_error = event_test('src, 404, not parser-inserted, no defer, async', false, true);
+
+var test6_load = event_test('no src, parser-inserted, no style sheets blocking scripts', false, false);
+
+var script3_dynamic_load = document.createElement('script');
+script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+script3_dynamic_load.async = false;
+script3_dynamic_load.src = "resources/load-error-events.py?test=test3_dynamic_load";
+document.head.appendChild(script3_dynamic_load);
+
+var script3_dynamic_error = document.createElement('script');
+script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+script3_dynamic_error.async = false;
+script3_dynamic_error.src = "resources/load-error-events.py?test=test3_dynamic_error";
+document.head.appendChild(script3_dynamic_error);
+
+var script4_dynamic_load = document.createElement('script');
+script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+script4_dynamic_load.async = true;
+script4_dynamic_load.src = "resources/load-error-events.py?test=test4_dynamic_load";
+document.head.appendChild(script4_dynamic_load);
+
+var script4_dynamic_error = document.createElement('script');
+script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+script4_dynamic_error.async = true;
+script4_dynamic_error.src = "resources/load-error-events.py?test=test4_dynamic_error";
+document.head.appendChild(script4_dynamic_error);
+</script>
+
+<script src="resources/load-error-events.py?test=test1_load" onload="onLoad(test1_load);" onerror="onError(test1_load);" defer></script>
+<script src="resources/load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);"></script>
+<script src="resources/load-error-events.py?test=test4_load" onload="onLoad(test4_load);" onerror="onError(test4_load);" async></script>
+<script src="resources/load-error-events.py?test=test1_error" onload="onLoad(test1_error);" onerror="onError(test1_error);" defer></script>
+<script src="resources/load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);"></script>
+<script src="resources/load-error-events.py?test=test4_error" onload="onLoad(test4_error);" onerror="onError(test4_error);" async></script>
+
+<script onload="onLoad(test6_load);" onerror="onError(test6_load);">
+"use strict";
+onExecute(test6_load);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html
new file mode 100644
index 0000000000..0748b45909
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-2.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for classic scripts with a style sheet that is blocking scripts</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script>
+"use strict";
+var test5_load = event_test('no src, parser-inserted, has style sheets blocking scripts, script nesting level == 1', false, false);
+</script>
+
+<link rel="stylesheet" href="/common/slow.py"></link>
+<!-- This is testing the case where an inline classic script is inserted
+by parser while there is an loading stylesheet. Therefore, it is critical to
+place a <link rel="stylesheet"> just above the <script> to be tested. -->
+<script onload="onLoad(test5_load);" onerror="onError(test5_load);">
+"use strict";
+onExecute(test5_load);
+</script>
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html
new file mode 100644
index 0000000000..83a752ce2c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-error-events-3.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for classic scripts with a style sheet that is blocking scripts and script nesting level &gt; 1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+"use strict";
+var test6_load = event_test('no src, parser-inserted, has style sheets blocking scripts, script nesting level == 2',
+ false, false);
+
+document.write(
+ `<link rel="stylesheet" href="/common/slow.py"></link>
+ <script onload="onLoad(test6_load);"
+ onerror="onError(test6_load);">
+ "use strict";
+ onExecute(test6_load);
+ </scr` + `ipt>`);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py
new file mode 100644
index 0000000000..2a6cc33029
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py
@@ -0,0 +1,13 @@
+import time
+
+def main(request, response):
+ response.headers.append(b"Content-Type", b"text/javascript")
+ try:
+ script_id = int(request.GET.first(b"id"))
+ delay = int(request.GET.first(b"sec"))
+ except:
+ response.set_error(400, u"Invalid parameter")
+
+ time.sleep(int(delay))
+
+ return u"log('%s')" % script_id
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror-module.html
new file mode 100644
index 0000000000..728ce32c38
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror-module.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Microtask checkpoint after window.onerror events (module)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/checkpoint-after-error-event.js" type="module"></script>
+ <script type="module">self.postMessage("foo");</script>
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror.html
new file mode 100644
index 0000000000..72a197ca6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Microtask checkpoint after window.onerror events (classic)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="resources/checkpoint-after-error-event.js"></script>
+ <script>self.postMessage("foo");</script>
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-module.html
new file mode 100644
index 0000000000..ff2b5d4943
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Microtask checkpoint after window.onerror events (module)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ const worker = new Worker(
+ "resources/checkpoint-after-error-event-worker-module.js",
+ {type: "module"});
+ fetch_tests_from_worker(worker);
+ worker.postMessage("foo");
+ </script>
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror.html
new file mode 100644
index 0000000000..1932c7183b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Microtask checkpoint after window.onerror events (module)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ const worker = new Worker(
+ "resources/checkpoint-after-error-event-worker.js");
+ fetch_tests_from_worker(worker);
+ worker.postMessage("foo");
+ </script>
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.js
new file mode 100644
index 0000000000..8791a099b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.js
@@ -0,0 +1,40 @@
+// META: global=dedicatedworker,sharedworker
+
+// The `then` handlers for `Promise.resolve()` are evaluated in the first
+// microtasks checkpoint after `Promise.resolve()`.
+
+// ----------------------------------------------------------------
+// Check when microtasks checkpoint is performed around importScripts().
+
+// The expectation is: the `then` handlers are evaluated after the script
+// calling importScripts() is finished, not immediately after importScripts().
+// Although #clean-up-after-running-script is executed as a part of
+// #run-a-classic-script for importScripts()ed scripts, but at that time
+// microtasks checkpoint is NOT performed because JavaScript execution context
+// stack is not empty.
+
+self.log = [];
+
+// Microtasks should be executed before
+// #run-a-classic-script/#run-a-module-script is completed, and thus before
+// script evaluation scheduled by setTimeout().
+async_test(t => {
+ self.addEventListener('error',
+ t.unreached_func('error event should not be fired'));
+
+ t.step_timeout(() => {
+ assert_array_equals(log, [
+ 'importScripts()ed script',
+ 'catch',
+ 'promise'
+ ]);
+ t.done();
+ },
+ 0);
+}, "Promise resolved during importScripts()");
+
+try {
+ importScripts('resources/resolve-then-throw.js');
+} catch (e) {
+ self.log.push('catch');
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-importScripts.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-importScripts.any.js
new file mode 100644
index 0000000000..bacfc9fd04
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-importScripts.any.js
@@ -0,0 +1,11 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=./resources/evaluation-order-setup.js
+
+// Spec: https://html.spec.whatwg.org/C/#run-a-classic-script
+// called from https://html.spec.whatwg.org/C/#import-scripts-into-worker-global-scope
+setupTest("importScripts() queueing a microtask then throwing an exception", [
+ "body",
+ "microtask",
+]);
+
+importScripts('./resources/evaluation-order-1-nothrow.js');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-static-import.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-static-import.any.js
new file mode 100644
index 0000000000..006eab7a7e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-nothrow-static-import.any.js
@@ -0,0 +1,5 @@
+// META: global=dedicatedworker-module,sharedworker-module
+// META: script=./resources/evaluation-order-setup.js
+
+import './resources/evaluation-order-1-nothrow-setup.js';
+import './resources/evaluation-order-1-nothrow.js';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-importScripts.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-importScripts.any.js
new file mode 100644
index 0000000000..0b42ea1e50
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-importScripts.any.js
@@ -0,0 +1,22 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=./resources/evaluation-order-setup.js
+
+// Spec: https://html.spec.whatwg.org/C/#run-a-classic-script
+// called from https://html.spec.whatwg.org/C/#import-scripts-into-worker-global-scope
+setupTest("importScripts() queueing a microtask then throwing an exception", [
+ // Step 6 of #run-a-classic-script.
+ "body",
+
+ // Step 7.1.1 ("Clean up after running script") is no-op because JavaScript
+ // execution context stack is still non-empty immediately after
+ // importScripts() as the outer script is still executing.
+
+ // Step 7.1.2 (Rethrowing an exception) causes worker onerror.
+ "global-error",
+
+ // Microtask checkpoint is performed later, perhaps
+ // "Clean up after running script" after the outer script is finished.
+ "microtask",
+]);
+
+importScripts('./resources/evaluation-order-1-throw.js');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-static-import.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-static-import.any.js
new file mode 100644
index 0000000000..f6cc427c71
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1-throw-static-import.any.js
@@ -0,0 +1,5 @@
+// META: global=dedicatedworker-module,sharedworker-module
+// META: script=./resources/evaluation-order-setup.js
+
+import './resources/evaluation-order-1-throw-setup.js';
+import './resources/evaluation-order-1-throw.js';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1.html
new file mode 100644
index 0000000000..4800ef81bc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/evaluation-order-setup.js"></script>
+
+<script>
+// Spec: https://html.spec.whatwg.org/C/#run-a-classic-script
+setupTest("Classic script queueing a microtask then throwing an exception", [
+ "body", // Step 6.
+ "global-error", // "Report the exception" at Step 7.3.
+ "microtask", // "Clean up after running script" at Step 7.2.
+ ]);
+</script>
+<script src="resources/evaluation-order-1-throw.js"
+ onerror="unreachable()" onload="testDone()"></script>
+
+<script>
+// Spec: https://html.spec.whatwg.org/C/#run-a-classic-script
+setupTest("Classic script queueing a microtask", [
+ "body", // Step 6.
+ "microtask", // "Clean up after running script" at Step 7.2.
+ ]);
+</script>
+<script src="resources/evaluation-order-1-nothrow.js"
+ onerror="unreachable()" onload="testDone()"></script>
+
+
+<script type="module" src="resources/evaluation-order-1-throw-setup.js"></script>
+<script type="module" src="resources/evaluation-order-1-throw.js"
+ onerror="unreachable()" onload="testDone()"></script>
+
+<script type="module" src="resources/evaluation-order-1-nothrow-setup.js"></script>
+<script type="module" src="resources/evaluation-order-1-nothrow.js"
+ onerror="unreachable()" onload="testDone()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.any.js
new file mode 100644
index 0000000000..bbc6474823
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.any.js
@@ -0,0 +1,5 @@
+// META: global=dedicatedworker-module,sharedworker-module
+// META: script=./resources/evaluation-order-setup.js
+
+import './resources/evaluation-order-2-setup.js';
+import './resources/evaluation-order-2.1.mjs';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.html
new file mode 100644
index 0000000000..e55c2ecbed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/evaluation-order-setup.js"></script>
+
+<script type="module" src="resources/evaluation-order-2-setup.js"></script>
+<script type="module" src="resources/evaluation-order-2.1.mjs"
+ onerror="unreachable()" onload="testDone()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.any.js
new file mode 100644
index 0000000000..19e94714e5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.any.js
@@ -0,0 +1,5 @@
+// META: global=dedicatedworker-module,sharedworker-module
+// META: script=./resources/evaluation-order-setup.js
+
+import './resources/evaluation-order-3-setup.js';
+import './resources/evaluation-order-3.1.mjs';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.html
new file mode 100644
index 0000000000..ef351acd28
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-3.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/evaluation-order-setup.js"></script>
+
+<script type="module" src="resources/evaluation-order-3-setup.js"></script>
+<script type="module" src="resources/evaluation-order-3.1.mjs"
+ onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-4.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-4.html
new file mode 100644
index 0000000000..f27678439d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/evaluation-order-4.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/evaluation-order-setup.js"></script>
+
+<script>
+// Spec: https://html.spec.whatwg.org/C/#run-a-module-script
+setupTest("Module script queueing a microtask then top-level await", [
+ "step-4.1-1", "step-4.1-2",
+ "microtask-4.1",
+ "script-load",
+ "step-4.2-1", "step-4.2-2",
+ "microtask-4.2",
+]);
+window.onerror = testDone;
+</script>
+<script type="module" src="resources/evaluation-order-4.1.mjs"
+ onerror="unreachable()" onload="log.push('script-load')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker-module.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker-module.js
new file mode 100644
index 0000000000..b9ae7142d5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker-module.js
@@ -0,0 +1,2 @@
+import "/resources/testharness.js";
+import "./checkpoint-after-error-event.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker.js
new file mode 100644
index 0000000000..4694db1e44
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event-worker.js
@@ -0,0 +1,2 @@
+importScripts("/resources/testharness.js");
+importScripts("checkpoint-after-error-event.js");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event.js
new file mode 100644
index 0000000000..1a2b9404a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/checkpoint-after-error-event.js
@@ -0,0 +1,89 @@
+// The `then` handlers for `Promise.resolve()` are evaluated in the first
+// microtasks checkpoint after `Promise.resolve()`.
+
+self.setup({allow_uncaught_exception: true});
+
+// ----------------------------------------------------------------
+// Check when microtasks checkpoint is performed
+// - Around `self`'s error event fired via
+// https://html.spec.whatwg.org/C/#report-the-error during
+// - https://html.spec.whatwg.org/C/#run-a-classic-script or
+// - https://html.spec.whatwg.org/C/#run-a-module-script.
+
+// The expectation is: the `then` handlers are evaluated after all error event
+// handlers are evaluated, not after each error event handler.
+
+// Just after each event handler is invoked,
+// https://webidl.spec.whatwg.org/#call-a-user-objects-operation
+// calls #clean-up-after-running-script, but this doesn't execute new
+// microtasks immediately, because:
+// - Before https://github.com/whatwg/html/pull/4352:
+// #report-the-error is called before #clean-up-after-running-script by
+// #run-a-classic-script/#run-a-module-script, so microtask checkpoint
+// is not performed because JavaScript execution context stack is not empty.
+// - After https://github.com/whatwg/html/pull/4352:
+// #report-the-error is called during #perform-a-microtask-checkpoint (because
+// it is called on rejection of promises), so #perform-a-microtask-checkpoint
+// is executed but early exited.
+self.log = [];
+
+self.addEventListener('error', () => {
+ log.push('handler 1');
+ Promise.resolve().then(() => log.push('handler 1 promise'));
+});
+self.addEventListener('error', () => {
+ log.push('handler 2');
+ Promise.resolve().then(() => log.push('handler 2 promise'));
+});
+
+// Microtasks should be executed before
+// #run-a-classic-script/#run-a-module-script is completed, and thus before
+// script evaluation scheduled by setTimeout().
+async_test(t => {
+ t.step_timeout(() => {
+ assert_array_equals(log, [
+ 'handler 1',
+ 'handler 2',
+ 'handler 1 promise',
+ 'handler 2 promise'
+ ]);
+ t.done();
+ },
+ 0);
+}, "Promise resolved during #report-the-error");
+
+// ----------------------------------------------------------------
+// Check when microtasks checkpoint is performed
+// around event events other than the `self` error event cases above.
+// In this case, microtasks are executed just after each event handler is
+// invoked via #clean-up-after-running-script called from
+// https://webidl.spec.whatwg.org/#call-a-user-objects-operation,
+// because the event handlers are executed outside the
+// #prepare-to-run-script/#clean-up-after-running-script scopes in
+// #run-a-classic-script/#run-a-module-script.
+self.log2 = [];
+self.t2 = async_test(
+ "Promise resolved during event handlers other than error");
+
+self.addEventListener('message', () => {
+ log2.push('handler 1');
+ Promise.resolve().then(() => log2.push('handler 1 promise'));
+});
+self.addEventListener('message', () => {
+ log2.push('handler 2');
+ Promise.resolve().then(t2.step_func_done(() => {
+ log2.push('handler 2 promise');
+ assert_array_equals(log2, [
+ 'handler 1',
+ 'handler 1 promise',
+ 'handler 2',
+ 'handler 2 promise'
+ ]);
+ }));
+});
+
+// ----------------------------------------------------------------
+
+done();
+
+throw new Error('script 1');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow-setup.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow-setup.js
new file mode 100644
index 0000000000..1b42e99593
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow-setup.js
@@ -0,0 +1,5 @@
+// Spec: https://html.spec.whatwg.org/C/#run-a-module-script
+setupTest("Module script queueing a microtask", [
+ "body", // Step 6.
+ "microtask", // "Clean up after running script" at Step 8.
+]);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow.js
new file mode 100644
index 0000000000..e19d9b1b13
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-nothrow.js
@@ -0,0 +1,2 @@
+queueMicrotask(() => globalThis.log.push("microtask"));
+globalThis.log.push("body");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw-setup.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw-setup.js
new file mode 100644
index 0000000000..651a494e53
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw-setup.js
@@ -0,0 +1,10 @@
+// Spec: https://html.spec.whatwg.org/C/#run-a-module-script
+setupTest("Module script queueing a microtask then throwing an exception", [
+ "body", // Step 6.
+ "microtask", // "Clean up after running script" at Step 8.
+ "global-error", // "Clean up after running script" at Step 8, because
+ // `evaluationPromise` is synchronously rejected and the rejection is
+ // processed in the microtask checkpoint here (See also Step 7).
+ // As `evaluationPromise` is rejected after the microtask queued during
+ // evaluation, "global-error" occurs after "microtask".
+]);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw.js
new file mode 100644
index 0000000000..2451df1c15
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-1-throw.js
@@ -0,0 +1,4 @@
+queueMicrotask(() => globalThis.log.push("microtask"));
+globalThis.log.push("body");
+
+throw new Error("error");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2-setup.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2-setup.js
new file mode 100644
index 0000000000..46f7354538
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2-setup.js
@@ -0,0 +1,10 @@
+// Spec: https://html.spec.whatwg.org/C/#run-a-module-script
+setupTest("Module script queueing a microtask then throwing an exception", [
+ "step-2.2-1", "step-2.2-2", // Step 6.
+ "microtask-2.2", // "Clean up after running script" at Step 8.
+ "global-error", // "Clean up after running script" at Step 8,
+ // because `evaluationPromise` is synchronously rejected and the rejection
+ // is processed in the microtask checkpoint here (See also Step 7).
+ // As `evaluationPromise` is rejected after the microtask queued during
+ // evaluation, "global-error" occurs after "microtask".
+]);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.1.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.1.mjs
new file mode 100644
index 0000000000..d6c2afa2f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.1.mjs
@@ -0,0 +1,8 @@
+globalThis.log.push("step-2.1-1");
+queueMicrotask(() => globalThis.log.push("microtask-2.1"));
+globalThis.log.push("step-2.1-2");
+
+// import is evaluated first.
+import "./evaluation-order-2.2.mjs";
+
+globalThis.log.push("step-2.1-3");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.2.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.2.mjs
new file mode 100644
index 0000000000..5c67c4f9a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-2.2.mjs
@@ -0,0 +1,7 @@
+globalThis.log.push("step-2.2-1");
+queueMicrotask(() => globalThis.log.push("microtask-2.2"));
+globalThis.log.push("step-2.2-2");
+
+globalThis.test_load.step_timeout(() => globalThis.testDone(), 0);
+
+throw new Error("error");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3-setup.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3-setup.js
new file mode 100644
index 0000000000..edc046910e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3-setup.js
@@ -0,0 +1,7 @@
+setupTest("Module script queueing a microtask then throwing an exception", [
+ "step-3.1-1", "step-3.1-2", "step-3.1-3",
+ "microtask-3.1",
+ "step-3.2-1", "step-3.2-2",
+ "microtask-3.2",
+ "import-catch", "error",
+]);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.1.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.1.mjs
new file mode 100644
index 0000000000..ef320632af
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.1.mjs
@@ -0,0 +1,11 @@
+globalThis.log.push("step-3.1-1");
+queueMicrotask(() => globalThis.log.push("microtask-3.1"));
+globalThis.log.push("step-3.1-2");
+
+import("./evaluation-order-3.2.mjs").catch(
+ exception => {
+ globalThis.log.push("import-catch", exception.message);
+ globalThis.testDone();
+ });
+
+globalThis.log.push("step-3.1-3");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.2.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.2.mjs
new file mode 100644
index 0000000000..8ccb581206
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-3.2.mjs
@@ -0,0 +1,5 @@
+globalThis.log.push("step-3.2-1");
+queueMicrotask(() => globalThis.log.push("microtask-3.2"));
+globalThis.log.push("step-3.2-2");
+
+throw new Error("error");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.1.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.1.mjs
new file mode 100644
index 0000000000..f3347c1d28
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.1.mjs
@@ -0,0 +1,8 @@
+log.push("step-4.1-1");
+queueMicrotask(() => log.push("microtask-4.1"));
+log.push("step-4.1-2");
+
+await import("./evaluation-order-4.2.mjs");
+
+// Not happening as we throw in the above module.
+log.push("step-4.1-3");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.2.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.2.mjs
new file mode 100644
index 0000000000..96a5cca3a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-4.2.mjs
@@ -0,0 +1,5 @@
+log.push("step-4.2-1");
+queueMicrotask(() => log.push("microtask-4.2"));
+log.push("step-4.2-2");
+
+throw new Error("error");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-setup.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-setup.js
new file mode 100644
index 0000000000..d2e28935c4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/evaluation-order-setup.js
@@ -0,0 +1,30 @@
+globalThis.setup({allow_uncaught_exception: true});
+
+// Must be called after previous tests are completed.
+globalThis.setupTest = (description, expectedLog) => {
+ globalThis.log = [];
+ globalThis.onerror = message => {
+ globalThis.log.push("global-error");
+ return true;
+ };
+ globalThis.onunhandledrejection =
+ () => globalThis.log.push('unhandled-promise-rejection');
+
+ globalThis.unreachable = () => globalThis.log.push("unreachable");
+
+ globalThis.test_load = async_test(description);
+ globalThis.testDone = globalThis.test_load.step_func_done(() => {
+ assert_array_equals(globalThis.log, expectedLog);
+ });
+
+ if (!('Window' in globalThis && globalThis instanceof Window)) {
+ // In workers, there are no <script> load event, so scheduling `testDone()`
+ // here, assuming the target script is loaded and evaluated soon.
+ globalThis.test_load.step_timeout(() => globalThis.testDone(), 1000);
+
+ // In workers, call `done()` here because the auto-generated `done()` calls
+ // by `any.js` etc. are at the end of main script and thus are not
+ // evaluated when the target script throws an exception.
+ done();
+ }
+};
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/resolve-then-throw.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/resolve-then-throw.js
new file mode 100644
index 0000000000..a841eb780a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/microtasks/resources/resolve-then-throw.js
@@ -0,0 +1,3 @@
+self.log.push('importScripts()ed script');
+Promise.resolve().then(() => self.log.push('promise'));
+throw new Error('foo');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/bad-module-specifier.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/bad-module-specifier.js
new file mode 100644
index 0000000000..a53a3bebe7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/bad-module-specifier.js
@@ -0,0 +1,3 @@
+import "string-without-dot-slash-prefix";
+import "./this.js";
+log.push("bad-module-specifier");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-01.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-01.html
new file mode 100644
index 0000000000..7cd4916309
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-01.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Root module scripts should always use UTF-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module" src="../serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript&dummy=1"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 module script');
+</script>
+
+<script type="module" src="../serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript&dummy=2" charset="windows-1250"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 module script with wrong charset in attribute');
+</script>
+
+<script type="module" src="../serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript%3Bcharset=windows-1250&dummy=3"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 module script with wrong charset in Content-Type');
+</script>
+
+<script type="module" src="../serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript&dummy=1"></script>
+<script type="module">
+test(function() {
+ assert_not_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'Non-UTF-8 module script');
+</script>
+
+<script type="module" src="../serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript&dummy=2" charset="windows-1250"></script>
+<script type="module">
+test(function() {
+ assert_not_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'Non-UTF-8 module script with charset in attribute');
+</script>
+
+<script type="module" src="../serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=windows-1250"></script>
+<script type="module">
+test(function() {
+ assert_not_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'Non-UTF-8 module script with charset in Content-Type');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-02.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-02.html
new file mode 100644
index 0000000000..c7c4517ad3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-02.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>Module scripts should ignore BOMs and always use UTF-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({allow_uncaught_exception: true});
+</script>
+<script type="module" src="../serve-with-content-type.py?fn=resources/bom-utf-8.js&ct=text/javascript"></script>
+<script type="module" src="../serve-with-content-type.py?fn=resources/bom-utf-16be.js&ct=text/javascript"></script>
+<script type="module" src="../serve-with-content-type.py?fn=resources/bom-utf-16le.js&ct=text/javascript"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.executed_utf8_bom, '\u4e09\u6751\u304b\u306a\u5b50',
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 module script with UTF-8 BOM');
+
+test(function() {
+ assert_equals(window.executed_utf16be_bom, undefined,
+ 'Should result in compile error because of UTF-16BE BOM');
+}, 'UTF-16 module script with UTF-16BE BOM');
+
+test(function() {
+ assert_equals(window.executed_utf16le_bom, undefined,
+ 'Should result in compile error because of UTF-16LE BOM');
+}, 'UTF-16 module script with UTF-16LE BOM');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-03.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-03.html
new file mode 100644
index 0000000000..666cb2e68b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/charset-03.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Imported module scripts should always use UTF-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script type="module" src="resources/import-utf8.js"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 imported module script');
+</script>
+
+<script type="module" src="resources/import-utf8-with-charset-header.js"></script>
+<script type="module">
+test(function() {
+ assert_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'UTF-8 imported module script with wrong charset in Content-Type');
+</script>
+
+<script type="module" src="resources/import-non-utf8.js"></script>
+<script type="module">
+test(function() {
+ assert_not_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'Non-UTF-8 imported module script');
+</script>
+
+<script type="module" src="resources/import-non-utf8-with-charset-header.js"></script>
+<script type="module">
+test(function() {
+ assert_not_equals(window.getSomeString(), "śćążź",
+ 'Should be decoded as UTF-8');
+}, 'Non-UTF-8 imported module script with charset in Content-Type');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html
new file mode 100644
index 0000000000..50933da2c1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Choice of parse errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Parse errors in different files should be reported " +
+ "depending on different roots");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4);
+
+ // Two different parse errors from different module scripts
+ // should be reported for each <script> element.
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1], 1);
+
+ assert_equals(log[2].constructor, SyntaxError);
+ assert_equals(log[3], 2);
+
+ assert_not_equals(log[0], log[2],
+ 'two different parse errors should be reported');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./choice-of-error-1a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./choice-of-error-1b.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1a.js
new file mode 100644
index 0000000000..f479e5e1fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1a.js
@@ -0,0 +1,2 @@
+import './choice-of-error-1b.js';
+import './syntaxerror.js?1c';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1b.js
new file mode 100644
index 0000000000..257f4a4678
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1b.js
@@ -0,0 +1,2 @@
+import './choice-of-error-1a.js';
+import './syntaxerror.js?1d';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html
new file mode 100644
index 0000000000..51adb09d11
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Choice of instantiation errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Instantiation errors in different files should be reported " +
+ "depending on different roots");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4);
+
+ // Two different instantiation errors from different module scripts
+ // should be reported for each <script> element.
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1], 1);
+
+ assert_equals(log[2].constructor, SyntaxError);
+ assert_equals(log[3], 2);
+
+ assert_not_equals(log[0], log[2],
+ 'two different instantiation errors should be reported');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./choice-of-error-2a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./choice-of-error-2b.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2a.js
new file mode 100644
index 0000000000..2dc7aac11a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2a.js
@@ -0,0 +1,2 @@
+import './choice-of-error-2b.js';
+import './instantiation-error-1.js?2c';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2b.js
new file mode 100644
index 0000000000..2adb9eea59
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2b.js
@@ -0,0 +1,2 @@
+import './choice-of-error-2a.js';
+import './instantiation-error-1.js?2d';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html
new file mode 100644
index 0000000000..bc52119bfe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Choice of evaluation errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Evaluation errors are cached in intermediate module scripts");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 5);
+
+ // Evaluation errors, unlike parse/instantiation errors, are remembered
+ // and cached in module scripts between the root and the script that
+ // caused an evaluation error, and thus the same evaluation error
+ // is reported for both <script> elements.
+ assert_equals(log[0], "throw2");
+ assert_true(log[1].bar);
+ assert_equals(log[2], 1);
+
+ assert_true(log[3].bar);
+ assert_equals(log[4], 2);
+
+ assert_equals(log[1], log[3], 'evaluation errors must be the same');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./choice-of-error-3a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./choice-of-error-3b.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3a.js
new file mode 100644
index 0000000000..71154674a3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3a.js
@@ -0,0 +1,2 @@
+import './choice-of-error-3b.js';
+import './throw.js?3c';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3b.js
new file mode 100644
index 0000000000..2131a35eff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3b.js
@@ -0,0 +1,2 @@
+import './choice-of-error-3a.js';
+import './throw2.js?3d';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-1.html
new file mode 100644
index 0000000000..ff580d4899
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-1.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Handling of compilation errors, 1</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that syntax errors lead to SyntaxError events on window, " +
+ "and that exceptions are remembered.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 5);
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_true(log.every(exn => exn === log[0]));
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./syntaxerror.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror-nested.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror-nested.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-2.html
new file mode 100644
index 0000000000..131a6e439f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/compilation-error-2.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Handling of compilation errors, 2</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that syntax errors lead to SyntaxError events on window, " +
+ "and that exceptions are remembered.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 5);
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_true(log.every(exn => exn === log[0]));
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./syntaxerror-nested.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror-nested.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror-nested.js" onerror="unreachable()"></script>
+<script type="module" src="./syntaxerror.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
new file mode 100644
index 0000000000..983961ae44
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/credentials.sub.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'same=1';
+
+const setCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=cross&path=/html/semantics/scripting-1/the-script-element/module/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+
+const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+});
+
+promise_test(t => {
+ const iframe = document.createElement('iframe');
+
+ return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+ const messagePromise = new Promise(resolve => {
+ window.addEventListener('message', event => {
+ resolve();
+ });
+ });
+
+ iframe.src = 'resources/credentials-iframe.sub.html';
+ document.body.appendChild(iframe);
+
+ return messagePromise;
+ }).then(() => {
+ const w = iframe.contentWindow;
+
+ assert_equals(w.sameOriginNone, 'found',
+ 'Modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymous, 'found',
+ 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentials, 'found',
+ 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNone, 'not found',
+ 'Modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymous, 'not found',
+ 'Modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentials, 'found',
+ 'Modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+
+ assert_equals(w.sameOriginNoneDescendant, 'found',
+ 'Descendant modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+ assert_equals(w.sameOriginAnonymousDescendant, 'found',
+ 'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+ assert_equals(w.sameOriginUseCredentialsDescendant, 'found',
+ 'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+ assert_equals(w.crossOriginNoneDescendant, 'not found',
+ 'Descendant modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+ assert_equals(w.crossOriginAnonymousDescendant, 'not found',
+ 'Descendant modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+ assert_equals(w.crossOriginUseCredentialsDescendant, 'found',
+ 'Descendant modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-common.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-common.js
new file mode 100644
index 0000000000..59bf0fd42f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-common.js
@@ -0,0 +1,8 @@
+document._log = [];
+window.addEventListener("error", function (ev) {
+ var errorSerialized = ev.lineno + "-" + ev.colno;
+ document._log.push(errorSerialized);
+});
+window.addEventListener("load", function () {
+ document._log = document._log.join(",");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-different.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-different.sub.html
new file mode 100644
index 0000000000..8eb3292e89
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-different.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-import-NoCORS</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-import-NoCORS</h1>
+ <script type="module" onerror="document._log.push('error');">
+
+ import { foo } from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-missingheader.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-missingheader.sub.html
new file mode 100644
index 0000000000..cccb30f718
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-missingheader.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-BlockedMissingHeader</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-BlockedMissingHeader</h1>
+ <script type="module" onerror="document._log.push('error');" crossorigin>
+
+ import { foo } from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-same.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-same.sub.html
new file mode 100644
index 0000000000..84f4de1d7e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-same.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-WithCORS</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-WithCORS</h1>
+ <script type="module" crossorigin>
+
+ import { foo } from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js?pipe=header(Access-Control-Allow-Origin,*)";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-wrongheader.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-wrongheader.sub.html
new file mode 100644
index 0000000000..5743a9e304
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-import-wrongheader.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-BlockedWrongHeader</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-BlockedWrongHeader</h1>
+ <script type="module" onerror="document._log.push('error');" crossorigin>
+
+ import { foo } from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js?pipe=header(Access-Control-Allow-Origin,http://{{domains[www2]}}:{{ports[http][0]}})";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-different.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-different.sub.html
new file mode 100644
index 0000000000..54d4354c53
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-different.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-NoCORS</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-NoCORS</h1>
+ <script type="module" src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js" onerror="document._log.push('error');"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-missingheader.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-missingheader.sub.html
new file mode 100644
index 0000000000..03943002ba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-missingheader.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-BlockedMissingHeader</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-BlockedMissingHeader</h1>
+ <script type="module" src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js" onerror="document._log.push('error');" crossorigin></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-same.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-same.sub.html
new file mode 100644
index 0000000000..3ec839e9a9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-same.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-WithCORS</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-WithCORS</h1>
+ <script type="module" src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js?pipe=header(Access-Control-Allow-Origin,*)" crossorigin></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-wrongheader.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-wrongheader.sub.html
new file mode 100644
index 0000000000..c45736a896
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-root-wrongheader.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin-root-BlockedWrongHeader</title>
+ <script src="crossorigin-common.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin-root-BlockedWrongHeader</h1>
+ <script type="module" src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js?pipe=header(Access-Control-Allow-Origin,http://{{domains[www2]}}:{{ports[http][0]}})" onerror="document._log.push('error');" crossorigin></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js
new file mode 100644
index 0000000000..29d04ec619
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin-scripterror.js
@@ -0,0 +1,8 @@
+export var foo = {};
+
+// Push an event to the log indicating that the script was executed.
+document._log.push("running");
+
+// Deliberately trigger an error to test what details of the error
+// the (possibly) cross-origin parent can listen to.
+nonExistentMethod();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin.html
new file mode 100644
index 0000000000..5c8d6667b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/crossorigin.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-crossOrigin</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>html-script-module-crossOrigin</h1>
+ <iframe id="root-WithCORS" src="crossorigin-root-same.sub.html"></iframe>
+ <iframe id="root-NoCORS" src="crossorigin-root-different.sub.html"></iframe>
+ <iframe id="root-BlockedMissingHeader" src="crossorigin-root-missingheader.sub.html"></iframe>
+ <iframe id="root-BlockedWrongHeader" src="crossorigin-root-wrongheader.sub.html"></iframe>
+ <iframe id="import-WithCORS" src="crossorigin-import-same.sub.html"></iframe>
+ <iframe id="import-NoCORS" src="crossorigin-import-different.sub.html"></iframe>
+ <iframe id="import-BlockedMissingHeader" src="crossorigin-import-missingheader.sub.html"></iframe>
+ <iframe id="import-BlockedWrongHeader" src="crossorigin-import-wrongheader.sub.html"></iframe>
+ <script>
+
+ var tests = [
+ { "obj": async_test("Root module, Error in CORS-same-origin script"), "id": "root-WithCORS", "expected": "running,8-1" },
+ { "obj": async_test("Root module, Blocked script download, missing CORS ACAO header"), "id": "root-NoCORS", "expected": "error" },
+ { "obj": async_test("Root module, Blocked script download, crossorigin attribute with missing CORS ACAO header"), "id": "root-BlockedMissingHeader", "expected": "error" },
+ { "obj": async_test("Root module, Blocked script download, mismatched CORS ACAO header"), "id": "root-BlockedWrongHeader", "expected": "error" },
+ { "obj": async_test("Imported module, Error in CORS-same-origin script"), "id": "import-WithCORS", "expected": "running,8-1" },
+ { "obj": async_test("Imported module, Blocked script download, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+ { "obj": async_test("Imported module, Blocked script download, crossorigin attribute with missing CORS ACAO header"), "id": "import-BlockedMissingHeader", "expected": "error" },
+ { "obj": async_test("Imported module, Blocked script download, mismatched CORS ACAO header"), "id": "import-BlockedWrongHeader", "expected": "error" },
+ ];
+
+ window.addEventListener("load", function () {
+ tests.forEach(function (test) {
+ var target = document.getElementById(test.id);
+ test.obj.step(function () {
+ assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+ });
+ test.obj.done();
+ });
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentScript-null.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentScript-null.html
new file mode 100644
index 0000000000..146a9db60d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentScript-null.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module" src="set-currentScript-on-window.js"></script>
+<script type="module">
+import { currentScriptOnImportedModule } from "./currentscript.js";
+
+test(() => {
+ assert_equals(document.currentScript, null, "document.currentScript on inline scripts should be null");
+ assert_equals(currentScriptOnImportedModule, null, "document.currentScript on imported scripts should be null");
+ assert_equals(window.currentScriptRecorded, null, "document.currentScript on external module scripts should be null");
+}, "currentScript on script type=module should be all null");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentscript.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentscript.js
new file mode 100644
index 0000000000..547359ff96
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/currentscript.js
@@ -0,0 +1 @@
+export let currentScriptOnImportedModule = window.document.currentScript;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html
new file mode 100644
index 0000000000..bd77a8f1bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>Handling of exceptions in custom element constructors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that exceptions from the constructor of a custom element " +
+ "inside a module are propagated as expected.\n");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(1, log.length);
+ const exception = log[0];
+ assert_true(exception instanceof Error);
+ assert_equals(exception.message, "custom element error");
+ }));
+</script>
+<script type="module">
+ class XThrower extends HTMLElement {
+ constructor() {
+ super();
+ throw new Error("custom element error");
+ }
+ }
+ customElements.define("x-thrower", XThrower);
+ document.createElement("x-thrower");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access-a.js
new file mode 100644
index 0000000000..1f91f93eb1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access-a.js
@@ -0,0 +1,3 @@
+log.push("cycle-tdz-access-a");
+import { Y } from "./cycle-tdz-access.js";
+export var X = Y;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access.js
new file mode 100644
index 0000000000..9df68b3b27
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-tdz-access.js
@@ -0,0 +1,3 @@
+log.push("cycle-tdz-access");
+import { X } from "./cycle-tdz-access-a.js";
+export let Y = X;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable-a.js
new file mode 100644
index 0000000000..12994f23d0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable-a.js
@@ -0,0 +1,2 @@
+export {x} from "./cycle-unresolvable.js";
+log.push("cycle-unresolvable-a");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable.js
new file mode 100644
index 0000000000..61c6d8dcb0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/cycle-unresolvable.js
@@ -0,0 +1,2 @@
+export {x} from "./cycle-unresolvable-a.js";
+log.push("cycle-unresolvable");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-1.html
new file mode 100644
index 0000000000..57002a3e07
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Importing a module multiple times with the same specifier</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+window.log = [];
+</script>
+<script type="module">
+import { foo } from './export-something.js';
+import { set_foo } from './export-something.js';
+import default1 from './export-default.js';
+import default2 from './export-default.js';
+
+test(() => {
+ assert_array_equals(log, ['export-something', 'export-default']);
+ assert_equals(foo, 42);
+ set_foo(43);
+ assert_equals(foo, 43);
+ assert_equals(default1, "fox");
+ assert_equals(default2, "fox");
+}, 'Duplicated imports with the same specifier');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-2.html
new file mode 100644
index 0000000000..6a01495c33
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/duplicated-imports-2.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Importing a module multiple times with the different specifier</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+window.log = [];
+</script>
+<script type="module">
+import { foo } from './export-something.js';
+import { set_foo } from '../module/export-something.js';
+import default1 from './export-default.js';
+import default2 from '../module/export-default.js';
+
+test(() => {
+ assert_array_equals(log, ['export-something', 'export-default']);
+ assert_equals(foo, 42);
+ set_foo(43);
+ assert_equals(foo, 43);
+ assert_equals(default1, "fox");
+ assert_equals(default2, "fox");
+}, 'Duplicated imports with the different specifier');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker-importScripts.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker-importScripts.html
new file mode 100644
index 0000000000..817cf6d5dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker-importScripts.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<title>Base URLs used in resolving specifiers in dynamic imports from importScripts()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+fetch_tests_from_worker(new Worker("./worker-importScripts.sub.js"));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker.sub.html
new file mode 100644
index 0000000000..a12204281c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url-worker.sub.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>Base URLs used in resolving specifiers in dynamic imports from workers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+fetch_tests_from_worker(new Worker(
+ "../beta/redirect.py?location=http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js"));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url.sub.html
new file mode 100644
index 0000000000..f7d4927a10
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/base-url.sub.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Base URLs used in resolving specifiers in dynamic imports</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+self.testName = "same origin classic <script>";
+self.baseUrlSanitized = false;
+</script>
+<script src="../beta/redirect.py?location=http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js"></script>
+
+<script>
+self.testName = "cross origin classic <script> without crossorigin attribute";
+self.baseUrlSanitized = true;
+</script>
+<script src="../beta/redirect.py?location=http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js"></script>
+
+<script>
+self.testName = "cross origin classic <script> with crossorigin attribute";
+self.baseUrlSanitized = false;
+</script>
+<script src="../beta/redirect.py?location=http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js%3Fpipe=header(Access-Control-Allow-Origin,*)" crossorigin></script>
+
+<script>
+self.testName = "cross origin module <script>";
+self.baseUrlSanitized = false;
+</script>
+<script src="../beta/redirect.py?location=http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js%3Fpipe=header(Access-Control-Allow-Origin,*)" type="module"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/code-cache.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/code-cache.js
new file mode 100644
index 0000000000..8a8530c9b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/code-cache.js
@@ -0,0 +1,9 @@
+promise_test(() => {
+ return (new Function('w', 'return import(w)'))("./import.js?Function")
+ .then(module => assert_equals(module.A.from, 'alpha/import.js'));
+}, 'alpha - Function');
+
+promise_test(() => {
+ return eval('import("./import.js?eval")')
+ .then(module => assert_equals(module.A.from, 'alpha/import.js'));
+}, 'alpha - eval');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/import.js
new file mode 100644
index 0000000000..b2ac52df2a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/import.js
@@ -0,0 +1 @@
+export const A = { "from": "alpha/import.js" };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/worker-importScripts.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/worker-importScripts.sub.js
new file mode 100644
index 0000000000..904d32f9bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/alpha/worker-importScripts.sub.js
@@ -0,0 +1,15 @@
+"use strict";
+
+importScripts("/resources/testharness.js");
+
+// CORS-same-origin
+self.testName = "same-origin importScripts()";
+self.baseUrlSanitized = false;
+importScripts("../beta/redirect.py?location=http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js");
+
+// CORS-cross-origin
+self.testName = "cross-origin importScripts()";
+self.baseUrlSanitized = true;
+importScripts("../beta/redirect.py?location=http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js");
+
+done();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/code-cache.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/code-cache.js
new file mode 100644
index 0000000000..1c2a2b636a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/code-cache.js
@@ -0,0 +1,9 @@
+promise_test(() => {
+ return (new Function('w', 'return import(w)'))("./import.js?Function")
+ .then(module => assert_equals(module.A.from, 'beta/import.js'));
+}, 'beta - Function');
+
+promise_test(() => {
+ return eval('import("./import.js?eval")')
+ .then(module => assert_equals(module.A.from, 'beta/import.js'));
+}, 'beta - eval');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/import.js
new file mode 100644
index 0000000000..7de1c68182
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/import.js
@@ -0,0 +1 @@
+export const A = { "from": "beta/import.js" };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/redirect.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/redirect.py
new file mode 100644
index 0000000000..f2fd1ebd51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/beta/redirect.py
@@ -0,0 +1,19 @@
+def main(request, response):
+ """Simple handler that causes redirection.
+
+ The request should typically have two query parameters:
+ status - The status to use for the redirection. Defaults to 302.
+ location - The resource to redirect to.
+ """
+ status = 302
+ if b"status" in request.GET:
+ try:
+ status = int(request.GET.first(b"status"))
+ except ValueError:
+ pass
+
+ response.status = status
+
+ location = request.GET.first(b"location")
+
+ response.headers.set(b"Location", location)
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url-workers.window.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url-workers.window.js
new file mode 100644
index 0000000000..70cb20fa57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url-workers.window.js
@@ -0,0 +1,60 @@
+function objectUrlFromModule(module) {
+ const blob = new Blob([module], { type: "text/javascript" });
+ return URL.createObjectURL(blob);
+}
+
+const moduleText = `export const foo = "bar";`;
+
+async_test((t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
+
+ const worker = new Worker("./resources/blob-url-worker.js");
+ worker.postMessage(moduleBlobUrl);
+
+ worker.addEventListener(
+ "message",
+ t.step_func_done((evt) => {
+ assert_true(evt.data.importSucceeded);
+ assert_equals(evt.data.module.foo, "bar");
+ })
+ );
+}, "A blob URL created in a window agent can be imported from a worker");
+
+async_test((t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ URL.revokeObjectURL(moduleBlobUrl);
+
+ const worker = new Worker("./resources/blob-url-worker.js");
+ worker.postMessage(moduleBlobUrl);
+
+ worker.addEventListener(
+ "message",
+ t.step_func_done((evt) => {
+ assert_false(evt.data.importSucceeded);
+ assert_equals(evt.data.errorName, "TypeError");
+ })
+ );
+}, "A blob URL revoked in a window agent will not resolve in a worker");
+
+promise_test(async (t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+
+ await import(moduleBlobUrl);
+
+ URL.revokeObjectURL(moduleBlobUrl);
+
+ const worker = new Worker("./resources/blob-url-worker.js");
+ worker.postMessage(moduleBlobUrl);
+
+ await new Promise((resolve) => {
+ worker.addEventListener(
+ "message",
+ t.step_func((evt) => {
+ assert_false(evt.data.importSucceeded);
+ assert_equals(evt.data.errorName, "TypeError");
+ resolve();
+ })
+ );
+ });
+}, "A revoked blob URL will not resolve in a worker even if it's in the window's module graph");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js
new file mode 100644
index 0000000000..0719a18bf1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js
@@ -0,0 +1,66 @@
+// META: global=window,dedicatedworker,sharedworker,dedicatedworker-module,sharedworker-module
+
+function objectUrlFromModule(module) {
+ const blob = new Blob([module], { type: "text/javascript" });
+ return URL.createObjectURL(blob);
+}
+
+const moduleText = `export const foo = "bar";`;
+
+promise_test(async (t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
+
+ const module = await import(moduleBlobUrl);
+ assert_equals(module.foo, "bar");
+}, "Blob URLs are supported in dynamic imports");
+
+promise_test(async (t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
+
+ const module1 = await import(moduleBlobUrl);
+ const module2 = await import(moduleBlobUrl);
+ assert_equals(module1, module2);
+}, "Identical blob URLs resolve to the same module");
+
+promise_test(async (t) => {
+ const moduleBlob = new Blob([moduleText], { type: "text/javascript" });
+ const moduleBlobUrl1 = URL.createObjectURL(moduleBlob);
+ const moduleBlobUrl2 = URL.createObjectURL(moduleBlob);
+ t.add_cleanup(() => {
+ URL.revokeObjectURL(moduleBlobUrl1);
+ URL.revokeObjectURL(moduleBlobUrl2);
+ });
+
+ const module1 = await import(moduleBlobUrl1);
+ const module2 = await import(moduleBlobUrl2);
+ assert_not_equals(module1, module2);
+}, "Different blob URLs pointing to the same blob resolve to different modules");
+
+promise_test(async (t) => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ URL.revokeObjectURL(moduleBlobUrl);
+
+ await promise_rejects_js(t, TypeError, import(moduleBlobUrl));
+}, "A revoked blob URL will not resolve");
+
+promise_test(async () => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+ const module1 = await import(moduleBlobUrl);
+
+ URL.revokeObjectURL(moduleBlobUrl);
+
+ const module2 = await import(moduleBlobUrl);
+ assert_equals(module1, module2);
+}, "A revoked blob URL will resolve if it's already in the module graph");
+
+promise_test(async () => {
+ const moduleBlobUrl = objectUrlFromModule(moduleText);
+
+ const importPromise = import(moduleBlobUrl);
+ URL.revokeObjectURL(moduleBlobUrl);
+
+ const module = await importPromise;
+ assert_equals(module.foo, "bar");
+}, "Revoking a blob URL immediately after calling import will not fail");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-base-url.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-base-url.html
new file mode 100644
index 0000000000..688a6193a5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-base-url.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<!--
+Regression test for https://crbug.com/990810:
+Functions with the same source code shouldn't be cached if their referencing
+scripts and host defined options are different.
+
+Each Function in the following three scripts should have different base URLs
+respectively, but in https://crbug.com/990810 the Function in
+`gamma/code-cache.js` reuses the Function in `beta/code-cache.js`, resulting in
+wrong base URL.
+-->
+
+<script src="alpha/code-cache.js"></script>
+<script src="beta/code-cache.js"></script>
+<script src="gamma/code-cache.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-nonce.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-nonce.html
new file mode 100644
index 0000000000..bd920f8107
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/code-cache-nonce.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+// Regression test for https://crbug.com/979351:
+// This test loads a same script file (`resources/code-cache-nonce.js`)
+// with three different nonces (i.e. different host defined options).
+// Dynamic imports from the script therefore should have different nonces,
+// but when code caching ignores the difference in nonces, the first nonce
+// ('abc') is reused incorrectly for subsequent dynamic imports, causing
+// CSP violation (and thus dynamic import rejection).
+
+function runTest(nonce, description) {
+ // Perform a dynamic import with nonce=`nonce`
+ // from a page (`iframe`) with a matching CSP script-src 'nonce-`nonce`'.
+ // This should be successful.
+ promise_test(t => {
+ return new Promise((resolve, reject) => {
+ const iframe = document.createElement('iframe');
+ iframe.src = 'resources/code-cache-nonce-iframe.sub.html?nonce=' + nonce;
+ iframe.onload = () => {
+ // `globalThis.promise` is set by `resources/code-cache-nonce.js`.
+ // `t.step_timeout()` is workaround for https://crbug.com/1247801.
+ globalThis.promise.then(
+ v => t.step_timeout(() => resolve(v), 0),
+ v => t.step_timeout(() => reject(v), 0)
+ );
+ };
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ });
+ }, description);
+}
+
+// As `promise_test` are serialized, each iframe is created after previous
+// iframes and scripts are completely loaded.
+runTest('abc', 'First dynamic import should use nonce=abc');
+runTest('def', 'Second dynamic import should use nonce=def');
+runTest('ghi', 'Third dynamic import should use nonce=ghi');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/delay-load-event.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/delay-load-event.html
new file mode 100644
index 0000000000..5ec6433e65
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/delay-load-event.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Dynamic imports don't delay the load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Dynamic imports don't #delay-the-load-event.
+// Therefore, Window load event would be fired
+// just after the dynamic import() below starts.
+window.loaded = [];
+window.addEventListener('load', () => loaded.push('Window load event'));
+promise_test(t => {
+ loaded.push('import start');
+ // This 'loading' log is added to detect the previous Chromium behavior
+ // where the Window load event is delayed until just before script
+ // element's load event.
+ t.step_timeout(() => loaded.push('loading'), 1000);
+ return import("../resources/slow-module.js?pipe=trickle(d2)")
+ .then(() => {
+ assert_array_equals(
+ loaded,
+ ['import start', 'Window load event', 'loading', 'slow'],
+ "Window load event shouldn't be delayed by dynamic imports");
+ });
+}, "Dynamic imports don't delay the load event.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials-setTimeout.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials-setTimeout.sub.html
new file mode 100644
index 0000000000..189aa819fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials-setTimeout.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/dynamic-import-credentials-helper.sub.js"></script>
+
+<script type="text/javascript">
+runTestsFromIframe('../resources/dynamic-import-credentials-setTimeout-iframe.sub.html');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html
new file mode 100644
index 0000000000..910644531c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/dynamic-import-credentials-helper.sub.js"></script>
+
+<script type="text/javascript">
+runTestsFromIframe('../resources/dynamic-import-credentials-iframe.sub.html');
+</script>
+<body>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html
new file mode 100644
index 0000000000..12738c7b97
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-fetch-error.sub.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>import(): error cases occuring during fetching</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script type="module">
+const cases = [
+ ["wrong MIME type", "../errorhandling-wrongMimetype.js?pipe=header(Content-Type,text/plain)"],
+ ["wrong MIME type of a dependency", "../errorhandling-wrongMimetype-import.js"],
+ ["404", "../resources/404-but-js.asis"],
+ ["404 of a dependency", "../resources/imports-404-but-js.js"],
+ ["500", "../resources/500-but-js.asis"],
+ ["500 of a dependency", "../resources/imports-500-but-js.js"],
+ ["cross-origin module (without CORS)", "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/imports-a.js"],
+ ["cross-origin module dependency (without CORS)", "../resources/imports-b-cross-origin.sub.js"]
+];
+
+for (const [label, specifier] of cases) {
+ promise_test(t => {
+ return promise_rejects_js(t, TypeError, import(specifier));
+ }, "import() must reject when there is a " + label);
+
+ promise_test(async t => {
+ // The use of ?x is used to separate tests so they don't interfere with each other.
+ // (However, it shouldn't matter anyway, in a spec-compliant implementation.)
+ const suffix = (specifier.includes("?") ? "&" : "?") + "x";
+ const promise1 = import(specifier + suffix);
+ const promise2 = import(specifier + suffix);
+
+ await promise_rejects_js(t, TypeError, promise1, "It must reject the first time");
+ await promise_rejects_js(t, TypeError, promise2, "It must reject the second time");
+
+ const error1 = await promise1.catch(e => e);
+ const error2 = await promise2.catch(e => e);
+
+ assert_not_equals(error1, error2, "The error objects must be different");
+ }, "import() must reject with a different error object for each import when there is a " + label);
+}
+
+promise_test(async t => {
+ const id = token();
+ const url = `./resources/status-changing-script.py?id=${id}`;
+
+ // Serve HTTP 404 for the first import().
+ await fetch(url + '&newStatus=404');
+ const promise1 = import(url);
+ await promise_rejects_js(t, TypeError, promise1,
+ "First import() must be rejected due to 404");
+
+ // Serve HTTP 200 after the first import() completes.
+ await fetch(url + '&newStatus=200');
+ const r = await fetch(url, { cache: 'no-cache' });
+ assert_equals(r.status, 200);
+
+ const promise2 = import(url);
+ await promise_rejects_js(t, TypeError, promise2,
+ "Second import() must be rejected, because the result of " +
+ "the first import() is cached in the module map");
+}, "import() fetch errors must be cached");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-script-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-script-error.html
new file mode 100644
index 0000000000..e9b10e3bab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-script-error.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<title>import(): error cases caused by the imported module script</title>
+<link rel="author" title="Kouhei Ueno" href="mailto:kouhei@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script type="module">
+const cases = [
+ ["parse error", "../syntaxerror.js", SyntaxError],
+ ["bad module specifier", "does-not-start-with-dot.js", TypeError, { differentErrorObjects: true }],
+ ["bad module specifier in a dependency", "../bad-module-specifier.js", TypeError],
+ ["instantiation error", "../instantiation-error-1.js", SyntaxError, { differentErrorObjects: true }],
+ ["evaluation error", "../throw-error.js", Error]
+];
+
+for (const [label, specifier, error, { differentErrorObjects } = {}] of cases) {
+ promise_test(t => {
+ return promise_rejects_js(t, error, import(specifier));
+ }, "import() must reject when there is a " + label);
+
+ const errorObjectsLabel = differentErrorObjects ? "different error objects" : "the same error object";
+ promise_test(async t => {
+ // The use of ?x is used to separate tests so they don't interfere with each other.
+ // (However, it shouldn't matter anyway, in a spec-compliant implementation.)
+ const promise1 = import(specifier + "?x");
+ const promise2 = import(specifier + "?x");
+
+ await promise_rejects_js(t, error, promise1, "It must reject the first time");
+ await promise_rejects_js(t, error, promise2, "It must reject the second time");
+
+ const error1 = await promise1.catch(e => e);
+ const error2 = await promise2.catch(e => e);
+
+ if (differentErrorObjects) {
+ assert_not_equals(error1, error2, "The error objects must be different");
+ } else {
+ assert_equals(error1, error2, "The error objects must be equal");
+ }
+ }, `import() must reject with ${errorObjectsLabel} for each import when there is a ${label}`);
+}
+
+promise_test(t => {
+ delete window.before_throwing_error;
+ delete window.after_throwing_error;
+
+ return promise_rejects_js(t, Error, import("../throw-error.js?y")).then(() => {
+ assert_true(window.before_throwing_error,
+ "the module script should run to a point where it throws exception");
+ assert_equals(window.after_throwing_error, undefined,
+ "the module script should not run after it throws exception");
+ });
+}, "import()ing a module with an evaluation error must stop evaluation");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports.html
new file mode 100644
index 0000000000..9807e21b0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Basic dynamic imports</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+promise_test(t => {
+ return import("./../imports-a.js").then(module => {
+ assert_true(window.evaluated_imports_a);
+ assert_equals(module.A["from"], "imports-a.js");
+ });
+}, "Dynamic imports should resolve module.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js
new file mode 100644
index 0000000000..ec7784983d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/base-url.sub.js
@@ -0,0 +1,58 @@
+"use strict";
+
+// This script triggers import(), and thus the base URL of this script
+// (either loaded by `<script>` or `importScripts()`) is used as the base URL
+// of resolving relative URL-like specifiers in `import()`.
+
+// The following fields should be set by the callers of this script
+// (unless loaded as the worker top-level script):
+// - self.testName (string)
+// - self.baseUrlSanitized (boolean)
+
+// When this script is loaded as the worker top-level script:
+if ('DedicatedWorkerGlobalScope' in self &&
+ self instanceof DedicatedWorkerGlobalScope &&
+ !self.testName) {
+ importScripts("/resources/testharness.js");
+ self.testName = 'worker top-level script';
+ // Worker top-level scripts are always same-origin.
+ self.baseUrlSanitized = false;
+}
+
+{
+ // This could change by the time the test is executed, so we save it now.
+ // As this script is loaded multiple times, savedBaseUrlSanitized is scoped.
+ const savedBaseUrlSanitized = self.baseUrlSanitized;
+
+ promise_test(() => {
+ const promise = import("./import.js?pipe=header(Access-Control-Allow-Origin,*)&label=relative-" + self.testName);
+ if (savedBaseUrlSanitized) {
+ // The base URL is "about:blank" and thus import() here should fail.
+ return promise.then(module => {
+ // This code should be unreached, but assert_equals() is used here
+ // to log `module.A["from"]` in case of unexpected resolution.
+ assert_equals(module.A["from"], "(unreached)",
+ "Relative URL-like specifier resolution should fail");
+ assert_unreached();
+ },
+ () => {});
+ } else {
+ // The base URL is the response URL of this script, i.e.
+ // `.../gamma/base-url.sub.js`.
+ return promise.then(module => {
+ assert_equals(module.A["from"], "gamma/import.js");
+ });
+ }
+ },
+ "Relative URL-like from " + self.testName);
+}
+
+promise_test(() => {
+ return import("http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/import.js?pipe=header(Access-Control-Allow-Origin,*)&label=absolute-" + self.testName)
+ .then(module => {
+ assert_equals(module.A["from"], "gamma/import.js");
+ })
+ },
+ "Absolute URL-like from " + self.testName);
+
+done();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/code-cache.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/code-cache.js
new file mode 100644
index 0000000000..b470bc8ae5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/code-cache.js
@@ -0,0 +1,9 @@
+promise_test(() => {
+ return (new Function('w', 'return import(w)'))("./import.js?Function")
+ .then(module => assert_equals(module.A.from, 'gamma/import.js'));
+}, 'gamma - Function');
+
+promise_test(() => {
+ return eval('import("./import.js?eval")')
+ .then(module => assert_equals(module.A.from, 'gamma/import.js'));
+}, 'gamma - eval');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/import.js
new file mode 100644
index 0000000000..435c1369be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/gamma/import.js
@@ -0,0 +1 @@
+export const A = { "from": "gamma/import.js" };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/inline-event-handler.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/inline-event-handler.html
new file mode 100644
index 0000000000..13cc8b6624
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/inline-event-handler.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id='div' onmousedown='import("./../imports-a.js").then(window.continueTest);'></div>
+<script>
+const div = document.getElementById('div');
+
+promise_test(t => {
+ const promise = new Promise(resolve => window.continueTest = resolve);
+
+ const event = new MouseEvent('mousedown', {'button': 1});
+ div.dispatchEvent(event);
+
+ return promise.then(() => {
+ assert_true(window.evaluated_imports_a);
+ div.parentNode.removeChild(div);
+ });
+}, "dynamic import should work when triggered from inline event handlers");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.js
new file mode 100644
index 0000000000..82cb3b215d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.js
@@ -0,0 +1,32 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=ticker.js
+
+promise_test(async t => {
+ const getCount = ticker(1000);
+
+ const importP = import("<invalid>");
+ await promise_rejects_js(t, TypeError, importP, 'import() should reject');
+
+ assert_less_than(getCount(), 1000);
+}, "import() should not drain the microtask queue if it fails during specifier resolution");
+
+promise_test(async t => {
+ // Use Date.now() to ensure that the module is not in the module map
+ const specifier = "./empty-module.js?" + Date.now();
+
+ await import(specifier);
+
+ const getCount = ticker(1000);
+ await import(specifier);
+ assert_less_than(getCount(), 1000);
+}, "import() should not drain the microtask queue when loading an already loaded module");
+
+promise_test(async t => {
+ // Use Date.now() to ensure that the module is not in the module map
+ const specifier = "./empty-module.js?" + Date.now();
+
+ const getCount = ticker(1e7);
+ await import(specifier);
+ assert_equals(getCount(), 1e7);
+}, "import() should drain the microtask queue when fetching a new module");
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/css-import-in-worker.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/css-import-in-worker.any.js
new file mode 100644
index 0000000000..bd6f5d092f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/css-import-in-worker.any.js
@@ -0,0 +1,14 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=ticker.js
+
+promise_test(async t => {
+ // Use Date.now() to ensure that the module is not in the module map
+ const specifier = "./empty-module.css?" + Date.now();
+
+ const getCount = ticker(1000);
+
+ const importP = import(specifier, { assert: { type: "css" } });
+ await promise_rejects_js(t, TypeError, importP, 'import() should reject');
+
+ assert_less_than(getCount(), 1000);
+}, "import() should not drain the microtask queue if it fails because of the 'type: css' assertion in a worker");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.css b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.css
new file mode 100644
index 0000000000..108e7649bd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.css
@@ -0,0 +1,4 @@
+/*
+This file is empty, because all it matters is if the
+dynamic import that loads it fails or succedes.
+*/
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.js
new file mode 100644
index 0000000000..108e7649bd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/empty-module.js
@@ -0,0 +1,4 @@
+/*
+This file is empty, because all it matters is if the
+dynamic import that loads it fails or succedes.
+*/
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/serviceworker.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/serviceworker.any.js
new file mode 100644
index 0000000000..4c75cab1b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/serviceworker.any.js
@@ -0,0 +1,14 @@
+// META: global=serviceworker
+// META: script=ticker.js
+
+promise_test(async t => {
+ // Use Date.now() to ensure that the module is not in the module map
+ const specifier = "./empty-module.js?" + Date.now();
+
+ const getCount = ticker(1000);
+
+ const importP = import(specifier);
+ await promise_rejects_js(t, TypeError, importP, 'import() should reject');
+
+ assert_less_than(getCount(), 1000);
+}, "import() should not drain the microtask queue if it fails because it's used in a ServiceWorker");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/ticker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/ticker.js
new file mode 100644
index 0000000000..42619b6e70
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/ticker.js
@@ -0,0 +1,13 @@
+globalThis.ticker = function ticker(max) {
+ let i = 0;
+ let stop = false;
+ Promise.resolve().then(function loop() {
+ if (stop || i >= max) return;
+ i++;
+ Promise.resolve().then(loop);
+ });
+ return () => {
+ stop = true;
+ return i;
+ };
+};
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/with-import-assertions.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/with-import-assertions.any.js
new file mode 100644
index 0000000000..f67ba9a1ae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/with-import-assertions.any.js
@@ -0,0 +1,15 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: script=ticker.js
+
+promise_test(async t => {
+ // Use Date.now() to ensure that the module is not in the module map
+ const specifier = "./empty-module.js?" + Date.now();
+
+ const getCount = ticker(1000);
+
+ const importP = import(specifier, { assert: { type: "<invalid>" } });
+ await promise_rejects_js(t, TypeError, importP, 'import() should reject');
+
+ assert_less_than(getCount(), 1000);
+}, "import() should not drain the microtask queue if it fails while validating the 'type' assertion");
+
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet-ref.https.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet-ref.https.html
new file mode 100644
index 0000000000..6c598aee39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet-ref.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<canvas id ="output" width="100" height="100" style="background: blue;"></canvas>
+<script>
+"use strict";
+const canvas = document.getElementById('output');
+const ctx = canvas.getContext('2d');
+
+ctx.fillStyle = 'green';
+ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet.https.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet.https.html
new file mode 100644
index 0000000000..5cd59f86dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/worklet.https.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://html.spec.whatwg.org/#hostimportmoduledynamically(referencingscriptormodule,-specifier,-promisecapability)">
+<link rel="match" href="worklet-ref.https.html">
+<style>
+#output {
+ width: 100px;
+ height: 100px;
+ background-image: paint(rects);
+ background-color: blue;
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<body>
+<div id="output"></div>
+
+<script id="code" type="text/worklet">
+registerPaint('rects', class {
+ async paint(ctx, geom) {
+ ctx.fillStyle = 'red';
+
+ const getCount = ticker(1000);
+
+ try {
+ // Use Date.now() to ensure that the module is not in the module map
+ await import("./empty-module.js?" + Date.now());
+ } catch (e) {
+ if (getCount() < 1000) {
+ ctx.fillStyle = 'green';
+ }
+ }
+ ctx.fillRect(0, 0, geom.width, geom.height);
+ }
+});
+</script>
+
+<script>
+"use strict";
+CSS.paintWorklet.addModule("./ticker.js").then(() =>
+ importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent)
+);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-classic-manual.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-classic-manual.html
new file mode 100644
index 0000000000..b01f595c03
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-classic-manual.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Dynamic import when there is no active script</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/4181">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<p>Click these buttons in sequence:</p>
+
+<button id="button1">Click me 1</button>
+
+<button id="button2">Click me 2</button>
+
+<p>The result will be pass/fail per the testharness.js results</p>
+
+<!-- We set the attributes from a separate script to specifically make
+ sure that it's not that script's base URL that gets used, but instead this page's. -->
+<script src="scripts/no-active-script.js"></script>
+
+<script>
+"use strict";
+setup({ explicit_timeout: true });
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = new Promise((resolve, reject) => {
+ window.continueTest1 = resolve;
+ window.errorTest1 = reject;
+ });
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+}, "onclick that directly imports should successfully import, using page's base URL");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = new Promise((resolve, reject) => {
+ window.continueTest2 = resolve;
+ window.errorTest2 = reject;
+ });
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+}, "onclick that indirectly imports after a task should successfully import, using page's base URL");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-module-manual.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-module-manual.html
new file mode 100644
index 0000000000..359b71d821
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-module-manual.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Dynamic import when there is no active script</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/4181">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<p>Click these buttons in sequence:</p>
+
+<button id="button1">Click me 1</button>
+
+<button id="button2">Click me 2</button>
+
+<p>The result will be pass/fail per the testharness.js results</p>
+
+<!-- We set the attributes from a separate script to specifically make
+ sure that it's not that script's base URL that gets used, but instead this page's. -->
+<script src="scripts/no-active-script.js" type="module"></script>
+
+<script type="module">
+"use strict";
+setup({ explicit_timeout: true });
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = new Promise((resolve, reject) => {
+ window.continueTest1 = resolve;
+ window.errorTest1 = reject;
+ });
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+}, "onclick that directly imports should successfully import, using page's base URL");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = new Promise((resolve, reject) => {
+ window.continueTest2 = resolve;
+ window.errorTest2 = reject;
+ });
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+}, "onclick that indirectly imports after a task should successfully import, using page's base URL");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-classic.html
new file mode 100644
index 0000000000..0958cfbeba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-classic.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct'">
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+<script nonce="correct" src="./propagate-nonce-external.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-module.html
new file mode 100644
index 0000000000..47c422e59c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external-module.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct'">
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+<script type="module" nonce="correct" src="./propagate-nonce-external.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external.js
new file mode 100644
index 0000000000..3b97d2f40e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-external.js
@@ -0,0 +1,7 @@
+// This file is loaded both as a module and as a classic script.
+promise_test(t => {
+ return import("../imports-a.js").then(module => {
+ assert_true(window.evaluated_imports_a);
+ assert_equals(module.A["from"], "imports-a.js");
+ });
+}, "Dynamically imported module should eval when imported from script w/ a valid nonce.");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-classic.html
new file mode 100644
index 0000000000..754110cb5e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-classic.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct'">
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+<script nonce="correct">
+promise_test(t => {
+ return import("./../imports-a.js").then(module => {
+ assert_true(window.evaluated_imports_a);
+ assert_equals(module.A["from"], "imports-a.js");
+ });
+}, "Dynamically imported module should eval when imported from script w/ a valid nonce.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-module.html
new file mode 100644
index 0000000000..f3322773a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/propagate-nonce-inline-module.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct'">
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+<script type="module" nonce="correct">
+promise_test(t => {
+ return import("./../imports-a.js").then(module => {
+ assert_true(window.evaluated_imports_a);
+ assert_equals(module.A["from"], "imports-a.js");
+ });
+}, "Dynamically imported module should eval when imported from script w/ a valid nonce.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/blob-url-worker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/blob-url-worker.js
new file mode 100644
index 0000000000..07071e05ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/blob-url-worker.js
@@ -0,0 +1,11 @@
+self.addEventListener("message", (evt) => {
+ const importModule = import(evt.data);
+ importModule.then(
+ (module) => {
+ self.postMessage({ importSucceeded: true, module: { ...module } });
+ },
+ (error) => {
+ self.postMessage({ importSucceeded: false, errorName: error.name });
+ }
+ );
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce-iframe.sub.html
new file mode 100644
index 0000000000..56f915aac1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce-iframe.sub.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy"
+ content="script-src 'unsafe-eval' 'nonce-{{GET[nonce]}}'">
+<script src="code-cache-nonce.js" nonce="{{GET[nonce]}}"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce.js
new file mode 100644
index 0000000000..e9983fb6cd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/code-cache-nonce.js
@@ -0,0 +1,4 @@
+// Note that the function source text is intentionally different from e.g.
+// ../alpha/code-cache.js to avoid caching Functions between different sets
+// of tests.
+parent.promise = (new Function('x', 'return import(x)'))('../../imports-a.js');
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/empty-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/empty-iframe.html
new file mode 100644
index 0000000000..ad5ab30eda
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/empty-iframe.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <div id="dummy"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/status-changing-script.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/status-changing-script.py
new file mode 100644
index 0000000000..a44d3dd3eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/status-changing-script.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript"),
+ (b"Cache-Control", b"private, no-store")]
+
+ id = request.GET.first(b"id")
+
+ with request.server.stash.lock:
+ status = request.server.stash.take(id)
+ if status is None:
+ status = 200
+
+ new_status = request.GET.first(b"newStatus", None)
+ if new_status is not None:
+ status = int(new_status)
+
+ request.server.stash.put(id, status)
+
+ return status, headers, b""
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache-iframe.sub.html
new file mode 100644
index 0000000000..c3a870b3f1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache-iframe.sub.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta http-equiv="content-security-policy"
+ content="script-src 'nonce-{{GET[nonce]}}'">
+<!--
+base element to make the base URLs of the Document and the script different
+-->
+<base href="../">
+<script src="resources/v8-code-cache.js?pipe=header(Cache-Control,max-age=1000)"
+ nonce="{{GET[nonce]}}" type="{{GET[type]}}"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache.js
new file mode 100644
index 0000000000..1d3e88a51d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/resources/v8-code-cache.js
@@ -0,0 +1,74 @@
+parent.promise = import('../../imports-a.js');
+
+// Padding for triggering V8 Code Cache on Chromium.
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
+// ============================================================================
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/Function.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/Function.js
new file mode 100644
index 0000000000..447e5060b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/Function.js
@@ -0,0 +1,2 @@
+// import()s in a dynamically created function are resolved relative to the script.
+Function(`import('../../imports-a.js?label=' + window.label).then(window.continueTest, window.errorTest)`)();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/eval.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/eval.js
new file mode 100644
index 0000000000..100602733a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/eval.js
@@ -0,0 +1,2 @@
+// import()s in eval are resolved relative to the script.
+eval(`import('../../imports-a.js?label=' + window.label).then(window.continueTest, window.errorTest)`);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/inline-event-handlers-UA-code.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/inline-event-handlers-UA-code.js
new file mode 100644
index 0000000000..3202ce47b9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/inline-event-handlers-UA-code.js
@@ -0,0 +1,3 @@
+// import()s in an event handler are resolved relative to the document base.
+window.dummyDiv.setAttribute("onclick", `import('./imports-a.js?label=' + window.label).then(window.continueTest, window.errorTest)`);
+window.dummyDiv.click(); // different from **on**click()
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/no-active-script.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/no-active-script.js
new file mode 100644
index 0000000000..85d8ac29ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/no-active-script.js
@@ -0,0 +1,5 @@
+"use strict";
+
+document.querySelector("#button1").setAttribute("onclick", "import('../imports-a.js?label=button1').then(window.continueTest1, window.errorTest1)");
+
+document.querySelector("#button2").setAttribute("onclick", "Promise.resolve(`import('../imports-a.js?label=button2')`).then(eval).then(window.continueTest2, window.errorTest2);");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/reflected-inline-event-handlers.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/reflected-inline-event-handlers.js
new file mode 100644
index 0000000000..923eb7d8b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/reflected-inline-event-handlers.js
@@ -0,0 +1,3 @@
+// import()s in an event handler are resolved relative to the document base.
+window.dummyDiv.setAttribute("onclick", `import('./imports-a.js?label=' + window.label).then(window.continueTest, window.errorTest)`);
+window.dummyDiv.onclick();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/setTimeout.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/setTimeout.js
new file mode 100644
index 0000000000..342b342e8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/scripts/setTimeout.js
@@ -0,0 +1,2 @@
+// import()s in a timeout handler are resolved relative to the script.
+setTimeout(`import('../../imports-a.js?label=' + window.label).then(window.continueTest, window.errorTest)`, 0);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html
new file mode 100644
index 0000000000..855705e585
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the script base URL inside a classic script that is loaded from a file</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<base href="scripts/foo/">
+<script>
+// Tweak the base URL of the document here to distinguish:
+// - document URL
+// - document base URL = ../
+// - External scripts' base URL = ./scripts/eval.js etc.
+// - This inline script's base URL = ./scripts/foo/
+document.querySelector("base").remove();
+const base = document.createElement("base");
+base.setAttribute("href", "../");
+document.body.appendChild(base);
+
+function load(scriptSrc) {
+ const el = document.createElement("script");
+ el.src = scriptSrc;
+ document.body.appendChild(el);
+}
+
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ delete window.label;
+
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+window.dummyDiv = document.querySelector("#dummy");
+
+const evaluators = [
+ "setTimeout",
+ "eval",
+ "Function",
+ "reflected-inline-event-handlers",
+ "inline-event-handlers-UA-code"
+];
+
+for (const label of evaluators) {
+ promise_test(() => {
+ const promise = createTestPromise();
+
+ window.label = label;
+ load(`dynamic-import/scripts/${label}.js`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html
new file mode 100644
index 0000000000..d90af9c96a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the script base URL inside a module script that is loaded from a file</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<base href="scripts/foo/">
+<script type="module">
+// Tweak the base URL of the document here to distinguish:
+// - document URL
+// - document base URL = ../
+// - External scripts' base URL = ./scripts/eval.js etc.
+// - This inline script's base URL = ./scripts/foo/
+document.querySelector("base").remove();
+const base = document.createElement("base");
+base.setAttribute("href", "../");
+document.body.appendChild(base);
+
+function load(scriptSrc) {
+ const el = document.createElement("script");
+ el.type = "module";
+ el.src = scriptSrc;
+ document.body.appendChild(el);
+}
+
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ delete window.label;
+
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+window.dummyDiv = document.querySelector("#dummy");
+
+const evaluators = [
+ "setTimeout",
+ "eval",
+ "Function",
+ "reflected-inline-event-handlers",
+ "inline-event-handlers-UA-code"
+];
+
+for (const label of evaluators) {
+ promise_test(() => {
+ const promise = createTestPromise();
+
+ window.label = label;
+ load(`dynamic-import/scripts/${label}.js`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html
new file mode 100644
index 0000000000..2fe1f75535
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the script base URL (= document base URL) inside an inline classic script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<div id="dummy"></div>
+
+<base href="scripts/foo/">
+<script>
+// Tweak the base URL of the document here to distinguish:
+// - document URL
+// - document base URL = ../
+// - This inline script's base URL = ./scripts/foo/
+document.querySelector("base").remove();
+const base = document.createElement("base");
+base.setAttribute("href", "../");
+document.body.appendChild(base);
+
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+const dummyDiv = document.querySelector("#dummy");
+
+function doTest(label, evaluator, path) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('${path}/imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+}
+
+// Inline script's base URL should be used.
+doTest("setTimeout", setTimeout, "../../..");
+doTest("eval", eval, "../../..");
+doTest("the Function constructor",
+ (x) => {
+ Function(x)();
+ },
+ "../../..");
+
+// Document's base URL should be used, as there are no active scripts.
+doTest("reflected inline event handlers",
+ (x) => {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.onclick();
+ },
+ ".");
+
+doTest("inline event handlers triggered via UA code",
+ (x) => {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.click(); // different from .**on**click()
+ },
+ ".");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html
new file mode 100644
index 0000000000..1691550ecb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the script base URL (= document base URL) inside an inline module script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<div id="dummy"></div>
+
+<base href="scripts/foo/">
+<script type="module">
+// Tweak the base URL of the document here to distinguish:
+// - document URL
+// - document base URL = ../
+// - This inline script's base URL = ./scripts/foo/
+document.querySelector("base").remove();
+const base = document.createElement("base");
+base.setAttribute("href", "../");
+document.body.appendChild(base);
+
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+const dummyDiv = document.querySelector("#dummy");
+
+function doTest(label, evaluator, path) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('${path}/imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+}
+
+// Inline script's base URL should be used.
+doTest("setTimeout", setTimeout, "../../..");
+doTest("eval", eval, "../../..");
+doTest("the Function constructor",
+ (x) => {
+ Function(x)();
+ },
+ "../../..");
+
+// Document's base URL should be used, as there are no active scripts.
+doTest("reflected inline event handlers",
+ (x) => {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.onclick();
+ },
+ ".");
+
+doTest("inline event handlers triggered via UA code",
+ (x) => {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.click(); // different from .**on**click()
+ },
+ ".");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-classic.html
new file mode 100644
index 0000000000..34ea00abc8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-classic.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings inside a classic script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<script>
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+const dummyDiv = document.querySelector("#dummy");
+
+const evaluators = {
+ eval,
+ setTimeout,
+ "the Function constructor"(x) {
+ Function(x)();
+ },
+ "reflected inline event handlers"(x) {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.onclick();
+ },
+ "inline event handlers triggered via UA code"(x) {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.click(); // different from .**on**click()
+ }
+};
+
+for (const [label, evaluator] of Object.entries(evaluators)) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-module.html
new file mode 100644
index 0000000000..b85d446d8d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-module.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings inside a module script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<script type="module">
+function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+const dummyDiv = document.querySelector("#dummy");
+
+const evaluators = {
+ eval,
+ setTimeout,
+ "the Function constructor"(x) {
+ Function(x)();
+ },
+ "reflected inline event handlers"(x) {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.onclick();
+ },
+ "inline event handlers triggered via UA code"(x) {
+ dummyDiv.setAttribute("onclick", x);
+ dummyDiv.click(); // different from .**on**click()
+ }
+};
+
+for (const [label, evaluator] of Object.entries(evaluators)) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ delete window.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html
new file mode 100644
index 0000000000..b582eba8b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the appropriate nonce inside a classic script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
+
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<script nonce="correct">
+"use strict";
+const dummyDiv = document.querySelector("#dummy");
+
+function createTestPromise(t) {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ delete window.unreached;
+ delete window.continueTest;
+ delete window.errorTest;
+ });
+
+ return new Promise((resolve, reject) => {
+ window.unreached = t.unreached_func("Must not reach this");
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+function assertSuccessful(module) {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+}
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ setTimeout(`import('../imports-a.js?label=setTimeout').then(window.continueTest, window.errorTest)`, 0);
+
+ return promise.then(assertSuccessful);
+}, "setTimeout must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ eval(`import('../imports-a.js?label=direct eval').then(window.continueTest, window.errorTest)`);
+
+ return promise.then(assertSuccessful);
+}, "direct eval must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ const evalAlias = eval;
+ evalAlias(`import('../imports-a.js?label=indirect eval').then(window.continueTest, window.errorTest)`);
+
+ return promise.then(assertSuccessful);
+}, "indirect eval must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ Function(`import('../imports-a.js?label=the Function constructor').then(window.continueTest, window.errorTest)`)();
+
+ return promise.then(assertSuccessful);
+}, "the Function constructor must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ });
+
+ const promise = createTestPromise(t);
+
+ // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
+ dummyDiv.setAttribute(
+ "onclick",
+ `import('../imports-a.js?label=reflected inline event handlers').then(window.continueTest, window.errorTest)`
+ );
+ dummyDiv.onclick();
+
+ return promise_rejects_js(t, TypeError, promise);
+}, "reflected inline event handlers must not inherit the nonce from the triggering script, thus fail");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ });
+
+ const promise = createTestPromise(t);
+
+ // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
+ dummyDiv.setAttribute(
+ "onclick",
+ `import('../imports-a.js?label=inline event handlers triggered via UA code').then(window.continueTest, window.errorTest)`
+ );
+ assert_equals(typeof dummyDiv.onclick, "function", "the browser must be able to parse a string containing the import() syntax into a function");
+ dummyDiv.click(); // different from **on**click()
+
+ return promise_rejects_js(t, TypeError, promise);
+}, "inline event handlers triggered via UA code must not inherit the nonce from the triggering script, thus fail");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html
new file mode 100644
index 0000000000..4fa1cc5877
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings uses the appropriate nonce inside a module script</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
+
+<script nonce="correct" src="/resources/testharness.js"></script>
+<script nonce="correct" src="/resources/testharnessreport.js"></script>
+
+<div id="dummy"></div>
+
+<script type="module" nonce="correct">
+const dummyDiv = document.querySelector("#dummy");
+
+function createTestPromise(t) {
+ t.add_cleanup(() => {
+ delete window.evaluated_imports_a;
+ delete window.unreached;
+ delete window.continueTest;
+ delete window.errorTest;
+ });
+
+ return new Promise((resolve, reject) => {
+ window.unreached = t.unreached_func("Must not reach this");
+ window.continueTest = resolve;
+ window.errorTest = reject;
+ });
+}
+
+function assertSuccessful(module) {
+ assert_true(window.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+}
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ setTimeout(`import('../imports-a.js?label=setTimeout').then(window.continueTest, window.errorTest)`, 0);
+
+ return promise.then(assertSuccessful);
+}, "setTimeout must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ eval(`import('../imports-a.js?label=direct eval').then(window.continueTest, window.errorTest)`);
+
+ return promise.then(assertSuccessful);
+}, "direct eval must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ const evalAlias = eval;
+ evalAlias(`import('../imports-a.js?label=indirect eval').then(window.continueTest, window.errorTest)`);
+
+ return promise.then(assertSuccessful);
+}, "indirect eval must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ const promise = createTestPromise(t);
+
+ Function(`import('../imports-a.js?label=the Function constructor').then(window.continueTest, window.errorTest)`)();
+
+ return promise.then(assertSuccessful);
+}, "the Function constructor must inherit the nonce from the triggering script, thus execute");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ });
+
+ const promise = createTestPromise(t);
+
+ // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
+ dummyDiv.setAttribute(
+ "onclick",
+ `import('../imports-a.js?label=reflected inline event handlers').then(window.continueTest, window.errorTest)`
+ );
+ dummyDiv.onclick();
+
+ return promise_rejects_js(t, TypeError, promise);
+}, "reflected inline event handlers must not inherit the nonce from the triggering script, thus fail");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ dummyDiv.removeAttribute("onclick");
+ });
+
+ const promise = createTestPromise(t);
+
+ // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
+ dummyDiv.setAttribute(
+ "onclick",
+ `import('../imports-a.js?label=inline event handlers triggered via UA code').then(window.continueTest, window.errorTest)`
+ );
+ assert_equals(typeof dummyDiv.onclick, 'function', "the browser must be able to parse a string containing the import() syntax into a function");
+ dummyDiv.click(); // different from **on**click()
+
+ return promise_rejects_js(t, TypeError, promise);
+}, "inline event handlers triggered via UA code must not inherit the nonce from the triggering script, thus fail");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html
new file mode 100644
index 0000000000..5514049c78
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-of-promise-result.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>import() inside compiled strings inside a classic script</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/3163">
+<link rel="help" href="https://github.com/tc39/ecma262/issues/871#issuecomment-292493142">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<base href="scripts/foo/">
+<script>
+"use strict";
+
+// This test is based on the current specification, but all browser
+// implementations aren't conformant. See
+// https://bugs.chromium.org/p/chromium/issues/detail?id=1245063
+// https://github.com/heycam/webidl/pull/902
+
+// Tweak the base URL of the document here to distinguish:
+// - document URL
+// - document base URL = ../
+// - This inline script's base URL = ./scripts/foo/
+document.querySelector("base").remove();
+const base = document.createElement("base");
+base.setAttribute("href", "../");
+document.body.appendChild(base);
+
+self.ran = false;
+
+// The active script for the dynamic import is this inline script
+// (see https://html.spec.whatwg.org/C/#hostmakejobcallback).
+promise_test(t => {
+ t.add_cleanup(() => {
+ self.ran = false;
+ })
+
+ return Promise.resolve(`import("../../../imports-a.js?1").then(() => { self.ran = true; })`)
+ .then(eval)
+ .then(() => {
+ assert_true(self.ran);
+ });
+}, "Evaled the script via eval, successful import");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ self.ran = false;
+ })
+
+ return Promise.resolve(`import("bad-specifier?1").catch(() => { self.ran = true; })`)
+ .then(eval)
+ .then(() => {
+ assert_true(self.ran);
+ });
+}, "Evaled the script via eval, failed import");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ self.ran = false;
+ })
+
+ return Promise.resolve(`return import("../../../imports-a.js?2").then(() => { self.ran = true; })`)
+ .then(Function)
+ .then(Function.prototype.call.bind(Function.prototype.call))
+ .then(() => {
+ assert_true(self.ran);
+ });
+}, "Evaled the script via Function, successful import");
+
+promise_test(t => {
+ t.add_cleanup(() => {
+ self.ran = false;
+ })
+
+ return Promise.resolve(`return import("bad-specifier?2").catch(() => { self.ran = true; })`)
+ .then(Function)
+ .then(Function.prototype.call.bind(Function.prototype.call))
+ .then(() => {
+ assert_true(self.ran);
+ });
+}, "Evaled the script via Function, failed import");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-other-document.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-other-document.html
new file mode 100644
index 0000000000..3b1d98f6b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-other-document.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check import() works when active script is in another document</title>
+<link rel="author" title="Jon Coppeard" href="mailto:jcoppeard@mozilla.com">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<iframe id="frame" src="resources/empty-iframe.html"></iframe>
+
+<script>
+
+function startTest() {
+ const otherWindow = document.getElementById("frame").contentWindow;
+ const otherDiv = otherWindow.document.getElementById("dummy");
+
+ function createTestPromise() {
+ return new Promise((resolve, reject) => {
+ otherWindow.continueTest = resolve;
+ otherWindow.errorTest = reject;
+ });
+ }
+
+ const evaluators = {
+ eval: otherWindow.eval,
+ setTimeout: otherWindow.setTimeout,
+ "the Function constructor"(x) {
+ otherWindow.Function(x)();
+ },
+ };
+
+ for (const [label, evaluator] of Object.entries(evaluators)) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ otherDiv.removeAttribute("onclick");
+ delete otherWindow.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(otherWindow.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+ };
+
+ const eventHandlerEvaluators = {
+ "reflected inline event handlers"(x) {
+ otherDiv.setAttribute("onclick", x);
+ otherDiv.onclick();
+ },
+ "inline event handlers triggered by JS"(x) {
+ otherDiv.setAttribute("onclick", x);
+ otherDiv.click(); // different from .**on**click()
+ }
+ };
+
+ for (const [label, evaluator] of Object.entries(eventHandlerEvaluators)) {
+ promise_test(t => {
+ t.add_cleanup(() => {
+ otherDiv.removeAttribute("onclick");
+ delete otherWindow.evaluated_imports_a;
+ });
+
+ const promise = createTestPromise();
+
+ evaluator(`import('../../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
+
+ return promise.then(module => {
+ assert_true(otherWindow.evaluated_imports_a, "The module must have been evaluated");
+ assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
+ });
+ }, label + " should successfully import");
+ };
+}
+</script>
+<body onLoad="startTest()"></body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/v8-code-cache.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/v8-code-cache.html
new file mode 100644
index 0000000000..77de19e74b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/dynamic-import/v8-code-cache.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+// Regression test for https://crbug.com/1244145:
+// This test loads a same script file (`resources/v8-code-cache.js`)
+// multiple times to trigger V8 Code Cache.
+// Host defined options (including base URLs and nonces) are lost when the
+// script is compiled using the cached metadata, and thus causing
+// dynamic import failures due to wrong base URLs and wrong nonces.
+
+function runTest(type, nonce, description) {
+ promise_test(t => {
+ return new Promise((resolve, reject) => {
+ const iframe = document.createElement('iframe');
+ iframe.src = 'resources/v8-code-cache-iframe.sub.html?nonce=' + nonce + '&type=' + type;
+ iframe.onload = () => {
+ // `window.promise` is set by `resources/v8-code-cache.js`.
+ window.promise.then(resolve, reject);
+ };
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ });
+ }, type + ': ' + description);
+}
+
+// As `promise_test` are serialized, each iframe is created after previous
+// iframes and scripts are completely loaded.
+for (const type of ['text/javascript', 'module']) {
+ // Cache the script in V8 Code Cache by running multiple times.
+ runTest(type, 'abc', 'Run #1');
+ runTest(type, 'abc', 'Run #2');
+ runTest(type, 'abc', 'Run #3');
+ runTest(type, 'abc', 'Run #4');
+ // Changing the nonce seems to disable compilation cache, trigger compilation
+ // using V8 Code Cache and thus expose the bug.
+ runTest(type, 'def', 'Run #5');
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html
new file mode 100644
index 0000000000..f336276f3f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-and-slow-dependency.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Module importing syntax error script and slow script should not crash UA</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+setup({allow_uncaught_exception: true});
+window.log = [];
+window.loaded = false;
+</script>
+<script type="module">
+import "./syntaxerror.js";
+import "./resources/delayed-modulescript.py";
+
+window.loaded = true;
+</script>
+<script type="module">
+test(() => {
+ assert_false(loaded);
+ }, "module graph with a syntax error should not evaulate but should not crash UA.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html
new file mode 100644
index 0000000000..2480a60d6d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Handling of different types of errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "network error has higher priority than parse error");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 3);
+
+ // A parse error is reported for the first top-level
+ // <script> element for syntaxerror.js.
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1], 1);
+
+ // onerror is called (with no errors reported) due to a network error
+ // for the second top-level <script>.
+ assert_equals(log[2], 2);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./syntaxerror.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./error-type-1.js"
+ onerror="log.push(2)" onload="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.js
new file mode 100644
index 0000000000..4882d3f2a5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.js
@@ -0,0 +1,2 @@
+import './syntaxerror.js';
+import './404.js';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html
new file mode 100644
index 0000000000..673bf28ca2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Handling of different types of errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "parse error has higher priority than instantiation error");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4);
+
+ // An instantiation error is reported for the first top-level
+ // <script> element for instantiation-error-1.js.
+ assert_equals(log[0].constructor, SyntaxError);
+ assert_equals(log[1], 1);
+
+ // A parse error is reported for the second top-level <script>.
+ assert_equals(log[2].constructor, SyntaxError);
+ assert_equals(log[3], 2);
+ assert_not_equals(log[0], log[2]);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./instantiation-error-1.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./error-type-2.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.js
new file mode 100644
index 0000000000..6b11397300
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.js
@@ -0,0 +1,2 @@
+import './instantiation-error-1.js';
+import './syntaxerror.js';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html
new file mode 100644
index 0000000000..8a16266f4c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Handling of different types of errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "instantiation error has higher priority than evaluation error");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 5);
+
+ // An evaluation error is reported for the first top-level
+ // <script> element for throw.js.
+ assert_equals(log[0], 'throw');
+ assert_true(log[1].foo);
+ assert_equals(log[2], 1);
+
+ // An instantiation error is reported for the second top-level <script>.
+ assert_equals(log[3].constructor, SyntaxError);
+ assert_equals(log[4], 2);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./throw.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./error-type-3.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.js
new file mode 100644
index 0000000000..542be52846
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.js
@@ -0,0 +1,2 @@
+import './throw.js';
+import './instantiation-error-1.js';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-common.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-common.js
new file mode 100644
index 0000000000..4eb5597a58
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-common.js
@@ -0,0 +1,10 @@
+function errorHandler(ev)
+{
+ document._errorReported.push("error");
+}
+
+document._errorReported = [];
+window.addEventListener("error", errorHandler);
+window.addEventListener("load", function () {
+ document._errorReported = document._errorReported.join(",");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.html
new file mode 100644
index 0000000000..3a00f62f00
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-errorHandling-parseError-Dependent</title>
+ <script src="errorhandling-parseerror-common.js"></script>
+</head>
+<body>
+ <script type="module" onerror="errorHandler(event);">
+
+ // No parse errors in the root module, just in the dependent module
+ import test from "./errorhandling-parseerror-dependent.js";
+ document._errorReported = "shouldn't have run dependent module";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.js
new file mode 100644
index 0000000000..71872c47cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependent.js
@@ -0,0 +1,2 @@
+// Parse error in a dependent module
+1A
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.html
new file mode 100644
index 0000000000..7775aeabb4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-errorHandling-parseError-DependentMultiple</title>
+ <script src="errorhandling-parseerror-common.js"></script>
+</head>
+<body>
+ <script type="module" onerror="errorHandler(event)">
+
+ // No parse errors in the root module, just in the dependent module
+ import test from "./errorhandling-parseerror-dependentmultiple.js";
+ document._errorReported = "shouldn't have run dependent module";
+
+ </script>
+ <script type="module" onerror="errorHandler(event)">
+
+ // With the broken dependent module already acquired, try to import it
+ // again from another root. This root should be unwound appropriately.
+ import test from "./errorhandling-parseerror-dependentmultiple.js";
+ document._errorReported = "really shouldn't have run dependent module";
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.js
new file mode 100644
index 0000000000..71872c47cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-dependentmultiple.js
@@ -0,0 +1,2 @@
+// Parse error in a dependent module
+1A
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-root.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-root.html
new file mode 100644
index 0000000000..012f3e9b8c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-parseerror-root.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-errorHandling-parseError-Root</title>
+ <script src="errorhandling-parseerror-common.js"></script>
+</head>
+<body>
+ <script type="module">
+
+ // Parse error in a root module
+ 1A
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype-import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype-import.js
new file mode 100644
index 0000000000..286e1a4229
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype-import.js
@@ -0,0 +1,8 @@
+import foo from "./errorhandling-wrongMimetype.js?pipe=header(Content-Type,text/plain)";
+
+// We don't expect this code to run, the import above should fail!
+// If we do run though, don't trigger an error that the testharness
+// might misinterpret as the import itself failing to load.
+
+var A = null;
+export { A };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype.js
new file mode 100644
index 0000000000..373a532445
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling-wrongMimetype.js
@@ -0,0 +1,7 @@
+// This is a plain JavaScript file, but since it will only be accessed with
+// a Content-Type of text/plain and nosniff, it will be seen as invalid.
+// The file itself will have no errors/effects, so if it does actually run,
+// no error will be detected, and the test will fail.
+
+var foo = null;
+export foo; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling.html
new file mode 100644
index 0000000000..cf47465b49
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/errorhandling.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-errorHandling</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+
+ iframe
+ { display: none; }
+
+ </style>
+</head>
+<body>
+ <h1>html-script-module-errorHandling</h1>
+ <iframe id="iframe_parseError_Root" src="errorhandling-parseerror-root.html"></iframe>
+ <iframe id="iframe_parseError_Dependent" src="errorhandling-parseerror-dependent.html"></iframe>
+ <iframe id="iframe_parseError_DependentMultiple" src="errorhandling-parseerror-dependentmultiple.html"></iframe>
+ <script>
+
+ var tests = [
+ { "id": "iframe_parseError_Root", "expected": "error" },
+ { "id": "iframe_parseError_Dependent", "expected": "error" },
+ { "id": "iframe_parseError_DependentMultiple", "expected": "error,error" },
+ ];
+ tests.forEach(function (testObj) {
+ var testHandle = async_test("IFrame test: '" + testObj.id + "'");
+ var testTarget = document.getElementById(testObj.id);
+ testTarget.addEventListener("load", testHandle.step_func(function () {
+ assert_equals(testTarget.contentDocument._errorReported, testObj.expected, "Unexpected _errorReported value");
+ testHandle.done();
+ }));
+ });
+
+ var test_wrongMimetype_root = async_test("External root module with non-script mimetype");
+ var script_wrongMimetype_root = document.createElement("script");
+ script_wrongMimetype_root.type = "module";
+ script_wrongMimetype_root.src = "errorhandling-wrongMimetype.js?pipe=header(Content-Type,text/plain)";
+ script_wrongMimetype_root.addEventListener("error", test_wrongMimetype_root.step_func(function () {
+ test_wrongMimetype_root.done();
+ }));
+ script_wrongMimetype_root.addEventListener("load", test_wrongMimetype_root.step_func(function () {
+ assert_unreached("This script should not have loaded!");
+ }));
+ document.body.appendChild(script_wrongMimetype_root);
+
+ var test_wrongMimetype_import = async_test("Module with imported non-script mimetype");
+ var script_wrongMimetype_import = document.createElement("script");
+ script_wrongMimetype_import.type = "module";
+ script_wrongMimetype_import.src = "errorhandling-wrongMimetype-import.js";
+ script_wrongMimetype_import.addEventListener("error", test_wrongMimetype_import.step_func(function () {
+ test_wrongMimetype_import.done();
+ }));
+ script_wrongMimetype_import.addEventListener("load", test_wrongMimetype_import.step_func(function () {
+ assert_unreached("This script should not have loaded!");
+ }));
+ document.body.appendChild(script_wrongMimetype_import);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html
new file mode 100644
index 0000000000..3f2bb35f4e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Handling of evaluation errors, 1</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Test that exceptions during evaluation lead to error events on " +
+ "window, and that exceptions are remembered.\n");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[1];
+ assert_array_equals(log,
+ ["throw", exn, "load", exn, "load", exn, "load", exn, "load"]);
+ assert_true(exn.foo);
+ }));
+
+ function logLoad() { log.push("load") }
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="throw.js" async onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="throw.js" nomodule onerror="unreachable()"
+ onload="logLoad()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html
new file mode 100644
index 0000000000..4f2b3c5a74
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Handling of evaluation errors, 2</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Test that ill-founded cyclic dependencies cause ReferenceError " +
+ "during evaluation, which leads to error events on window, and that " +
+ "exceptions are remembered.\n");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[1];
+ assert_array_equals(log,
+ ["cycle-tdz-access-a", exn, "load", exn, "load", exn, "load"]);
+ assert_equals(exn.constructor, ReferenceError);
+ }));
+
+ function logLoad() { log.push("load"); }
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="cycle-tdz-access.js" async onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="cycle-tdz-access.js" nomodule onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="cycle-tdz-access.js" onerror="unreachable()"
+ onload="logLoad()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html
new file mode 100644
index 0000000000..9bfb5df2cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Handling of evaluation errors, 3</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Test that exceptions during evaluation lead to error events on " +
+ "window, and that exceptions are remembered.\n");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[1];
+ assert_array_equals(log,
+ ["throw", exn, "load", exn, "load", exn, "load", exn, "load",
+ exn, "load"]);
+ assert_true(exn.foo);
+ }));
+
+ function logLoad() { log.push("load"); }
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw-nested.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw-nested.js" onerror="unreachable()"
+ onload="logLoad()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html
new file mode 100644
index 0000000000..0b4b7d1662
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Handling of evaluation errors, 4</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+ window.addEventListener("onunhandledrejection", unreachable);
+
+ const test_load = async_test(
+ "Test that exceptions during evaluation lead to error events on " +
+ "window, and that exceptions are remembered.\n");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[1];
+ assert_array_equals(log,
+ ["throw", exn, "load", exn, "load", exn, "load", exn, "load",
+ exn, "load"]);
+ assert_true(exn.foo);
+ }));
+
+ function logLoad() { log.push("load"); }
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./throw-nested.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw-nested.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw-nested.js" onerror="unreachable()"
+ onload="logLoad()"></script>
+<script type="module" src="./throw.js" onerror="unreachable()"
+ onload="logLoad()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered2.js
new file mode 100644
index 0000000000..d7115a2ac6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered2.js
@@ -0,0 +1,3 @@
+test_dynamicOrdered.step(function() {
+ assert_execCount(1, 2, "External script element (#1) should have fired second");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered3.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered3.js
new file mode 100644
index 0000000000..c04e101bb8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered3.js
@@ -0,0 +1,3 @@
+test_dynamicOrdered.step(function() {
+ assert_execCount(1, 3, "External script element (#2) should have fired third");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered4.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered4.js
new file mode 100644
index 0000000000..958736a3d8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicordered4.js
@@ -0,0 +1,3 @@
+test_dynamicOrdered.step(function() {
+ assert_execCount(1, 4, "External script element (#3) should have fired fourth");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered1.js
new file mode 100644
index 0000000000..a54cb7a303
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered1.js
@@ -0,0 +1,3 @@
+test_dynamicUnordered1.step(function() {
+ test_dynamicUnordered1.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered2.js
new file mode 100644
index 0000000000..df0cd85421
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-dynamicunordered2.js
@@ -0,0 +1,3 @@
+test_dynamicUnordered2.step(function() {
+ test_dynamicUnordered2.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered2.js
new file mode 100644
index 0000000000..fca73bd9db
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered2.js
@@ -0,0 +1,3 @@
+test_parsedOrdered.step(function() {
+ assert_execCount(0, 2, "External deferred (#1) script element should have fired second");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered4.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered4.js
new file mode 100644
index 0000000000..6435333bb9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedordered4.js
@@ -0,0 +1,3 @@
+test_parsedOrdered.step(function() {
+ assert_execCount(0, 4, "External deferred (#2) script element should have fired fourth");
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered1.js
new file mode 100644
index 0000000000..ea0bb1b486
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered1.js
@@ -0,0 +1,3 @@
+test_parsedUnordered1.step(function() {
+ test_parsedUnordered1.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered2.js
new file mode 100644
index 0000000000..ce219ee0ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder-parsedunordered2.js
@@ -0,0 +1,3 @@
+test_parsedUnordered2.step(function() {
+ test_parsedUnordered2.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder.html
new file mode 100644
index 0000000000..6a7513dc13
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/execorder.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<html>
+<head>
+ <title>html-script-module-execOrder</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+
+ var execCounts = [
+ 0, // test_parsedOrdered
+ 0, // test_dynamicOrdered
+ ];
+ function assert_execCount(set, expected, description)
+ {
+ if (!execCounts[set])
+ {
+ execCounts[set] = 0;
+ }
+ assert_equals(++execCounts[set], expected, description);
+ }
+
+ function create_script(src, opts)
+ {
+ var element = document.createElement("script");
+ element.src = src;
+ element.async = (opts.asyncOrdered ? false : true);
+ element.type = (opts.module ? "module" : "text/javascript");
+ document.body.appendChild(element);
+ }
+
+ </script>
+</head>
+<body>
+ <h1>html-script-module-execOrder</h1>
+ <script>
+
+ /////
+ // Start test_parsedUnordered*
+ /////
+ var test_parsedUnordered1 = async_test("Unordered module script execution (parsed, unordered #1)");
+ var test_parsedUnordered2 = async_test("Unordered module script execution (parsed, unordered #2)");
+ </script>
+ <script type="module" src="execorder-parsedunordered1.js"></script>
+ <script type="module" src="execorder-parsedunordered2.js"></script>
+ <script>
+ /////
+ // End test_parsedUnordered*
+ /////
+
+ /////
+ // Start test_dynamicUnordered*
+ /////
+ var test_dynamicUnordered1 = async_test("Unordered module script execution (dynamic, unordered #1)");
+ var test_dynamicUnordered2 = async_test("Unordered module script execution (dynamic, unordered #2)");
+ create_script("execorder-dynamicunordered1.js", { module: true });
+ create_script("execorder-dynamicunordered2.js", { module: true });
+ /////
+ // End test_dynamicUnordered*
+ /////
+
+ /////
+ // Begin test_parsedOrdered
+ /////
+ var test_parsedOrdered = async_test("Interlaced module/non-module script execution (parsed, async-ordered)");
+ window.addEventListener("load", test_parsedOrdered.step_func(function() {
+ assert_execCount(0, 5, "onload should have fired fifth");
+ test_parsedOrdered.done();
+ }));
+ </script>
+ <script src="execorder-parsedordered2.js" defer></script>
+ <script type="module">
+ test_parsedOrdered.step(function() {
+ assert_execCount(0, 3, "Inline module-typed script element should have fired third");
+ });
+ </script>
+ <script src="execorder-parsedordered4.js" defer></script>
+ <script>
+ test_parsedOrdered.step(function() {
+ assert_execCount(0, 1, "Inline untyped script element should have fired first");
+ });
+ /////
+ // End test_parsedOrdered
+ /////
+
+ /////
+ // Start test_dynamicOrdered
+ /////
+ var test_dynamicOrdered = async_test("Interlaced module/non-module script execution (dynamic, async-ordered)");
+ window.addEventListener("load", test_dynamicOrdered.step_func(function() {
+ assert_execCount(1, 5, "onload should have fired fifth (last)");
+ test_dynamicOrdered.done();
+ }));
+ create_script("execorder-dynamicordered2.js", { asyncOrdered: true, module: false });
+ create_script("execorder-dynamicordered3.js", { asyncOrdered: true, module: true });
+ create_script("execorder-dynamicordered4.js", { asyncOrdered: true, module: false });
+ test_dynamicOrdered.step(function() {
+ assert_execCount(1, 1, "Inline untyped script element should have fired first");
+ });
+ /////
+ // End test_dynamicOrdered
+ /////
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-default.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-default.js
new file mode 100644
index 0000000000..283830ab28
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-default.js
@@ -0,0 +1,2 @@
+log.push("export-default");
+export default "fox";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something-nested.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something-nested.js
new file mode 100644
index 0000000000..ca806eb8b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something-nested.js
@@ -0,0 +1,2 @@
+log.push("export-something-nested");
+export * from "./export-something.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something.js
new file mode 100644
index 0000000000..cf2c3a99fe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/export-something.js
@@ -0,0 +1,3 @@
+log.push("export-something");
+export let foo = 42;
+export function set_foo(x) { foo = x };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-1.html
new file mode 100644
index 0000000000..170bb665ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Handling of fetch errors, 1</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that failure to fetch root leads to error event on script.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["script"]);
+ }));
+</script>
+<script type="module" src="./no-such-file.js" onerror="log.push('script')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.html
new file mode 100644
index 0000000000..9386ce603a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Handling of fetch errors, 2</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that failure to fetch dependency leads to error event on script.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, ["script"]);
+ }));
+</script>
+<script type="module" src="./fetch-error-2.js" onerror="log.push('script')"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.js
new file mode 100644
index 0000000000..20c0ea6402
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/fetch-error-2.js
@@ -0,0 +1,2 @@
+import "./no-such-file.js"
+import "./this.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-dependent.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-dependent.js
new file mode 100644
index 0000000000..cfaeabc47e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-dependent.js
@@ -0,0 +1 @@
+export let importMetaOnDependentModule = import.meta;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-object.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-object.any.js
new file mode 100644
index 0000000000..494e168102
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-object.any.js
@@ -0,0 +1,20 @@
+// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module
+
+test(() => {
+ assert_equals(typeof import.meta, "object");
+ assert_not_equals(import.meta, null);
+}, "import.meta is an object");
+
+test(() => {
+ import.meta.newProperty = 1;
+ assert_true(Object.isExtensible(import.meta));
+}, "import.meta is extensible");
+
+test(() => {
+ for (const name of Reflect.ownKeys(import.meta)) {
+ const desc = Object.getOwnPropertyDescriptor(import.meta, name);
+ assert_equals(desc.writable, true);
+ assert_equals(desc.enumerable, true);
+ assert_equals(desc.configurable, true);
+ }
+}, "import.meta's properties are writable, configurable, and enumerable");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html
new file mode 100644
index 0000000000..214b9bb59c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<!--
+ More extensive tests of import maps and import.meta.resolve() will be
+ located in the import maps test suite. This contains some basic tests plus
+ tests some tricky parts of the import.meta.resolve() algorithm around string
+ conversion which are only testable with import maps.
+-->
+
+<script type="importmap">
+{
+ "imports": {
+ "bare": "https://example.com/",
+ "https://example.com/rewrite": "https://example.com/rewritten",
+
+ "1": "https://example.com/PASS-1",
+ "null": "https://example.com/PASS-null",
+ "undefined": "https://example.com/PASS-undefined",
+ "[object Object]": "https://example.com/PASS-object",
+
+ "./start": "./resources/export-1.mjs",
+ "./resources/export-1.mjs": "./resources/export-2.mjs"
+ }
+}
+</script>
+
+<script type="module">
+test(() => {
+ assert_equals(import.meta.resolve("bare"), "https://example.com/");
+}, "import.meta.resolve() given an import mapped bare specifier");
+
+test(() => {
+ assert_equals(import.meta.resolve("https://example.com/rewrite"), "https://example.com/rewritten");
+}, "import.meta.resolve() given an import mapped URL-like specifier");
+
+test(() => {
+ assert_equals(import.meta.resolve(), "https://example.com/PASS-undefined", "no-arg case");
+
+ assert_equals(import.meta.resolve(1), "https://example.com/PASS-1");
+ assert_equals(import.meta.resolve(null), "https://example.com/PASS-null");
+ assert_equals(import.meta.resolve(undefined), "https://example.com/PASS-undefined");
+
+ // Only toString() methods are consulted by ToString, not valueOf() ones.
+ // So this becomes "[object Object]".
+ assert_equals(import.meta.resolve({ valueOf() { return "./x"; } }), "https://example.com/PASS-object");
+}, "Testing the ToString() step of import.meta.resolve() via import maps");
+
+promise_test(async () => {
+ const one = (await import("./start")).default;
+ assert_equals(one, 1);
+
+ const two = (await import(import.meta.resolve("./start"))).default;
+ assert_equals(two, 2);
+}, "import(import.meta.resolve(x)) can be different from import(x)");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts.html
new file mode 100644
index 0000000000..d2e0f185e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe src="resources/store-import-meta.html"></iframe>
+
+<script type="module">
+import * as otherImportMeta from "./resources/export-import-meta.mjs";
+setup({ explicit_done: true });
+
+window.onload = () => {
+ test(() => {
+ assert_not_equals(frames[0].importMetaURL, import.meta.url,
+ "Precondition check: we've set things up so that the other script has a different import.meta.url");
+
+ const expected = (new URL("resources/x", location.href)).href;
+ assert_equals(frames[0].importMetaResolve("./x"), expected);
+ }, "import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another global's inline script");
+
+ test(() => {
+ const otherFrameImportMetaResolve = frames[0].importMetaResolve;
+
+ document.querySelector("iframe").remove();
+
+ const expected = (new URL("resources/x", location.href)).href;
+ assert_equals(otherFrameImportMetaResolve("./x"), expected);
+ }, "import.meta.resolve still works if its global has been destroyed (by detaching the iframe)");
+
+ test(() => {
+ assert_not_equals(otherImportMeta.url, import.meta.url,
+ "Precondition check: we've set things up so that the other script has a different import.meta.url");
+
+ const expected = (new URL("resources/x", location.href)).href;
+ assert_equals(otherImportMeta.resolve("./x"), expected);
+ }, "import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another module script");
+
+ done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.js
new file mode 100644
index 0000000000..5b8a84efaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.js
@@ -0,0 +1,77 @@
+// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module
+
+import { importMetaOnRootModule, importMetaOnDependentModule }
+ from "./import-meta-root.js";
+
+test(() => {
+ assert_equals(typeof import.meta.resolve, "function");
+ assert_equals(import.meta.resolve.name, "resolve");
+ assert_equals(import.meta.resolve.length, 1);
+ assert_equals(Object.getPrototypeOf(import.meta.resolve), Function.prototype);
+}, "import.meta.resolve is a function with the right properties");
+
+test(() => {
+ assert_false(isConstructor(import.meta.resolve));
+
+ assert_throws_js(TypeError, () => new import.meta.resolve("./x"));
+}, "import.meta.resolve is not a constructor");
+
+test(() => {
+ // See also tests in ./import-meta-resolve-importmap.html.
+
+ assert_equals(import.meta.resolve({ toString() { return "./x"; } }), resolveURL("x"));
+ assert_throws_js(TypeError, () => import.meta.resolve(Symbol("./x")),
+ "symbol");
+ assert_throws_js(TypeError, () => import.meta.resolve(),
+ "no argument (which is treated like \"undefined\")");
+}, "import.meta.resolve ToString()s its argument");
+
+test(() => {
+ assert_equals(import.meta.resolve("./x"), resolveURL("x"),
+ "current module import.meta");
+ assert_equals(importMetaOnRootModule.resolve("./x"), resolveURL("x"),
+ "sibling module import.meta");
+ assert_equals(importMetaOnDependentModule.resolve("./x"), resolveURL("x"),
+ "dependency module import.meta");
+}, "Relative URL-like specifier resolution");
+
+test(() => {
+ assert_equals(import.meta.resolve("https://example.com/"), "https://example.com/",
+ "current module import.meta");
+ assert_equals(importMetaOnRootModule.resolve("https://example.com/"), "https://example.com/",
+ "sibling module import.meta");
+ assert_equals(importMetaOnDependentModule.resolve("https://example.com/"), "https://example.com/",
+ "dependency module import.meta");
+}, "Absolute URL-like specifier resolution");
+
+test(() => {
+ const invalidSpecifiers = [
+ "https://eggplant:b/c",
+ "pumpkins.js",
+ ".tomato",
+ "..zuccini.mjs",
+ ".\\yam.es"
+ ];
+
+ for (const specifier of invalidSpecifiers) {
+ assert_throws_js(TypeError, () => import.meta.resolve(specifier), specifier);
+ }
+}, "Invalid module specifiers");
+
+test(() => {
+ const { resolve } = import.meta;
+ assert_equals(resolve("https://example.com/"), "https://example.com/", "current module import.meta");
+}, "Works fine with no this value");
+
+function resolveURL(urlRelativeToThisTest) {
+ return (new URL(urlRelativeToThisTest, location.href)).href;
+}
+
+function isConstructor(o) {
+ try {
+ new (new Proxy(o, { construct: () => ({}) }));
+ return true;
+ } catch {
+ return false;
+ }
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js
new file mode 100644
index 0000000000..62ec082a8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js
@@ -0,0 +1,2 @@
+export let importMetaOnRootModule = import.meta;
+export { importMetaOnDependentModule } from "./import-meta-dependent.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.any.js
new file mode 100644
index 0000000000..61d96f35af
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.any.js
@@ -0,0 +1,38 @@
+// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module
+
+import { importMetaOnRootModule, importMetaOnDependentModule }
+ from "./import-meta-root.js";
+
+const base = location.href.slice(0, location.href.lastIndexOf('/'));
+
+test(() => {
+ assert_equals(importMetaOnRootModule.url,
+ base + "/import-meta-root.js");
+}, "import.meta.url in a root external script");
+
+test(() => {
+ assert_equals(importMetaOnDependentModule.url,
+ base + "/import-meta-dependent.js");
+}, "import.meta.url in a dependent external script");
+
+
+import { importMetaOnRootModule as hashedImportMetaOnRootModule1,
+ importMetaOnDependentModule as hashedImportMetaOnDependentModule1 }
+ from "./import-meta-root.js#1";
+
+import { importMetaOnRootModule as hashedImportMetaOnRootModule2,
+ importMetaOnDependentModule as hashedImportMetaOnDependentModule2 }
+ from "./import-meta-root.js#2";
+
+test(() => {
+ assert_equals(hashedImportMetaOnRootModule1.url,
+ base + "/import-meta-root.js#1");
+ assert_equals(hashedImportMetaOnRootModule2.url,
+ base + "/import-meta-root.js#2");
+
+ // Must not be affected
+ assert_equals(hashedImportMetaOnDependentModule1.url,
+ base + "/import-meta-dependent.js");
+ assert_equals(hashedImportMetaOnDependentModule2.url,
+ base + "/import-meta-dependent.js");
+}, "import.meta.url when importing the module with different fragments");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html
new file mode 100644
index 0000000000..284a15f2b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module" src="import-meta-url.any.js"></script>
+
+<script type="module">
+const base = location.href.slice(0, location.href.lastIndexOf('/'));
+
+test(() => {
+ assert_equals(import.meta.url, location.href);
+}, "import.meta.url in a root inline script");
+
+for (const workerType of ['DedicatedWorker', 'SharedWorker']) {
+ promise_test(async t => {
+ const worker_request_url =
+ new URL(`postmessage-worker.js?${workerType}`, location);
+ let w;
+ let port;
+ if (workerType === 'DedicatedWorker') {
+ w = new Worker(worker_request_url.href, {type: 'module'});
+ port = w;
+ } else {
+ w = new SharedWorker(worker_request_url.href, {type: 'module'});
+ port = w.port;
+ w.port.start();
+ }
+ w.onerror = t.unreached_func('Worker error');
+ const url = await new Promise(resolve => {
+ port.onmessage = evt => resolve(evt.data);
+ });
+ assert_equals(url, worker_request_url.href);
+ }, `import.meta.url at top-level module ${workerType}`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/postmessage-worker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/postmessage-worker.js
new file mode 100644
index 0000000000..3618137aef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/postmessage-worker.js
@@ -0,0 +1,12 @@
+if ('DedicatedWorkerGlobalScope' in self &&
+ self instanceof DedicatedWorkerGlobalScope) {
+ postMessage(import.meta.url);
+} else if (
+ 'SharedWorkerGlobalScope' in self &&
+ self instanceof SharedWorkerGlobalScope) {
+ self.onconnect = function(e) {
+ const port = e.ports[0];
+ port.start();
+ port.postMessage(import.meta.url);
+ };
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-1.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-1.mjs
new file mode 100644
index 0000000000..aef22247d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-1.mjs
@@ -0,0 +1 @@
+export default 1;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-2.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-2.mjs
new file mode 100644
index 0000000000..842e368a0a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-2.mjs
@@ -0,0 +1 @@
+export default 2;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-import-meta.mjs b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-import-meta.mjs
new file mode 100644
index 0000000000..488ca74c93
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-import-meta.mjs
@@ -0,0 +1,2 @@
+export const url = import.meta.url;
+export const resolve = import.meta.resolve;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/store-import-meta.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/store-import-meta.html
new file mode 100644
index 0000000000..c9751da408
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-meta/resources/store-import-meta.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<script type="module">
+window.importMetaURL = import.meta.url;
+window.importMetaResolve = import.meta.resolve;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-something-namespace.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-something-namespace.js
new file mode 100644
index 0000000000..32d90287d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-something-namespace.js
@@ -0,0 +1,5 @@
+log.push("import-something-namespace");
+log.push(m.foo);
+m.set_foo(43);
+log.push(m.foo);
+import * as m from "./export-something.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html
new file mode 100644
index 0000000000..4911a071a0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/import-subgraph-404.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+import { delayedLoaded } from "./resources/delayed-modulescript.py";
+import { A } from "./404.js";
+window.loadSuccess = delayedLoaded;
+</script>
+<script type="module">
+test(function () {
+ assert_equals(window.loadSuccess, undefined,
+ "module tree w/ its sub graph 404 should fail to load without crashing");
+}, "Import a module graph w/ sub-graph 404.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-a.js
new file mode 100644
index 0000000000..44d1ac96c2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-a.js
@@ -0,0 +1,3 @@
+var A = { "from": "imports-a.js" };
+window.evaluated_imports_a = true;
+export { A };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-b.js
new file mode 100644
index 0000000000..ae194e4d8a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-b.js
@@ -0,0 +1 @@
+export var B = { "from": "imports-b.js" };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-a.js
new file mode 100644
index 0000000000..8bd8526f76
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-a.js
@@ -0,0 +1,2 @@
+import { CycleB } from "./imports-cycle-b.js";
+export var CycleA = "CycleA";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-b.js
new file mode 100644
index 0000000000..218f350c39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle-b.js
@@ -0,0 +1,2 @@
+import { CycleA } from "./imports-cycle-a.js";
+export var CycleB = "CycleB";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle.js
new file mode 100644
index 0000000000..88a77a4d67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-cycle.js
@@ -0,0 +1,6 @@
+import { CycleA } from "./imports-cycle-a.js";
+
+test_importCycle.step(function () {
+ assert_equals(CycleA, "CycleA");
+ test_importCycle.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-a.js
new file mode 100644
index 0000000000..8cb2298e8a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-a.js
@@ -0,0 +1,2 @@
+import { A } from "./imports-a.js";
+export { A as INC_A };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-ab.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-ab.js
new file mode 100644
index 0000000000..b7d84005c5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-ab.js
@@ -0,0 +1,5 @@
+import { A } from "./imports-a.js";
+export { A as INC_AB_A };
+
+import { B } from "./imports-b.js";
+export { B as INC_AB_B };
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-b.js
new file mode 100644
index 0000000000..243b84fdd0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-inc-b.js
@@ -0,0 +1,2 @@
+import { B } from "./imports-b.js";
+export { B as INC_B }; \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self-inner.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self-inner.js
new file mode 100644
index 0000000000..40eca1c8df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self-inner.js
@@ -0,0 +1,2 @@
+import { SelfInner as SelfInnerA } from "./imports-self-inner.js";
+export var SelfInner = "SelfInner";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self.js
new file mode 100644
index 0000000000..05fa60e2dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports-self.js
@@ -0,0 +1,6 @@
+import { SelfInner } from "./imports-self-inner.js";
+
+test_importSelf.step(function () {
+ assert_equals(SelfInner, "SelfInner");
+ test_importSelf.done();
+});
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports.html
new file mode 100644
index 0000000000..ca6900744d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/imports.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>html-script-module-imports</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>html-script-module-imports</h1>
+
+ <script type="module">
+
+ import { A } from "./imports-a.js";
+
+ test(function () {
+ assert_equals(A.from, "imports-a.js", "Unexpected A");
+ }, "Import a simple module");
+
+ </script>
+ <script type="module">
+
+ import { B as B_RENAMED } from "./imports-b.js";
+
+ test(function () {
+ assert_equals(B_RENAMED.from, "imports-b.js", "Unexpected B_RENAMED");
+
+ try
+ {
+ B;
+ assert_unreached("Unexpectedly defined B");
+ }
+ catch (ex)
+ {}
+ }, "Import a simple module, renamed");
+
+ </script>
+ <script type="module">
+
+ import { INC_A } from "./imports-inc-a.js";
+ import { INC_B } from "./imports-inc-b.js";
+ import { INC_AB_A, INC_AB_B } from "./imports-inc-ab.js";
+
+ test(function () {
+ assert_equals(INC_A.from, "imports-a.js", "Unexpected INC_A");
+ assert_equals(INC_B.from, "imports-b.js", "Unexpected INC_A");
+ assert_equals(INC_AB_A.from, "imports-a.js", "Unexpected INC_A");
+ assert_equals(INC_AB_B.from, "imports-b.js", "Unexpected INC_A");
+ assert_equals(INC_A, INC_AB_A, "INC_A and INC_AB_A should be the same");
+ assert_equals(INC_B, INC_AB_B, "INC_B and INC_AB_B should be the same");
+ }, "Import the same module multiple times");
+
+ </script>
+
+ <script>
+ var test_importSelf = async_test("Import a module that validly imports itself");
+ </script>
+ <script type="module" src="imports-self.js"></script>
+
+ <script>
+ var test_importCycle = async_test("Import a module with a valid cyclical module dependency");
+ </script>
+ <script type="module" src="imports-cycle.js"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html
new file mode 100644
index 0000000000..ce88c0a152
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inactive-context-import.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Dynamic import triggered from inactive context should not crash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="container">
+<iframe></iframe>
+</div>
+
+<script>
+test(() => {
+ const iframe = document.querySelector('iframe');
+ const otherWindow = iframe.contentWindow;
+ iframe.remove();
+
+ // Below should not crash
+ otherWindow.eval(`import('foobar');`);
+}, 'dynamic import from inactive context should not crash');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html
new file mode 100644
index 0000000000..db03612e82
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-execorder.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Inline async module script execution order</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+ let loaded = [];
+ let test = async_test("Inline async module script execution order");
+ window.addEventListener("load", test.step_func(function() {
+ assert_array_equals(loaded,
+ ["fast", "fast", "fast", "slow", "slow", "slow"]);
+ test.done();
+ }));
+ </script>
+ <script type="module" async src="resources/slow-module.js?pipe=trickle(d2)&unique=1"></script>
+ <script type="module" async>
+ import "./resources/slow-module.js?pipe=trickle(d2)&unique=2";
+ loaded.push("slow");
+ </script>
+ <script type="module" async src="resources/fast-module.js?unique=1"></script>
+ <script type="module" async>
+ import "./resources/fast-module.js?unique=2";
+ loaded.push("fast");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-onload.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-onload.html
new file mode 100644
index 0000000000..314abc98dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-async-onload.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>Inline async module script without external deps onload blocking</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+ let loadFired = false;
+ let moduleRan = false
+ let test = async_test("Inline async module script vs. onload");
+ window.addEventListener("load", test.step_func(function() {
+ loadFired = true;
+ assert_true(moduleRan, "Module should have run before the load event");
+ test.step_timeout(function() {
+ test.done();
+ }, 0);
+ }));
+ </script>
+ <script type="module" async>
+ moduleRan = true;
+ test.step_func(function() {
+ assert_false(loadFired, "onload should not have fired yet");
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-defer-onload.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-defer-onload.html
new file mode 100644
index 0000000000..0a0bc36f8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-defer-onload.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Inline defer module script without external deps onload blocking</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+ let loadFired = false;
+ let moduleRan = false
+ let test = async_test("Inline defer module script vs. onload");
+ window.addEventListener("load", test.step_func(function() {
+ loadFired = true;
+ assert_true(moduleRan, "Module should have run before the load event");
+ test.step_timeout(function() {
+ test.done();
+ }, 0);
+ }));
+ </script>
+ <!-- defer should be equivalent to neither defer nor async specified -->
+ <script type="module" defer>
+ moduleRan = true;
+ test.step_func(function() {
+ assert_false(loadFired, "onload should not have fired yet");
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-no-async-onload.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-no-async-onload.html
new file mode 100644
index 0000000000..50f42c6a38
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/inline-no-async-onload.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>Inline module script without external deps onload blocking</title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script>
+ let loadFired = false;
+ let moduleRan = false
+ let test = async_test("Inline module script vs. onload");
+ window.addEventListener("load", test.step_func(function() {
+ loadFired = true;
+ assert_true(moduleRan, "Module should have run before the load event");
+ test.step_timeout(function() {
+ test.done();
+ }, 0);
+ }));
+ </script>
+ <script type="module">
+ moduleRan = true;
+ test.step_func(function() {
+ assert_false(loadFired, "onload should not have fired yet");
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.html
new file mode 100644
index 0000000000..57b40f5baa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 1</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ const test_load = async_test(
+ "Test that missing exports lead to SyntaxError events on window and " +
+ "load events on script");
+
+ window.log = [];
+ window.addEventListener("error", ev => {
+ test_load.step(() => assert_equals(ev.error.constructor, SyntaxError));
+ log.push(ev.message);
+ });
+
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const msg = log[0];
+ assert_array_equals(log, [msg, 1, msg, 2, msg, 3, msg, 4, msg, 5]);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./missing-export.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./missing-export.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
+<script type="module" src="./missing-export-nested.js"
+ onerror="unreachable()" onload="log.push(3)"></script>
+<script type="module" src="./missing-export.js"
+ onerror="unreachable()" onload="log.push(4)"></script>
+<script type="module" src="./missing-export-nested.js"
+ onerror="unreachable()" onload="log.push(5)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.js
new file mode 100644
index 0000000000..e317b01cc2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-1.js
@@ -0,0 +1 @@
+import something from "./instantiation-error-1.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-2.html
new file mode 100644
index 0000000000..27ba006fc7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 2</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ const test_load = async_test(
+ "Test that missing exports lead to SyntaxError events on window and " +
+ "load events on script");
+
+ window.log = [];
+ window.addEventListener("error", ev => {
+ test_load.step(() => assert_equals(ev.error.constructor, SyntaxError));
+ log.push(ev.message);
+ });
+
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const msg = log[0];
+ assert_array_equals(log, [msg, 1, msg, 2, msg, 3, msg, 4, msg, 5]);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./missing-export-nested.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./missing-export-nested.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
+<script type="module" src="./missing-export.js"
+ onerror="unreachable()" onload="log.push(3)"></script>
+<script type="module" src="./missing-export-nested.js"
+ onerror="unreachable()" onload="log.push(4)"></script>
+<script type="module" src="./missing-export.js"
+ onerror="unreachable()" onload="log.push(5)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-3.html
new file mode 100644
index 0000000000..32f0a4a243
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 3</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ const test_load = async_test(
+ "Test that unresolvable cycles lead to SyntaxError events on window " +
+ "and load events on script");
+
+ window.log = [];
+ window.addEventListener("error", ev => {
+ test_load.step(() => assert_equals(ev.error.constructor, SyntaxError));
+ log.push(ev.message);
+ });
+
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 6, 'Log length');
+ assert_equals(log[1], 1);
+ assert_equals(log[3], 2);
+ assert_equals(log[5], 3);
+ assert_not_equals(log[0], log[2],
+ 'Instantiation error objects for different root scripts');
+ assert_equals(log[0], log[4],
+ 'Instantiation error objects for the same root script');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./cycle-unresolvable.js"
+ onerror="unreachable()" onload="log.push(1)" nomodule></script>
+<script type="module" src="./cycle-unresolvable-a.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
+<script type="module" src="./cycle-unresolvable.js"
+ onerror="unreachable()" onload="log.push(3)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4.html
new file mode 100644
index 0000000000..8d3f23819a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 4</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+ const test_load = async_test(
+ "Test that loading a graph in which a module is already " +
+ "errored results in an error.");
+
+ window.addEventListener("error", ev => {
+ test_load.step(() => assert_equals(ev.error.constructor, SyntaxError));
+ log.push(ev.message);
+ });
+
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4, 'Log length');
+ assert_equals(log[1], 1);
+ assert_equals(log[3], 2);
+ assert_not_equals(log[0], log[2],
+ 'Instantiation error objects for different root scripts');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./instantiation-error-4a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./instantiation-error-4d.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4a.js
new file mode 100644
index 0000000000..6fed27f1c7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4a.js
@@ -0,0 +1,2 @@
+import "./instantiation-error-4b.js";
+log.push("instantiation-error-4a");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4b.js
new file mode 100644
index 0000000000..4b702cae67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4b.js
@@ -0,0 +1,3 @@
+import "./instantiation-error-4c.js";
+import "./instantiation-error-4d.js";
+log.push("instantiation-error-4b");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4c.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4c.js
new file mode 100644
index 0000000000..ef699f6ca3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4c.js
@@ -0,0 +1,2 @@
+import {something} from "./instantiation-error-4c.js";
+log.push("instantiation-error-4c");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4d.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4d.js
new file mode 100644
index 0000000000..ac04ccb9b3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-4d.js
@@ -0,0 +1,2 @@
+import {something} from "./instantiation-error-4d.js";
+log.push("instantiation-error-4d");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5.html
new file mode 100644
index 0000000000..20df0bb5c9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 5</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ const test_load = async_test(
+ "Test that loading a graph in which a module is already " +
+ "errored results an error.");
+
+ window.log = [];
+ window.addEventListener("error", ev => {
+ test_load.step(() => assert_equals(ev.error.constructor, SyntaxError));
+ log.push(ev.message);
+ });
+
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 4, 'Log length');
+ assert_equals(log[1], 1);
+ assert_equals(log[3], 2);
+ assert_not_equals(log[0], log[2],
+ 'Instantiation error objects for different root scripts');
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./instantiation-error-5a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./instantiation-error-5d.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5a.js
new file mode 100644
index 0000000000..b2e6b106b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5a.js
@@ -0,0 +1,2 @@
+import "./instantiation-error-5b.js";
+log.push("instantiation-error-5a");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5b.js
new file mode 100644
index 0000000000..2d37ae8fff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5b.js
@@ -0,0 +1,3 @@
+import "./instantiation-error-5c.js";
+import "./instantiation-error-5d.js";
+log.push("instantiation-error-5b");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5c.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5c.js
new file mode 100644
index 0000000000..ba221b6fc0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5c.js
@@ -0,0 +1,2 @@
+import {something} from "./instantiation-error-5c.js";
+log.push("instantiation-error-5c");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5d.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5d.js
new file mode 100644
index 0000000000..9775e04f82
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5d.js
@@ -0,0 +1,3 @@
+import "./instantiation-error-5e.js";
+import "./instantiation-error-5a.js";
+log.push("instantiation-error-5d");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5e.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5e.js
new file mode 100644
index 0000000000..8bd3b3c3bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-5e.js
@@ -0,0 +1,2 @@
+import {something} from "./instantiation-error-5e.js";
+log.push("instantiation-error-5e");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6.html
new file mode 100644
index 0000000000..8d3ce121ee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 6</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that ambiguous star exports lead to an instantiation error " +
+ "and that the correct module is blamed.");
+ // Concretely, instantiation-error-6a.js fails to instantiate because it
+ // requests a name from instantion-error-6b.js that is ambiguous there.
+ // instantiation-error-6b.js itself, however, is fine, and it instantiates
+ // and evaluates successfully.
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[0];
+ assert_array_equals(log, [
+ exn, 1,
+ "instantiation-error-6c",
+ "instantiation-error-6d",
+ "instantiation-error-6b", 2
+ ]);
+ assert_equals(exn.constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./instantiation-error-6a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./instantiation-error-6b.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6a.js
new file mode 100644
index 0000000000..4db49c6c46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6a.js
@@ -0,0 +1,2 @@
+import {foo} from "./instantiation-error-6b.js";
+log.push("instantiation-error-6a");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6b.js
new file mode 100644
index 0000000000..35272fe550
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6b.js
@@ -0,0 +1,3 @@
+export * from "./instantiation-error-6c.js";
+export * from "./instantiation-error-6d.js";
+log.push("instantiation-error-6b");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6c.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6c.js
new file mode 100644
index 0000000000..69d616b4ba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6c.js
@@ -0,0 +1,2 @@
+export let foo = "c";
+log.push("instantiation-error-6c");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6d.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6d.js
new file mode 100644
index 0000000000..d1336a57a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-6d.js
@@ -0,0 +1,2 @@
+export let foo = "d";
+log.push("instantiation-error-6d");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7.html
new file mode 100644
index 0000000000..57f1f87216
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 7</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that ambiguous star exports lead to an instantiation error, " +
+ "even when discovered through a star export, and that the correct " +
+ "module is blamed.");
+ // This is a variation of instantiation-error-6.html (see the explanation
+ // there).
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ const exn = log[0];
+ assert_array_equals(log, [
+ exn, 1,
+ "instantiation-error-7d",
+ "instantiation-error-7e",
+ "instantiation-error-7c",
+ "instantiation-error-7f",
+ "instantiation-error-7b", 2
+ ]);
+ assert_equals(exn.constructor, SyntaxError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./instantiation-error-7a.js"
+ onerror="unreachable()" onload="log.push(1)"></script>
+<script type="module" src="./instantiation-error-7b.js"
+ onerror="unreachable()" onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7a.js
new file mode 100644
index 0000000000..d27a44865c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7a.js
@@ -0,0 +1,2 @@
+import {foo} from "./instantiation-error-7b.js";
+log.push("instantiation-error-7a");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7b.js
new file mode 100644
index 0000000000..8c05d3b727
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7b.js
@@ -0,0 +1,3 @@
+export * from "./instantiation-error-7c.js";
+export * from "./instantiation-error-7f.js";
+log.push("instantiation-error-7b");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7c.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7c.js
new file mode 100644
index 0000000000..fff1368034
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7c.js
@@ -0,0 +1,3 @@
+export * from "./instantiation-error-7d.js";
+export * from "./instantiation-error-7e.js";
+log.push("instantiation-error-7c");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7d.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7d.js
new file mode 100644
index 0000000000..fa5e7651f4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7d.js
@@ -0,0 +1,2 @@
+export let foo = "d";
+log.push("instantiation-error-7d");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7e.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7e.js
new file mode 100644
index 0000000000..6547c3fe6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7e.js
@@ -0,0 +1,2 @@
+export let foo = "e";
+log.push("instantiation-error-7e");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7f.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7f.js
new file mode 100644
index 0000000000..7f9ec5d12e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-7f.js
@@ -0,0 +1,2 @@
+export let foo = "f";
+log.push("instantiation-error-7f");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-8.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-8.html
new file mode 100644
index 0000000000..080b170233
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/instantiation-error-8.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Handling of instantiation errors, 8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!-- The below module tree should fail to instantiate, since it references undefined identifier. -->
+<script type="module" src="instantiation-error-1.js"></script>
+<script>
+setup({allow_uncaught_exception: true});
+
+promise_test(t => {
+ return new Promise(resolve => {
+ window.addEventListener("error", e => {
+ assert_equals(e.error.constructor, SyntaxError);
+ resolve();
+ }, { once: true });
+ }).then(() => new Promise(resolve => {
+ window.addEventListener("error", e => {
+ assert_equals(e.error.constructor, SyntaxError);
+ resolve();
+ }, { once: true });
+ // Load another module tree w/ previously instantiate-failed tree as its sub-tree.
+ document.head.appendChild(Object.assign(
+ document.createElement('script'),
+ { type: 'module', innerText: 'import "./instantiation-error-1.js"'}));
+ }));
+}, "Instantiate attempt on a tree w/ previously instantiate-failed tree as a sub-tree shouldn't crash.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js
new file mode 100644
index 0000000000..369b3e7827
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches-inner.js
@@ -0,0 +1 @@
+window.matchesLog.push("integrity-matches-inner");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches.js
new file mode 100644
index 0000000000..d8c4219e90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-matches.js
@@ -0,0 +1,2 @@
+import "./integrity-matches-inner.js";
+window.matchesLog.push("integrity-matches");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches-inner.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches-inner.js
new file mode 100644
index 0000000000..8182d4de16
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches-inner.js
@@ -0,0 +1 @@
+window.mismatchesLog.push("integrity-mismatches-inner");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches.js
new file mode 100644
index 0000000000..2d47344a5a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import "./integrity-mismatches-inner.js";
+window.mismatchesLog.push("integrity-mismatches");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity.html
new file mode 100644
index 0000000000..c79843624f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/integrity.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity=""</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.inlineRan = false;
+
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+
+<script type="module" integrity="sha384-garbage">
+window.inlineRan = true;
+</script>
+
+<script type="module" src="integrity-matches.js" integrity="sha384-1/XwTy38IAlmvk1O674Efus1/REqfuX6x0V/B2/GX5R3lNbRjhrIwlWyEDPyOwpN" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+ assert_true(window.inlineRan);
+}, "The integrity attribute must have no affect on inline module scripts");
+
+test(() => {
+ assert_array_equals(window.matchesLog, ["integrity-matches-inner", "integrity-matches"], "The module and its dependency must have executed");
+ assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module and allow it to execute when it matches");
+
+test(() => {
+ assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+ assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-namespace-request.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-namespace-request.html
new file mode 100644
index 0000000000..00269efdf9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-namespace-request.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Late namespace request</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test the situation where a module is instantiated without the " +
+ "need for a namespace object, but later on a different module " +
+ "requests the namespace.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log,
+ ["export-something",
+ "import-something-namespace", 42, 43]);
+ }));
+</script>
+<script type="module" src="export-something.js"></script>
+<script type="module" src="import-something-namespace.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-star-export-request.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-star-export-request.html
new file mode 100644
index 0000000000..d40bb0aca7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/late-star-export-request.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Late star-export request</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test the situation where a module is instantiated without a use of " +
+ "its star-exports, but later on a different module requests them.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [
+ "export-something", "export-something-nested",
+ "import-something-namespace", 42, 43]);
+ }));
+</script>
+<script type="module" src="export-something-nested.js"></script>
+<script type="module">
+ log.push("import-something-namespace");
+ log.push(foo);
+ set_foo(43);
+ log.push(foo);
+ import {foo, set_foo} from "./export-something-nested.js";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events-inline.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events-inline.html
new file mode 100644
index 0000000000..58397dd07d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events-inline.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for inline module scripts</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+"use strict";
+
+var test1_load = event_test('src, 200, parser-inserted, defer, no async', false, false);
+var test4_load = event_test('src, 200, parser-inserted, no defer, async', false, false);
+
+var test3_dynamic_load = event_test('src, 200, not parser-inserted, no defer, no async, no non-blocking', false, false);
+var test4_dynamic_load = event_test('src, 200, not parser-inserted, no defer, async', false, false);
+
+var test1_error = event_test('src, 404, parser-inserted, defer, no async', false, true);
+var test4_error = event_test('src, 404, parser-inserted, no defer, async', false, true);
+
+var test3_dynamic_error = event_test('src, 404, not parser-inserted, no defer, no async, no non-blocking', false, true);
+var test4_dynamic_error = event_test('src, 404, not parser-inserted, no defer, async', false, true);
+
+var script3_dynamic_load = document.createElement('script');
+script3_dynamic_load.setAttribute('type', 'module');
+script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+script3_dynamic_load.async = false;
+script3_dynamic_load.appendChild(document.createTextNode('onExecute(test3_dynamic_load);'));
+document.head.appendChild(script3_dynamic_load);
+
+var script3_dynamic_error = document.createElement('script');
+script3_dynamic_error.setAttribute('type', 'module');
+script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+script3_dynamic_error.async = false;
+script3_dynamic_error.appendChild(document.createTextNode('import "./not_found.js";'));
+document.head.appendChild(script3_dynamic_error);
+
+var script4_dynamic_load = document.createElement('script');
+script4_dynamic_load.setAttribute('type', 'module');
+script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+script4_dynamic_load.async = true;
+script4_dynamic_load.appendChild(document.createTextNode('onExecute(test4_dynamic_load);'));
+document.head.appendChild(script4_dynamic_load);
+
+var script4_dynamic_error = document.createElement('script');
+script4_dynamic_error.setAttribute('type', 'module');
+script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+script4_dynamic_error.async = true;
+script4_dynamic_error.appendChild(document.createTextNode('import "./not_found.js";'));
+document.head.appendChild(script4_dynamic_error);
+</script>
+
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">"use strict";onExecute(test1_load);</script>
+<script onload="onLoad(test4_load);" onerror="onError(test4_load);" type="module" async>"use strict";onExecute(test4_load);</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">"use strict";import "./not_found.js";</script>
+<script onload="onLoad(test4_error);" onerror="onError(test4_error);" type="module" async>"use strict";import "./not_found.js";</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events.html
new file mode 100644
index 0000000000..d9bf05226c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/load-error-events.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for external module scripts</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+"use strict";
+
+var test1_load = event_test('src, 200, parser-inserted, defer, no async', true, false);
+var test4_load = event_test('src, 200, parser-inserted, no defer, async', true, false);
+
+var test3_dynamic_load = event_test('src, 200, not parser-inserted, no defer, no async, no non-blocking', true, false);
+var test4_dynamic_load = event_test('src, 200, not parser-inserted, no defer, async', true, false);
+
+var test1_error = event_test('src, 404, parser-inserted, defer, no async', false, true);
+var test4_error = event_test('src, 404, parser-inserted, no defer, async', false, true);
+
+var test3_dynamic_error = event_test('src, 404, not parser-inserted, no defer, no async, no non-blocking', false, true);
+var test4_dynamic_error = event_test('src, 404, not parser-inserted, no defer, async', false, true);
+
+var script3_dynamic_load = document.createElement('script');
+script3_dynamic_load.setAttribute('type', 'module');
+script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+script3_dynamic_load.async = false;
+script3_dynamic_load.src = "../resources/load-error-events.py?test=test3_dynamic_load";
+document.head.appendChild(script3_dynamic_load);
+
+var script3_dynamic_error = document.createElement('script');
+script3_dynamic_error.setAttribute('type', 'module');
+script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+script3_dynamic_error.async = false;
+script3_dynamic_error.src = "../resources/load-error-events.py?test=test3_dynamic_error";
+document.head.appendChild(script3_dynamic_error);
+
+var script4_dynamic_load = document.createElement('script');
+script4_dynamic_load.setAttribute('type', 'module');
+script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+script4_dynamic_load.async = true;
+script4_dynamic_load.src = "../resources/load-error-events.py?test=test4_dynamic_load";
+document.head.appendChild(script4_dynamic_load);
+
+var script4_dynamic_error = document.createElement('script');
+script4_dynamic_error.setAttribute('type', 'module');
+script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+script4_dynamic_error.async = true;
+script4_dynamic_error.src = "../resources/load-error-events.py?test=test4_dynamic_error";
+document.head.appendChild(script4_dynamic_error);
+</script>
+
+<script src="../resources/load-error-events.py?test=test1_load" onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module"></script>
+<script src="../resources/load-error-events.py?test=test4_load" onload="onLoad(test4_load);" onerror="onError(test4_load);" type="module" async></script>
+<script src="../resources/load-error-events.py?test=test1_error" onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module"></script>
+<script src="../resources/load-error-events.py?test=test4_error" onload="onLoad(test4_error);" onerror="onError(test4_error);" type="module" async></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export-nested.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export-nested.js
new file mode 100644
index 0000000000..860d2bf341
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export-nested.js
@@ -0,0 +1,2 @@
+import "./missing-export.js";
+log.push("nested-missing-export");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export.js
new file mode 100644
index 0000000000..e6f5746eb7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/missing-export.js
@@ -0,0 +1,2 @@
+import something from "./missing-export.js";
+log.push("missing-export");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.html
new file mode 100644
index 0000000000..7348b88075
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer for module imports</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>setup({ explicit_done: true })</script>
+</head>
+<body>
+<script type="module">
+
+import { referrerExternalStatic, referrerExternalDynamic } from "./module-import-referrer.js";
+
+// "name" parameter is necessary for bypassing the module map.
+import { referrer as referrerInlineStatic } from "./resources/referrer-checker.py?name=internal-static"
+const { referrer: referrerInlineDynamic } = await import("./resources/referrer-checker.py?name=internal-dynamic");
+
+const scriptURL = new URL("module-import-referrer.js", location.href)
+
+test(t => {
+ assert_equals(
+ referrerInlineStatic, location.href,
+ "Referrer should be the document URL");
+}, "Static imports from inline modules in the HTML document");
+
+test(t => {
+ assert_equals(
+ referrerInlineDynamic, location.href,
+ "Referrer should be the document URL");
+}, "Dynamic imports from inline modules in the HTML document");
+
+test(t => {
+ assert_equals(
+ referrerExternalStatic, scriptURL.href,
+ "Referrer should be the importer module URL");
+}, "Static imports from external modules");
+
+test(t => {
+ assert_equals(
+ referrerExternalDynamic, scriptURL.href,
+ "Referrer should be the document URL");
+}, "Dynamic imports from external modules");
+
+done();
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.js
new file mode 100644
index 0000000000..8710f5c621
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-import-referrer.js
@@ -0,0 +1,2 @@
+export { referrer as referrerExternalStatic } from "./resources/referrer-checker.py?name=external-static"
+export const { referrer: referrerExternalDynamic } = await import("./resources/referrer-checker.py?name=external-dynamic");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml
new file mode 100644
index 0000000000..1655e61a7c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+window.evaluated_module_script = true;
+</script>
+<script>
+ var test = async_test("module script in XHTML documents should be evaluated.");
+ window.addEventListener("load", () => {
+ test.step(() => { assert_true(window.evaluated_module_script); });
+ test.done();
+ });
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-1.html
new file mode 100644
index 0000000000..ae82e1348a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-1.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Once as module script, once as classic script</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that evaluating something as classic script does not prevent " +
+ "it from being evaluated as module script.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [window, undefined]);
+ }));
+</script>
+<script type="module" src="this.js"></script>
+<script src="this.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-2.html
new file mode 100644
index 0000000000..fb512b4b30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/module-vs-script-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Once as classic script, once as module script</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that evaluating something as classic script does not prevent " +
+ "it from being evaluated as module script.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [window, undefined]);
+ }));
+</script>
+<script src="this.js"></script>
+<script type="module" src="this.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-a.js
new file mode 100644
index 0000000000..a127aeb559
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-a.js
@@ -0,0 +1 @@
+import { b } from "./nested-imports-b.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-b.js
new file mode 100644
index 0000000000..18a5af40cc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-b.js
@@ -0,0 +1,2 @@
+import { c } from "./nested-imports-c.js";
+export const b = "b";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-c.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-c.js
new file mode 100644
index 0000000000..ec44596aea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-c.js
@@ -0,0 +1,2 @@
+import { d } from "./nested-imports-d.js";
+export const c = "c";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-d.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-d.js
new file mode 100644
index 0000000000..cee87849c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-d.js
@@ -0,0 +1,3 @@
+import { e } from "./nested-imports-e.js";
+import "./resources/delayed-modulescript.py";
+export const d = "d";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-e.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-e.js
new file mode 100644
index 0000000000..ec6f0360a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-e.js
@@ -0,0 +1,2 @@
+import { f } from "./nested-imports-f.js";
+export const e = "e";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-f.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-f.js
new file mode 100644
index 0000000000..0591e0b316
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-f.js
@@ -0,0 +1,2 @@
+import { g } from "./nested-imports-g.js";
+export const f = "f";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-g.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-g.js
new file mode 100644
index 0000000000..86cbe7d3f8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-g.js
@@ -0,0 +1,2 @@
+import { h } from "./nested-imports-h.js";
+export const g = "g";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-h.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-h.js
new file mode 100644
index 0000000000..a161291259
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports-h.js
@@ -0,0 +1,2 @@
+import { c } from "./nested-imports-c.js";
+export const h = "h";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports.html
new file mode 100644
index 0000000000..23bb595d0e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-imports.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>Test imports under more than 3 levels in different modules</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({ allow_uncaught_exception: true });
+
+ window.log = [];
+
+ const test_load = async_test("should load all modules successfully");
+ window.addEventListener(
+ "load",
+ test_load.step_func_done((ev) => {
+ assert_equals(log.length, 2);
+
+ assert_equals(log[0], 1);
+ assert_equals(log[1], 2);
+ })
+ );
+
+ function unreachable() {
+ log.push("unexpected");
+ }
+</script>
+<script type="module" src="./nested-imports-a.js" onerror="unreachable()"
+ onload="log.push(1)"></script>
+<script type="module" src="./nested-imports-e.js" onerror="unreachable()"
+ onload="log.push(2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-missing-export.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-missing-export.js
new file mode 100644
index 0000000000..3801ae847a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nested-missing-export.js
@@ -0,0 +1,2 @@
+import "./missing-export.js";
+log.push("missing-export-nested");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nomodule-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nomodule-attribute.html
new file mode 100644
index 0000000000..656c99b292
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/nomodule-attribute.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>The 'nomodule' attribute</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that 'nomodule' has the desired effect on classic scripts, but " +
+ "no effect on module scripts.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [undefined]);
+ }));
+
+</script>
+<script type="module" src="this.js" nomodule></script>
+<script src="this.js" nomodule></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
new file mode 100644
index 0000000000..b8866f9511
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the no-referrer policy</title>
+<meta name="referrer" content="no-referrer">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+
+import { referrer as referrerSame } from "./resources/referrer-checker.py?name=same";
+
+import { referrer as referrerRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name=remote";
+
+import { referrer as referrerSameSame } from "./resources/import-referrer-checker.sub.js?name=same_same";
+
+import { referrer as referrerSameRemote } from "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote";
+
+import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
+
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+test(t => {
+ assert_equals(
+ referrerSame, "",
+ "Referrer should not be sent for the same-origin top-level script.");
+}, "Importing a same-origin top-level script with the no-referrer policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemote, "",
+ "Referrer should not be sent for the remote-origin top-level script.");
+}, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameSame, "",
+ "Referrer should not be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a same-origin top-level " +
+ "script with the no-referrer policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameRemote, "",
+ "Referrer should not be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a same-origin top-level " +
+ "script with the no-referrer policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemoteRemote, "",
+ "Referrer should not be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
+ "top-level script with the no-referrer policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemoteSame, "",
+ "Referrer should not be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+ "top-level script with the no-referrer policy.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
new file mode 100644
index 0000000000..fd4c1ea496
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the origin-when-cross-origin policy</title>
+<meta name="referrer" content="origin-when-cross-origin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+
+import { referrer as referrerSame } from "./resources/referrer-checker.py?name=same";
+
+import { referrer as referrerRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name=remote";
+
+import { referrer as referrerSameSame } from "./resources/import-referrer-checker.sub.js?name=same_same";
+
+import { referrer as referrerSameRemote } from "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote";
+
+import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
+
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+const origin = (new URL(location.href)).origin + "/";
+const remoteOrigin = new URL("http://{{domains[www1]}}:{{ports[http][0]}}/").origin + "/";
+
+test(t => {
+ assert_equals(
+ referrerSame, location.href,
+ "Full referrer should be sent for the same-origin top-level script.");
+}, "Importing a same-origin top-level script with the " +
+ "origin-when-cross-origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemote, origin,
+ "Referrer should be stripped to the origin when importing " +
+ "remote-origin top-level script.");
+}, "Importing a remote-origin top-level script with the " +
+ "origin-when-cross-origin policy.");
+
+test(t => {
+ const scriptURL =
+ new URL("resources/import-referrer-checker.sub.js", location.href)
+ assert_equals(
+ referrerSameSame, scriptURL + "?name=same_same",
+ "Full referrer should be sent for same-origin descendant script" +
+ "imported by same-origin top-level script.");
+}, "Importing a same-origin descendant script from a same-origin top-level " +
+ "script with the origin-when-cross-origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameRemote, origin,
+ "Referrer should be stripped to the origin for the remote-origin " +
+ "descendant script imported from same-origin top-level script.");
+}, "Importing a remote-origin descendant script from a same-origin top-level " +
+ "script with the origin-when-cross-origin policy.");
+
+test(t => {
+ const scriptURL = new URL(
+ "html/semantics/scripting-1/the-script-element/module/resources/" +
+ "import-referrer-checker.sub.js",
+ remoteOrigin);
+ assert_equals(referrerRemoteRemote, scriptURL + "?name=remote_remote",
+ "Full referrer should be sent for the remote-origin descendant script " +
+ "imported from a remote-origin top-level script.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
+ "top-level script with the origin-when-cross-origin policy.");
+
+test(t => {
+ assert_equals(referrerRemoteSame, remoteOrigin,
+ "Referrer should be stripped to the origin for the same-origin " +
+ "descendant script imported by remote-origin top-level script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+ "top-level script with the origin-when-cross-origin policy.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
new file mode 100644
index 0000000000..a554fb4b0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the origin policy</title>
+<meta name="referrer" content="origin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+
+import { referrer as referrerSame } from "./resources/referrer-checker.py?name=same";
+
+import { referrer as referrerRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name=remote";
+
+import { referrer as referrerSameSame } from "./resources/import-referrer-checker.sub.js?name=same_same";
+
+import { referrer as referrerSameRemote } from "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote";
+
+import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
+
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+const origin = (new URL(location.href)).origin + "/";
+const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
+
+test(t => {
+ assert_equals(
+ referrerSame, origin,
+ "Referrer should be sent for the same-origin top-level script.");
+}, "Importing a same-origin top-level script with the origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemote, origin,
+ "Referrer should be sent for the remote-origin top-level script.");
+}, "Importing a remote-origin top-level script with the origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameSame, origin,
+ "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a same-origin top-level " +
+ "script with the origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameRemote, origin,
+ "Referrer should be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a same-origin top-level " +
+ "script with the origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemoteRemote, remoteOrigin,
+ "Referrer should be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
+ "top-level script with the origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemoteSame, remoteOrigin,
+ "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+ "top-level script with the origin policy.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-policy-for-descendants.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-policy-for-descendants.sub.html
new file mode 100644
index 0000000000..4a7005da84
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-policy-for-descendants.sub.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Module script descendants use the referrer policy on their ancestor, if one exists</title>
+<link rel=help href="https://github.com/whatwg/html/pull/9210">
+<meta name="referrer" content="no-referrer">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+//
+// The case where the parent module script is sent with no referrer policy at
+// all is covered in `referrer-no-referrer.sub.html` (and others like it). In
+// that case, the parent module inherits its referencing document's referrer
+// policy for use in descendant imports.
+
+import { referrer as parentWithNoReferrerWhenDowngrade } from
+ "./resources/import-referrer-checker.sub.js?name=same_same&pipe=header(Referrer-Policy,no-referrer-when-downgrade)";
+
+import { referrer as parentWithOrigin} from
+ "./resources/import-referrer-checker.sub.js?name=same_remote&pipe=header(Referrer-Policy,origin)";
+
+import { referrer as parentWithSameOrigin} from
+ "./resources/import-referrer-checker.sub.js?name=same_remote_so&pipe=header(Referrer-Policy,same-origin)";
+
+import { referrer as parentWithOriginWhenCrossOriginRemoteDescendant} from
+ "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote_owco&pipe=header(Referrer-Policy,origin-when-cross-origin)";
+
+import { referrer as remoteParentWithOriginWhenCrossOriginSameOriginDescendant} from
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_same&pipe=header(Referrer-Policy,origin-when-cross-origin)";
+
+import { referrer as remoteParentWithSameOriginWhenCrossOriginSameOriginDescendant} from
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_same_so&pipe=header(Referrer-Policy,same-origin)";
+
+import { referrer as remoteParentWithOriginWhenCrossOriginRemoteDescendant} from
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_remote&pipe=header(Referrer-Policy,origin-when-cross-origin)";
+
+import { referrer as remoteParentWithSameOriginWhenCrossOriginRemoteDescendant} from
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_remote_so&pipe=header(Referrer-Policy,same-origin)";
+
+import { referrer as parentWithInvalidPolicy } from
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_same_invalid&pipe=header(Referrer-Policy,invalid-policy)";
+
+test(t => {
+ const expected_url =
+ new URL("html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=same_same&pipe=header(Referrer-Policy,no-referrer-when-downgrade)",
+ window.origin);
+ assert_equals(
+ parentWithNoReferrerWhenDowngrade, expected_url.toString(),
+ "Descendant referrer should be the parent's full URL.");
+}, "Parent module delivered with `no-referrer-when-downgrade` policy importing a same-origin descendant script.");
+
+test(t => {
+ assert_equals(
+ parentWithOrigin, window.origin + "/",
+ "Descendant referrer should be the parent's origin.");
+}, "Parent module delivered with `origin` policy importing a same-origin descendant script.");
+
+test(t => {
+ const expected_url =
+ new URL("html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=same_remote_so&pipe=header(Referrer-Policy,same-origin)",
+ window.origin);
+ assert_equals(
+ parentWithSameOrigin, expected_url.toString(),
+ "Descendant referrer should be the parent's full URL.");
+}, "Parent module delivered with `same-origin` policy importing a same-origin descendant script.");
+
+test(t => {
+ assert_equals(
+ parentWithOriginWhenCrossOriginRemoteDescendant, window.origin + "/",
+ "Remote descendant referrer should be the parent's origin.");
+}, "Parent module delivered with `origin-when-cross-origin` policy importing a cross-origin descendant script.");
+
+test(t => {
+ const expected_url =
+ new URL("/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_same&pipe=header(Referrer-Policy,origin-when-cross-origin)",
+ "http://{{domains[www1]}}:{{ports[http][0]}}/");
+ assert_equals(
+ remoteParentWithOriginWhenCrossOriginSameOriginDescendant, expected_url.toString(),
+ "Same-origin descendant referrer should be the parent's full URL.");
+}, "Remote parent module delivered with `origin-when-cross-origin` policy importing a same-origin-to-parent-module descendant script.");
+
+test(t => {
+ const expected_url =
+ new URL("/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_same_so&pipe=header(Referrer-Policy,same-origin)",
+ "http://{{domains[www1]}}:{{ports[http][0]}}/");
+ assert_equals(
+ remoteParentWithSameOriginWhenCrossOriginSameOriginDescendant, expected_url.toString(),
+ "Same-origin descendant referrer should be the parent's full URL.");
+}, "Remote parent module delivered with `same-origin` policy importing a same-origin-to-parent-module descendant script.");
+
+test(t => {
+ assert_equals(
+ remoteParentWithOriginWhenCrossOriginRemoteDescendant, "http://{{domains[www1]}}:{{ports[http][0]}}/",
+ "Remote-origin descendant referrer should be the parent's origin.");
+}, "Remote parent module delivered with `origin-when-cross-origin` policy importing a cross-origin-to-parent-module descendant script.");
+
+test(t => {
+ assert_equals(
+ remoteParentWithSameOriginWhenCrossOriginRemoteDescendant, "");
+}, "Remote parent module delivered with `same-origin` policy importing a cross-origin-to-parent-module descendant script.");
+
+// This tests the following spec line:
+//
+// "If referrerPolicy is not the empty string, set options's referrer policy to
+// referrerPolicy."
+//
+// In other words, invalid referrer policies are ignored, so the referrer policy
+// from the referencing document is inherited as usual, which is `no-referrer`
+// in this case.
+test(t => {
+ assert_equals(
+ parentWithInvalidPolicy, "",
+ "Descendant referrer should be empty.");
+}, "Parent module delivered with invalid policy importing a same-origin descendant script.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
new file mode 100644
index 0000000000..7d6d515a47
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the same-origin policy</title>
+<meta name="referrer" content="same-origin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+
+import { referrer as referrerSame } from "./resources/referrer-checker.py?name=same";
+
+import { referrer as referrerRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name=remote";
+
+import { referrer as referrerSameSame } from "./resources/import-referrer-checker.sub.js?name=same_same";
+
+import { referrer as referrerSameRemote } from "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote";
+
+import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
+
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/";
+
+test(t => {
+ assert_equals(
+ referrerSame, location.href,
+ "Referrer should be sent for the same-origin top-level script.");
+}, "Importing a same-origin top-level script with the same-origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemote, "",
+ "Referrer should not be sent for the remote-origin top-level script.");
+}, "Importing a remote-origin top-level script with the same-origin policy.");
+
+test(t => {
+ const path =
+ new URL("resources/import-referrer-checker.sub.js", location.href);
+ assert_equals(
+ referrerSameSame, path + `?name=same_same`,
+ "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a same-origin top-level " +
+ "script with the same-origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerSameRemote, "",
+ "Referrer should not be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a same-origin top-level " +
+ "script with the same-origin policy.");
+
+test(t => {
+ const scriptURL = new URL(
+ "html/semantics/scripting-1/the-script-element/module/resources/" +
+ "import-referrer-checker.sub.js", remoteOrigin);
+ assert_equals(
+ referrerRemoteRemote, scriptURL + "?name=remote_remote",
+ "Referrer should be sent for the remote-origin descendant script " +
+ "when it is imported from a top-level script in the same remote-origin.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
+ "top-level script with the same-origin policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemoteSame, "",
+ "Referrer should not be sent for the same-origin descendant script " +
+ "when it is imported from a top-level remote-origin script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+ "top-level script with the same-origin policy.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-strict-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-strict-policies.sub.html
new file mode 100644
index 0000000000..1984d875b3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-strict-policies.sub.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the strict-origin referrer policy</title>
+<meta name="referrer" content="strict-origin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map in descendant import.
+
+import { referrer as insecureImport } from "./resources/import-referrer-checker-insecure.sub.js?name=insecure_import";
+import { referrer as secureImport } from "https://{{domains[www]}}:{{ports[https][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js?name=secure_import";
+
+const origin = (new URL(location.href)).origin + "/";
+
+test(t => {
+ assert_equals(
+ insecureImport, origin,
+ "A document with the strict-origin referrer policy served over HTTP, " +
+ "imports an module script over HTTP, that imports a descendant script " +
+ "over HTTP. The request for the descendant script is sent with a " +
+ "`Referer` header with the page's origin");
+
+ assert_equals(
+ secureImport, "",
+ "A document with the strict-origin referrer policy served over HTTP, " +
+ "imports an module script over HTTPS, that imports a descendant script " +
+ "over HTTP. The request for the descendant script is sent with no " +
+ "`Referer` header");
+}, "The strict-* referrer policies compare the trustworthiness of a " +
+ "request's referrer string against its URL");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
new file mode 100644
index 0000000000..443731c1b8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrer with the unsafe-url policy</title>
+<meta name="referrer" content="unsafe-url">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+
+// "name" parameter is necessary for bypassing the module map.
+
+import { referrer as referrerSame } from "./resources/referrer-checker.py?name=same";
+
+import { referrer as referrerRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name=remote";
+
+import { referrer as referrerSameSame } from "./resources/import-referrer-checker.sub.js?name=same_same";
+
+import { referrer as referrerSameRemote } from "./resources/import-remote-origin-referrer-checker.sub.js?name=same_remote";
+
+import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js?name=remote_remote";
+
+import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
+
+test(t => {
+ assert_equals(
+ referrerSame, location.href,
+ "Referrer should be sent for the same-origin top-level script.");
+}, "Importing a same-origin top-level script with the unsafe-url policy.");
+
+test(t => {
+ assert_equals(
+ referrerRemote, location.href,
+ "Referrer should be sent for the remote-origin top-level script.");
+}, "Importing a remote-origin top-level script with the unsafe-url policy.");
+
+test(t => {
+ const scriptURL =
+ new URL("resources/import-referrer-checker.sub.js", location.href)
+ assert_equals(
+ referrerSameSame, scriptURL + "?name=same_same",
+ "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a same-origin top-level " +
+ "script with the unsafe-url policy.");
+
+test(t => {
+ const scriptURL =
+ new URL("resources/import-remote-origin-referrer-checker.sub.js",
+ location.href)
+ assert_equals(
+ referrerSameRemote, scriptURL + "?name=same_remote",
+ "Referrer should be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a same-origin top-level " +
+ "script with the unsafe-url policy.");
+
+test(t => {
+ const scriptURL =
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/" +
+ "scripting-1/the-script-element/module/resources/" +
+ "import-referrer-checker.sub.js";
+ assert_equals(
+ referrerRemoteRemote, scriptURL + "?name=remote_remote",
+ "Referrer should be sent for the remote-origin descendant script.");
+}, "Importing a remote-origin descendant script from a remote-origin " +
+ "top-level script with the unsafe-url policy.");
+
+test(t => {
+ const scriptURL =
+ "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/" +
+ "scripting-1/the-script-element/module/resources/" +
+ "import-same-origin-referrer-checker-from-remote-origin.sub.js";
+ assert_equals(
+ referrerRemoteSame, scriptURL + "?name=remote_same",
+ "Referrer should be sent for the same-origin descendant script.");
+}, "Importing a same-origin descendant script from a remote-origin " +
+ "top-level script with the unsafe-url policy.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis
new file mode 100644
index 0000000000..0fe1379e56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/404-but-js.asis
@@ -0,0 +1,4 @@
+HTTP/1.1 404 Not Found
+Content-Type: text/javascript
+
+window.ran404 = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/500-but-js.asis b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/500-but-js.asis
new file mode 100644
index 0000000000..c81202f7ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/500-but-js.asis
@@ -0,0 +1,4 @@
+HTTP/1.1 500 Not Found
+Content-Type: text/javascript
+
+window.ran500 = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py
new file mode 100644
index 0000000000..90551e92c3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py
@@ -0,0 +1,20 @@
+def main(request, response):
+ headers = [
+ (b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+ (b"Access-Control-Allow-Credentials", b"true")
+ ]
+ identifier = request.GET.first(b"id")
+ cookie_name = request.GET.first(b"cookieName")
+ cookie = request.cookies.first(cookie_name, None)
+ if identifier is None or cookie_name is None:
+ return headers, b""
+
+ if cookie is None:
+ result = b"not found"
+ elif cookie.value == b"1":
+ result = b"found"
+ else:
+ result = b"different value: " + cookie.value
+
+ return headers, b"window." + identifier + b" = '" + result + b"';"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
new file mode 100644
index 0000000000..dbc14dffec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module"
+ src="check-cookie.py?id=sameOriginNone&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}">
+</script>
+<script type="module"
+ src="check-cookie.py?id=sameOriginAnonymous&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}"
+ crossOrigin="anonymous">
+</script>
+<script type="module"
+ src="check-cookie.py?id=sameOriginUseCredentials&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}"
+ crossOrigin="use-credentials">
+</script>
+<script type="module"
+ src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNone&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}">
+</script>
+<script type="module"
+ src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymous&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}"
+ crossOrigin="anonymous">
+</script>
+<script type="module"
+ src="http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentials&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}"
+ crossOrigin="use-credentials">
+</script>
+
+<script type="module">
+import "./check-cookie.py?id=sameOriginNoneDescendant&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+<script type="module" crossOrigin="anonymous">
+import "./check-cookie.py?id=sameOriginAnonymousDescendant&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+<script type="module" crossOrigin="use-credentials">
+import "./check-cookie.py?id=sameOriginUseCredentialsDescendant&cookieName=same&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+<script type="module">
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginNoneDescendant&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+<script type="module" crossOrigin="anonymous">
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginAnonymousDescendant&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+<script type="module" crossOrigin="use-credentials">
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py?id=crossOriginUseCredentialsDescendant&cookieName=cross&origin=http://{{host}}:{{ports[http][0]}}";
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+ window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py
new file mode 100644
index 0000000000..52dbfba445
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py
@@ -0,0 +1,7 @@
+import time
+
+def main(request, response):
+ delay = float(request.GET.first(b"ms", 500))
+ time.sleep(delay / 1E3)
+
+ return [(b"Content-type", b"text/javascript")], u"export let delayedLoaded = true;"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-helper.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-helper.sub.js
new file mode 100644
index 0000000000..7d9b024e75
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-helper.sub.js
@@ -0,0 +1,67 @@
+// runTestsFromIframe() is used in the top-level HTML to set cookies and then
+// start actual tests in iframe.
+function runTestsFromIframe(iframe_url) {
+ const setSameOriginCookiePromise = fetch(
+ '/cookies/resources/set-cookie.py?name=same&path=/html/semantics/scripting-1/the-script-element/module/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+ const setCrossOriginCookiePromise = fetch(
+ 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=cross&path=/html/semantics/scripting-1/the-script-element/module/',
+ {
+ mode: 'no-cors',
+ credentials: 'include',
+ });
+ const windowLoadPromise = new Promise(resolve => {
+ window.addEventListener('load', () => {
+ resolve();
+ });
+ });
+
+ const iframe = document.createElement('iframe');
+ Promise.all([setSameOriginCookiePromise,
+ setCrossOriginCookiePromise,
+ windowLoadPromise]).then(() => {
+ iframe.src = iframe_url;
+ document.body.appendChild(iframe);
+ fetch_tests_from_window(iframe.contentWindow);
+ });
+}
+
+// The functions below are used from tests within the iframe.
+
+let testNumber = 0;
+
+// importFunc and setTimeoutFunc is used to make the active script at the time
+// of import() to be the script elements that call `runTest()`,
+// NOT this script defining runTest().
+
+function runTest(importFunc, origin, expected, source) {
+ let url;
+ let description;
+ if (origin === 'same') {
+ url = "./check-cookie.py";
+ description = "Same-origin dynamic import from " + source;
+ } else {
+ url = "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/check-cookie.py";
+ description = "Cross-origin dynamic import from " + source;
+ }
+ promise_test(() => {
+ const id = "test" + testNumber;
+ testNumber += 1;
+ return importFunc(url + "?id=" + id + "&cookieName=" + origin + "&origin=" + location.origin)
+ .then(() => {
+ assert_equals(window[id], expected, "cookie");
+ });
+ }, description);
+}
+
+function setTimeoutWrapper(setTimeoutFunc) {
+ return url => {
+ return new Promise(resolve => {
+ window.resolve = resolve;
+ setTimeoutFunc(`import("${url}").then(window.resolve)`);
+ });
+ };
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html
new file mode 100644
index 0000000000..88204ef00b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-iframe.sub.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="dynamic-import-credentials-helper.sub.js"></script>
+
+<!--
+The active script at the time of import() is the script elements below, and
+thus the credentials mode of the fetch options of the script elements below
+are used for dynamic import requests.
+-->
+
+<script>
+runTest(url => import(url),
+ "same", "found", "classic script (crossOrigin not specified)");
+runTest(url => import(url),
+ "cross", "not found", "classic script (crossOrigin not specified)");
+</script>
+
+<script crossOrigin="anonymous">
+runTest(url => import(url), "same", "found",
+ "classic script (crossOrigin=anonymous)");
+runTest(url => import(url), "cross", "not found",
+ "classic script (crossOrigin=anonymous)");
+</script>
+
+<script crossOrigin="use-credentials">
+runTest(url => import(url),
+ "same", "found", "classic script (crossOrigin=use-credentials)");
+runTest(url => import(url),
+ "cross", "found", "classic script (crossOrigin=use-credentials)");
+</script>
+
+<script type="module">
+runTest(url => import(url),
+ "same", "found", "module script (crossOrigin not specified)");
+runTest(url => import(url),
+ "cross", "not found", "module script (crossOrigin not specified)");
+</script>
+
+<script type="module" crossOrigin="anonymous">
+runTest(url => import(url), "same", "found",
+ "module script (crossOrigin=anonymous)");
+runTest(url => import(url), "cross", "not found",
+ "module script (crossOrigin=anonymous)");
+</script>
+
+<script type="module" crossOrigin="use-credentials">
+runTest(url => import(url),
+ "same", "found", "module script (crossOrigin=use-credentials)");
+runTest(url => import(url),
+ "cross", "found", "module script (crossOrigin=use-credentials)");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-setTimeout-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-setTimeout-iframe.sub.html
new file mode 100644
index 0000000000..ffba141527
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/dynamic-import-credentials-setTimeout-iframe.sub.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="dynamic-import-credentials-helper.sub.js"></script>
+
+<!--
+The active script at the time of import() is the classic script created by
+https://html.spec.whatwg.org/multipage/C/#timer-initialisation-steps
+and the active script at the time of setTimeout() is the script elements below,
+thus the credentials mode of the fetch options of the script elements below
+are used for dynamic import requests.
+
+setTimeout() calls below can't be wrapped (e.g. by step_timeout())
+because wrapping setTimeout() would set active scripts differently.
+-->
+
+<script>
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from classic script (crossOrigin not specified)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "not found", "setTimeout(string) from classic script (crossOrigin not specified)");
+</script>
+
+<script crossOrigin="anonymous">
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from classic script (crossOrigin=anonymous)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "not found", "setTimeout(string) from classic script (crossOrigin=anonymous)");
+</script>
+
+<script crossOrigin="use-credentials">
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from classic script (crossOrigin=use-credentials)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "found", "setTimeout(string) from classic script (crossOrigin=use-credentials)");
+</script>
+
+<script type="module">
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from module script (crossOrigin not specified)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "not found", "setTimeout(string) from module script (crossOrigin not specified)");
+</script>
+
+<script type="module" crossOrigin="anonymous">
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from module script (crossOrigin=anonymous)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "not found", "setTimeout(string) from module script (crossOrigin=anonymous)");
+</script>
+
+<script type="module" crossOrigin="use-credentials">
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "same", "found", "setTimeout(string) from module script (crossOrigin=use-credentials)");
+runTest(setTimeoutWrapper(x => setTimeout(x, 0)),
+ "cross", "found", "setTimeout(string) from module script (crossOrigin=use-credentials)");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/fast-module.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/fast-module.js
new file mode 100644
index 0000000000..3a76cf71f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/fast-module.js
@@ -0,0 +1 @@
+loaded.push("fast");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8-with-charset-header.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8-with-charset-header.js
new file mode 100644
index 0000000000..6fc4ad395c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8-with-charset-header.js
@@ -0,0 +1 @@
+import "../../serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=windows-1250&dummy=6";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8.js
new file mode 100644
index 0000000000..3ae805d78d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-non-utf8.js
@@ -0,0 +1 @@
+import "../../serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript&dummy=5";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js
new file mode 100644
index 0000000000..2d6fd96712
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js
@@ -0,0 +1 @@
+export { referrer } from 'http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name={{GET[name]}}';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js.headers b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js.headers
new file mode 100644
index 0000000000..cb762eff80
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker-insecure.sub.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js
new file mode 100644
index 0000000000..2c7dce9dff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js
@@ -0,0 +1,2 @@
+import { referrer as referrerImport } from './referrer-checker.py?name={{GET[name]}}';
+export const referrer = referrerImport;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js.headers b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js.headers
new file mode 100644
index 0000000000..cb762eff80
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-referrer-checker.sub.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-remote-origin-referrer-checker.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-remote-origin-referrer-checker.sub.js
new file mode 100644
index 0000000000..45a2520b68
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-remote-origin-referrer-checker.sub.js
@@ -0,0 +1,2 @@
+import { referrer as referrerImport } from 'http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name={{GET[name]}}';
+export const referrer = referrerImport;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
new file mode 100644
index 0000000000..5a53bcd4d5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js
@@ -0,0 +1,2 @@
+import { referrer as referrerImport } from 'http://{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py?name={{GET[name]}}';
+export const referrer = referrerImport;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
new file mode 100644
index 0000000000..cb762eff80
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js
new file mode 100644
index 0000000000..c2ccab7c62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8-with-charset-header.js
@@ -0,0 +1 @@
+import "../../serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript%3Bcharset=windows-1250&dummy=6";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8.js
new file mode 100644
index 0000000000..5708a26e07
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/import-utf8.js
@@ -0,0 +1 @@
+import "../../serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript&dummy=5";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-404-but-js.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-404-but-js.js
new file mode 100644
index 0000000000..d62e4f05be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-404-but-js.js
@@ -0,0 +1 @@
+import "./404-but-js.asis";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-500-but-js.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-500-but-js.js
new file mode 100644
index 0000000000..d62e4f05be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-500-but-js.js
@@ -0,0 +1 @@
+import "./404-but-js.asis";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-b-cross-origin.sub.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-b-cross-origin.sub.js
new file mode 100644
index 0000000000..6db57b5017
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/imports-b-cross-origin.sub.js
@@ -0,0 +1 @@
+import "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/imports-b.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py
new file mode 100644
index 0000000000..413f48d381
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/referrer-checker.py
@@ -0,0 +1,6 @@
+def main(request, response):
+ referrer = request.headers.get(b"referer", b"")
+ response_headers = [(b"Content-Type", b"text/javascript"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ return (200, response_headers,
+ b"export const referrer = '" + referrer + b"';")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/slow-module.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/slow-module.js
new file mode 100644
index 0000000000..4623ef7360
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/resources/slow-module.js
@@ -0,0 +1,3 @@
+// This module is imported with pipe=trickle(d2) to make it load more slowly
+// than fast-module.js
+loaded.push("slow");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/script-for-event.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/script-for-event.html
new file mode 100644
index 0000000000..e3b8e15b41
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/script-for-event.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<title>Module scripts with for and event attributes</title>
+<link rel="author" title="Matheus Kerschbaum" href="mailto:matjk7@gmail.com">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var expected = [
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+];
+var run = expected.map(function() { return false });
+</script>
+<script for="w&#x130;ndow" event="onload" type="module">
+run[0] = true;
+</script>
+<script for="window" event="onload x" type="module">
+run[1] = true;
+</script>
+<script for="window" event="onload(x" type="module">
+run[2] = true;
+</script>
+<script for="window" event="onload(x)" type="module">
+run[3] = true;
+</script>
+<script for="window" event="onclick" type="module">
+run[4] = true;
+</script>
+<script for="" event="onload" type="module">
+run[5] = true;
+</script>
+<script for="window" event="" type="module">
+run[6] = true;
+</script>
+<script for="" event="" type="module">
+run[7] = true;
+</script>
+<script for="&#xa0;window" event="onload" type="module">
+run[8] = true;
+</script>
+<script for="window&#xa0;" event="onload" type="module">
+run[9] = true;
+</script>
+<script for="window" event="&#xa0;onload" type="module">
+run[10] = true;
+</script>
+<script for="window" event="onload&#xa0;" type="module">
+run[11] = true;
+</script>
+<script for=" window " event=" onload " type="module">
+run[12] = true;
+</script>
+<script for=" window " event=" onload() " type="module">
+run[13] = true;
+</script>
+<script for="object" event="handler" type="module">
+run[14] = true;
+</script>
+<script event="handler" type="module">
+run[15] = true;
+</script>
+<script for="object" type="module">
+run[16] = true;
+</script>
+<script type="module">
+test(function() {
+ for (var i = 0; i < run.length; ++i) {
+ test(function() {
+ var script = document.querySelectorAll("script[for], script[event]")[i];
+ assert_equals(run[i], expected[i],
+ "script for=" + format_value(script.getAttribute("for")) +
+ " event=" + format_value(script.getAttribute("event")));
+ }, "Script " + i);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/set-currentScript-on-window.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/set-currentScript-on-window.js
new file mode 100644
index 0000000000..6863075bd9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/set-currentScript-on-window.js
@@ -0,0 +1 @@
+window.currentScriptRecorded = document.currentScript;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-1.html
new file mode 100644
index 0000000000..cc4e2d69b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Single evaluation, 1</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that a module is evaluated only once, and that 'this' is " +
+ "undefined (because of strict mode).");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [undefined, "this-nested"]);
+ }));
+</script>
+<script type="module" src="this.js"></script>
+<script type="module" src="this.js"></script>
+<script type="module" src="this-nested.js"></script>
+<script type="module" src="this.js"></script>
+<script type="module" src="this-nested.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-2.html
new file mode 100644
index 0000000000..790e2fa9c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/single-evaluation-2.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Single evaluation, 2</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.log = [];
+
+ const test_load = async_test(
+ "Test that a module is evaluated only once, and that 'this' is " +
+ "undefined (because of strict mode).");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_array_equals(log, [undefined, "this-nested"]);
+ }));
+</script>
+<script type="module" src="this-nested.js"></script>
+<script type="module" src="this-nested.js"></script>
+<script type="module" src="this.js"></script>
+<script type="module" src="this-nested.js"></script>
+<script type="module" src="this.js"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-cycle.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-cycle.html
new file mode 100644
index 0000000000..3a42cf9e30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-cycle.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Cyclic graph with slow imports</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+import { loaded } from "./slow-module-graph-a.js";
+
+test(() => {
+ assert_true(loaded);
+}, "module graph with cycles load even if part of the graph loads slow");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js
new file mode 100644
index 0000000000..48701aa1d0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js
@@ -0,0 +1,3 @@
+import "./slow-module-graph-b.js";
+import "./resources/delayed-modulescript.py"
+export let loaded = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js
new file mode 100644
index 0000000000..53a8f2026e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js
@@ -0,0 +1 @@
+import "./slow-module-graph-a.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/specifier-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/specifier-error.html
new file mode 100644
index 0000000000..d07005caaa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/specifier-error.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Handling of invalid specifiers</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+
+ window.addEventListener("error", ev => log.push(ev.error));
+
+ const test_load = async_test(
+ "Test that invalid module specifier leads to TypeError on window.");
+ window.addEventListener("load", test_load.step_func_done(ev => {
+ assert_equals(log.length, 1);
+ assert_equals(log[0].constructor, TypeError);
+ }));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script type="module" src="./bad-module-specifier.js" onerror="unreachable()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror-nested.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror-nested.js
new file mode 100644
index 0000000000..de1b053c5a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror-nested.js
@@ -0,0 +1,2 @@
+import "./syntaxerror.js";
+log.push("nested-syntaxerror");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror.js
new file mode 100644
index 0000000000..31a9e2cbdf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/syntaxerror.js
@@ -0,0 +1,2 @@
+log.push("syntaxerror");
+%!#$@#$@#$@
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this-nested.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this-nested.js
new file mode 100644
index 0000000000..f204812fd1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this-nested.js
@@ -0,0 +1,2 @@
+import "./this.js";
+log.push("this-nested");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this.js
new file mode 100644
index 0000000000..996a439df0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/this.js
@@ -0,0 +1 @@
+log.push(this);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-error.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-error.js
new file mode 100644
index 0000000000..9769c84b23
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-error.js
@@ -0,0 +1,3 @@
+window.before_throwing_error = true;
+throw new Error;
+window.after_throwing_error = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-nested.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-nested.js
new file mode 100644
index 0000000000..f1801ea366
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw-nested.js
@@ -0,0 +1,2 @@
+import "./throw.js";
+log.push("throw-nested");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw.js
new file mode 100644
index 0000000000..cef7918216
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw.js
@@ -0,0 +1,2 @@
+log.push("throw");
+throw {foo: true}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw2.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw2.js
new file mode 100644
index 0000000000..2931eec500
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/throw2.js
@@ -0,0 +1,2 @@
+log.push("throw2");
+throw {bar: true}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked.any.js
new file mode 100644
index 0000000000..820f995aaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked.any.js
@@ -0,0 +1,11 @@
+promise_test(async t => {
+ const { checkMicrotask } = await import("./sibling-imports-not-blocked__microtask__parent.js");
+
+ assert_equals(checkMicrotask, "PASS");
+}, "Async modules only scheduling microtasks don't block execution of sibling modules");
+
+promise_test(async t => {
+ const { checkTask } = await import("./sibling-imports-not-blocked__task__parent.js");
+
+ assert_equals(checkTask, "PASS");
+}, "Async modules scheduling tasks don't block execution of sibling modules");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-get-sync.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-get-sync.js
new file mode 100644
index 0000000000..063697310a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-get-sync.js
@@ -0,0 +1 @@
+export const { checkMicrotask } = globalThis;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-set-async.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-set-async.js
new file mode 100644
index 0000000000..98930fed0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__check-set-async.js
@@ -0,0 +1,3 @@
+globalThis.checkMicrotask = "PASS";
+await 0;
+globalThis.checkMicrotask = "FAIL";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__parent.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__parent.js
new file mode 100644
index 0000000000..a28fcef9cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__microtask__parent.js
@@ -0,0 +1,2 @@
+import "./sibling-imports-not-blocked__microtask__check-set-async.js";
+export { checkMicrotask } from "./sibling-imports-not-blocked__microtask__check-get-sync.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-get-sync.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-get-sync.js
new file mode 100644
index 0000000000..833acdd7ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-get-sync.js
@@ -0,0 +1 @@
+export const { checkTask } = globalThis;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-set-async.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-set-async.js
new file mode 100644
index 0000000000..0973b3c65a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__check-set-async.js
@@ -0,0 +1,3 @@
+globalThis.checkTask = "PASS";
+await new Promise(r => setTimeout(r, 0));
+globalThis.checkTask = "FAIL";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__parent.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__parent.js
new file mode 100644
index 0000000000..56ee5134d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/top-level-await/sibling-imports-not-blocked__task__parent.js
@@ -0,0 +1,2 @@
+import "./sibling-imports-not-blocked__task__check-set-async.js";
+export { checkTask } from "./sibling-imports-not-blocked__task__check-get-sync.js";
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/type.html
new file mode 100644
index 0000000000..5817ae4d43
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/type.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Type attribute of module scripts</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+window.t1 = async_test('type="module"');
+window.t2 = async_test('type="MODULE"');
+window.t3 = async_test('type="Module"');
+window.t4 = async_test('type="module "');
+window.t5 = async_test('type=" module"');
+</script>
+<script type="module">window.t1.done();</script>
+<script type="MODULE">window.t2.done();</script>
+<script type="Module">window.t3.done();</script>
+<script type="module ">window.t4.unreached_func('Unexpectedly evaluated');</script>
+<script type=" module">window.t5.unreached_func('Unexpectedly evaluated');</script>
+<script type="module">
+window.t1.unreached_func('Unexpectedly not evaluated')();
+window.t2.unreached_func('Unexpectedly not evaluated')();
+window.t3.unreached_func('Unexpectedly not evaluated')();
+window.t4.done();
+window.t5.done();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents-during-evaluation.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents-during-evaluation.html
new file mode 100644
index 0000000000..e4cd887c61
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents-during-evaluation.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Moving script elements between documents during evaluation</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script id="outerScript">
+"use strict";
+
+async_test(t => {
+ const outerScript = document.querySelector('#outerScript');
+ assert_equals(document.currentScript, outerScript);
+
+ const innerScript = document.createElement('script');
+ window.innerScript = innerScript;
+
+ window.innerScriptEvaluated = false;
+ window.anotherDocument = null;
+
+ innerScript.innerText = `
+ window.innerScriptEvaluated = true;
+ const innerScript = window.innerScript;
+ assert_equals(document.currentScript, innerScript,
+ '[1] Before move: currentScript of source Document');
+ assert_equals(innerScript.ownerDocument, document,
+ '[1] Before move: ownerDocument');
+
+ window.anotherDocument = document.implementation.createHTMLDocument();
+ window.anotherDocument.body.appendChild(innerScript);
+
+ assert_equals(innerScript.ownerDocument, anotherDocument,
+ '[2] Just after move: ownerDocument');
+ assert_equals(document.currentScript, innerScript,
+ '[2] Just after move: currentScript of source Document');
+ assert_equals(anotherDocument.currentScript, null,
+ '[2] Just after move: currentScript of destination Document');
+ `;
+
+ document.body.appendChild(innerScript);
+ assert_true(window.innerScriptEvaluated,
+ 'Inner script should be evaluated synchronously');
+
+ assert_equals(document.currentScript, outerScript,
+ '[3] After inner script: currentScript of source Document');
+ assert_equals(window.anotherDocument.currentScript, null,
+ '[3] After inner script: currentScript of destination Document');
+
+ t.step_timeout(() => {
+ assert_equals(document.currentScript, null,
+ '[4] After outer script: currentScript of source Document');
+ assert_equals(anotherDocument.currentScript, null,
+ '[4] After outer script: currentScript of destination Document');
+ t.done();
+ }, 0);
+}, 'Script moved between documents during evaluation');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/README.md b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/README.md
new file mode 100644
index 0000000000..f95e0a63a3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/README.md
@@ -0,0 +1,16 @@
+The tests in this directory are for script elements moved between documents.
+
+Use
+
+```
+$ tools/generate.py
+```
+
+to generate test HTML files (except for tests in subdirectories).
+
+Background:
+
+- https://www.w3.org/Bugs/Public/show_bug.cgi?id=11323
+- https://github.com/whatwg/html/issues/2137
+- https://github.com/whatwg/html/issues/2469
+- https://github.com/whatwg/html/pull/2673
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-classic.html
new file mode 100644
index 0000000000..2b84ae8088
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html
new file mode 100644
index 0000000000..09ee1490c1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html
new file mode 100644
index 0000000000..477abd32cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html
new file mode 100644
index 0000000000..9da2276408
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html
new file mode 100644
index 0000000000..bc4deb6f17
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html
new file mode 100644
index 0000000000..ff76954f9d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "createHTMLDocument", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-classic.html
new file mode 100644
index 0000000000..768120e9d8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-module.html
new file mode 100644
index 0000000000..50dd80662d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html
new file mode 100644
index 0000000000..981a068230
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html
new file mode 100644
index 0000000000..6debb4189e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html
new file mode 100644
index 0000000000..53389f20db
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "parse-error", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html
new file mode 100644
index 0000000000..9c4a12226a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-module.html
new file mode 100644
index 0000000000..0a0490cfc1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-inline-classic.html
new file mode 100644
index 0000000000..932825709f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("after-prepare", "iframe", "success", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-classic.html
new file mode 100644
index 0000000000..444382ac20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-module.html
new file mode 100644
index 0000000000..e1a1f7c08f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-classic.html
new file mode 100644
index 0000000000..6bb5ebddbd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-module.html
new file mode 100644
index 0000000000..10a6549f62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-classic.html
new file mode 100644
index 0000000000..28bd935995
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "parse-error", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-module.html
new file mode 100644
index 0000000000..e665a75629
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-parse-error-inline-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "parse-error", "inline", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-classic.html
new file mode 100644
index 0000000000..8ee0dd1de1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "empty-src", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-module.html
new file mode 100644
index 0000000000..4791149c57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-empty-src-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "empty-src", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-classic.html
new file mode 100644
index 0000000000..3a3aceaf26
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-module.html
new file mode 100644
index 0000000000..c15b4fc77f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-classic.html
new file mode 100644
index 0000000000..576f4d4684
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-module.html
new file mode 100644
index 0000000000..c84d61c89a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-success-inline-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "createHTMLDocument", "success", "inline", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-classic.html
new file mode 100644
index 0000000000..febf6fcc55
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-module.html
new file mode 100644
index 0000000000..f936260b8c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-classic.html
new file mode 100644
index 0000000000..870c900abf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-module.html
new file mode 100644
index 0000000000..fb44a89df1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-classic.html
new file mode 100644
index 0000000000..986e4fa396
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "parse-error", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-module.html
new file mode 100644
index 0000000000..3a3fc38479
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-parse-error-inline-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "parse-error", "inline", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-classic.html
new file mode 100644
index 0000000000..4f03a94358
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "empty-src", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-module.html
new file mode 100644
index 0000000000..a7bd42fd32
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-empty-src-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "empty-src", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-classic.html
new file mode 100644
index 0000000000..08a8ac4afa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-module.html
new file mode 100644
index 0000000000..b8c3f79fea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-classic.html
new file mode 100644
index 0000000000..b639f6109d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-module.html
new file mode 100644
index 0000000000..616e46310f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-iframe-success-inline-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("before-prepare", "iframe", "success", "inline", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-classic.html
new file mode 100644
index 0000000000..745c62d898
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-module.html
new file mode 100644
index 0000000000..f6353a05fc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-classic.html
new file mode 100644
index 0000000000..21099c3ff9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-module.html
new file mode 100644
index 0000000000..2eb153acfe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-classic.html
new file mode 100644
index 0000000000..88821826ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-module.html
new file mode 100644
index 0000000000..f2a9d95741
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-createHTMLDocument-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "createHTMLDocument", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-classic.html
new file mode 100644
index 0000000000..d96bfe0d50
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "fetch-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-module.html
new file mode 100644
index 0000000000..7e71bfbe15
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-fetch-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "fetch-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-classic.html
new file mode 100644
index 0000000000..757c879897
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "parse-error", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-module.html
new file mode 100644
index 0000000000..6ec6c5970e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "parse-error", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-inline-classic.html
new file mode 100644
index 0000000000..c0b0f9d404
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-parse-error-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "parse-error", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-classic.html
new file mode 100644
index 0000000000..7955dbce62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "success", "external", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-module.html
new file mode 100644
index 0000000000..af17eb01f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-external-module.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "success", "external", "module");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-inline-classic.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-inline-classic.html
new file mode 100644
index 0000000000..8a44e2feaf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/move-back-iframe-success-inline-classic.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("move-back", "iframe", "success", "inline", "classic");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/README.md b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/README.md
new file mode 100644
index 0000000000..dcf5597e2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/README.md
@@ -0,0 +1,6 @@
+The tests in this directory checks side effects (other than script
+evaluation/event firing, which is covered by the tests in the parent directory)
+caused by scripts moved between Documents.
+
+The tests assume that script loading is not canceled when moved between
+documents (which is not explicitly specified as of Jan 2022).
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-1.html
new file mode 100644
index 0000000000..c5812765eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-1.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<body>
+<script>
+runDelayEventTest('Script elements (parser-blocking)');
+</script>
+
+<script id="to-be-moved" src="../../resources/throw.js?pipe=trickle(d3)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-2.html
new file mode 100644
index 0000000000..916673894d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<body>
+<script>
+runDelayEventTest('Script elements (async)');
+
+const script = document.createElement('script');
+script.setAttribute('id', 'to-be-moved');
+script.setAttribute('src', '../../resources/throw.js?pipe=trickle(d3)');
+document.body.appendChild(script);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-iframe.html
new file mode 100644
index 0000000000..efec7657c3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/delay-load-event-iframe.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body onload="parent.onloadIframe()">
+<script src="../../resources/throw.js?pipe=trickle(d2)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/helper.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/helper.js
new file mode 100644
index 0000000000..cb5f45eb0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/helper.js
@@ -0,0 +1,31 @@
+function runDelayEventTest(description) {
+ const t_original = async_test(description +
+ ' still delay the load event in the original Document after move');
+ const t_new = async_test(description +
+ ' does not delay the load event in the new Document after move');
+ const iframe = document.createElement('iframe');
+ iframe.setAttribute('src', 'delay-load-event-iframe.html');
+ const start_time = performance.now();
+ document.body.appendChild(iframe);
+
+ window.onload = t_original.step_func_done(() => {
+ // The `#to-be-moved` script should delay the load event until it is loaded
+ // (i.e. 3 seconds), not just until it is moved out to another Document
+ // (i.e. 1 second). Here we expect the delay should be at least 2 seconds,
+ // as the latency can be slightly less than 3 seconds due to preloading.
+ assert_greater_than(performance.now() - start_time, 2000,
+ 'Load event should be delayed until script is loaded');
+ });
+
+ window.onloadIframe = t_new.step_func_done(() => {
+ // The iframe's load event is fired after 2 seconds of its subresource
+ // loading, and shouldn't wait for the `#to-be-moved` script.
+ assert_less_than(performance.now() - start_time, 3000,
+ 'Load event should not be delayed until moved script is loaded');
+ });
+
+ t_original.step_timeout(() => {
+ const script = document.querySelector('#to-be-moved');
+ iframe.contentDocument.body.appendChild(script);
+ }, 1000);
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/in-order.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/in-order.html
new file mode 100644
index 0000000000..6a3e2b54a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/in-order.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/C/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+<body>
+<script>
+const t = async_test('Script elements (in-order) still block subsequent in-order scripts in the original Document after moved to another Document');
+const start_time = performance.now();
+const iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+
+const onScript2Evaluated = t.step_func_done(() => {
+ // `script1` should remain the
+ // #list-of-scripts-that-will-execute-in-order-as-soon-as-possible of the
+ // original Document and thus blocks `script2` evaluation until it is loaded.
+ assert_greater_than(performance.now() - start_time, 2000,
+ 'In-order scripts should block subsequent in-order scripts');
+});
+
+const script1 = document.createElement('script');
+script1.async = false;
+script1.setAttribute('src', '../../resources/throw.js?pipe=trickle(d2)');
+document.body.appendChild(script1);
+
+const script2 = document.createElement('script');
+script2.async = false;
+script2.setAttribute('src', 'data:text/javascript,onScript2Evaluated()');
+document.body.appendChild(script2);
+
+t.step_timeout(() => {
+ iframe.contentDocument.body.appendChild(script1);
+}, 1000);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/parser-blocking.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/parser-blocking.html
new file mode 100644
index 0000000000..9edde13736
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/ordering/parser-blocking.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/C/#pending-parsing-blocking-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+<body>
+<script>
+const t = async_test('Script elements (parser-blocking) still block the parser in the original Document after moved to another Document');
+const start_time = performance.now();
+const iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+
+t.step_timeout(() => {
+ const script = document.querySelector('#to-be-moved');
+ iframe.contentDocument.body.appendChild(script);
+}, 1000);
+
+let syncScriptEvaluated = false;
+
+const onSyncScript = t.step_func(() => {
+ syncScriptEvaluated = true;
+
+ // The `#to-be-moved` script should block the parser and thus the sync
+ // script after `#to-be-moved` should be delayed until `#to-be-moved` is
+ // loaded (i.e. 3 seconds).
+ // Here we expect the delay should be at least 2 seconds,
+ // as the latency can be slightly less than 3 seconds due to preloading.
+ assert_greater_than(performance.now() - start_time, 2000,
+ 'Parser should be blocked until script is loaded');
+});
+
+document.addEventListener('DOMContentLoaded', t.step_func_done(() => {
+ assert_true(syncScriptEvaluated,
+ 'sync script should be evaluated before DOMContentLoaded');
+ assert_greater_than(performance.now() - start_time, 2000,
+ 'DOMContentLoaded event should be delayed until script is loaded');
+}));
+</script>
+<script id="to-be-moved" src="../../resources/throw.js?pipe=trickle(d3)"></script>
+<script src="data:text/javascript,onSyncScript()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-helper.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-helper.js
new file mode 100644
index 0000000000..de4af6ac10
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-helper.js
@@ -0,0 +1,214 @@
+"use strict";
+
+function createDocument(documentType, result, inlineOrExternal, type, hasBlockingStylesheet) {
+ return new Promise((resolve, reject) => {
+ const iframe = document.createElement("iframe");
+ iframe.src =
+ "resources/moving-between-documents-iframe.py" +
+ "?result=" + result +
+ "&inlineOrExternal=" + inlineOrExternal +
+ "&type=" + type +
+ "&hasBlockingStylesheet=" + hasBlockingStylesheet +
+ "&cache=" + Math.random();
+ // As blocking stylesheets delays Document load events, we use
+ // DOMContentLoaded here.
+ // After that point, we expect iframe.contentDocument exists
+ // while still waiting for blocking stylesheet loading.
+ document.body.appendChild(iframe);
+
+ window.addEventListener('message', (event) => {
+ if (documentType === "iframe") {
+ resolve([iframe.contentWindow, iframe.contentDocument]);
+ } else if (documentType === "createHTMLDocument") {
+ resolve([
+ iframe.contentWindow,
+ iframe.contentDocument.implementation.createHTMLDocument("")]);
+ } else {
+ reject(new Error("Invalid document type: " + documentType));
+ }
+ }, {once: true});
+ });
+}
+
+window.didExecute = undefined;
+
+// For a script, there are three associated Documents that can
+// potentially different:
+//
+// [1] script's parser document
+// https://html.spec.whatwg.org/C/#parser-document
+//
+// [2] script's preparation-time document
+// https://html.spec.whatwg.org/C/#preparation-time-document
+// == script's node document at the beginning of #prepare-a-script
+//
+// [3] script's node document at the beginning of
+// #execute-the-script-block
+//
+// This helper is for tests where [1]/[2]/[3] are different.
+
+// In the spec, scripts are executed only if [1]/[2]/[3] are all the same
+// (or [1] is null and [2]==[3]).
+//
+// A check for [1]==[2] is in #prepare-a-script and
+// a check for [1]==[3] is in #execute-the-script-block,
+// but these are under debate: https://github.com/whatwg/html/issues/2137
+//
+// A check for [2]==[3] is in #execute-the-script-block, which is added by
+// https://github.com/whatwg/html/pull/2673
+
+// timing:
+// "before-prepare":
+// A <script> is moved during parsing before #prepare-a-script.
+// [1] != [2] == [3]
+//
+// "after-prepare":
+// A <script> is moved after parsing/#prepare-a-script but
+// before #execute-the-script-block.
+// [1] == [2] != [3]
+//
+// To move such scripts, #has-a-style-sheet-that-is-blocking-scripts
+// is utilized to block inline scripts after #prepare-a-script.
+// Note: this is a corner case in the spec which might be removed
+// from the spec in the future, e.g.
+// https://github.com/whatwg/html/issues/1349
+// https://github.com/chrishtr/rendering/blob/master/stylesheet-loading-proposal.md
+//
+// TODO(domfarolino): Remove the "parsing but moved back" tests, because if a
+// <script> is moved before #prepare-a-script, per spec it should never make
+// it to #execute-the-script-block. If an implementation does not implement
+// the check in #prepare-a-script, then it will fail the "before-prepare"
+// tests, so these are not necessary.
+// "parsing but moved back"
+// A <script> is moved before #prepare-a-script, but moved back again
+// to the original Document after #prepare-a-script.
+// [1] == [3] != [2]
+//
+// destType: "iframe" or "createHTMLDocument".
+// result: "fetch-error", "parse-error", or "success".
+// inlineOrExternal: "inline" or "external" or "empty-src".
+// type: "classic" or "module".
+async function runTest(timing, destType, result, inlineOrExternal, type) {
+ const description =
+ `Move ${result} ${inlineOrExternal} ${type} script ` +
+ `to ${destType} ${timing}`;
+
+ const t = async_test("Eval: " + description);
+ const tScriptLoadEvent = async_test("<script> load: " + description);
+ const tScriptErrorEvent = async_test("<script> error: " + description);
+ const tWindowErrorEvent = async_test("window error: " + description);
+
+ // If scripts should be moved after #prepare-a-script before
+ // #execute-the-script-block, we add a style sheet that is
+ // blocking scripts.
+ const hasBlockingStylesheet =
+ timing === "after-prepare" || timing === "move-back";
+
+ const [sourceWindow, sourceDocument] = await createDocument(
+ "iframe", result, inlineOrExternal, type, hasBlockingStylesheet);
+
+ // Due to https://crbug.com/1034176, Chromium needs
+ // blocking stylesheets also in the destination Documents.
+ const [destWindow, destDocument] = await createDocument(
+ destType, null, null, null, hasBlockingStylesheet);
+
+ const scriptOnLoad =
+ tScriptLoadEvent.unreached_func("Script load event fired unexpectedly");
+ const scriptOnError = (event) => {
+ // For Firefox: Prevent window.onerror is fired due to propagation
+ // from <script>'s error event.
+ event.stopPropagation();
+
+ tScriptErrorEvent.unreached_func("Script error evennt fired unexpectedly")();
+ };
+
+ sourceWindow.didExecute = false;
+ sourceWindow.t = t;
+ sourceWindow.scriptOnLoad = scriptOnLoad;
+ sourceWindow.scriptOnError = scriptOnError;
+ sourceWindow.onerror = tWindowErrorEvent.unreached_func(
+ "Window error event shouldn't fired on source window");
+ sourceWindow.readyToEvaluate = false;
+
+ destWindow.didExecute = false;
+ destWindow.t = t;
+ destWindow.scriptOnLoad = scriptOnLoad;
+ destWindow.scriptOnError = scriptOnError;
+ destWindow.onerror = tWindowErrorEvent.unreached_func(
+ "Window error event shouldn't fired on destination window");
+ destWindow.readyToEvaluate = false;
+
+ // t=0 sec: Move between documents before #prepare-a-script.
+ // At this time, the script element is not yet inserted to the DOM.
+ if (timing === "before-prepare" || timing === "move-back") {
+ destDocument.body.appendChild(
+ sourceDocument.querySelector("streaming-element"));
+ }
+ if (timing === "before-prepare") {
+ sourceWindow.readyToEvaluate = true;
+ destWindow.readyToEvaluate = true;
+ }
+
+ // t=1 sec: the script element is inserted to the DOM, i.e.
+ // #prepare-a-script is triggered (see monving-between-documents-iframe.py).
+ // In the case of `before-prepare`, the script can be evaluated.
+ // In other cases, the script evaluation is blocked by a style sheet.
+ await new Promise(resolve => step_timeout(resolve, 2000));
+
+ // t=2 sec: Move between documents after #prepare-a-script.
+ if (timing === "after-prepare") {
+ // At this point, the script hasn't been moved yet, so we'll move it for the
+ // first time, after #prepare-a-script, but before #execute-the-script-block.
+ destDocument.body.appendChild(
+ sourceDocument.querySelector("streaming-element"));
+ } else if (timing === "move-back") {
+ // At this point the script has already been moved to the destination block
+ // before #prepare-a-script, so we'll move it back to the source document
+ // before #execute-the-script-block.
+ sourceDocument.body.appendChild(
+ destDocument.querySelector("streaming-element"));
+ }
+ sourceWindow.readyToEvaluate = true;
+ destWindow.readyToEvaluate = true;
+
+ // t=3 or 5 sec: Blocking stylesheet and external script are loaded,
+ // and thus script evaulation is unblocked.
+
+ // Note: scripts are expected to be loaded at t=3, because the fetch
+ // is started by #prepare-a-script at t=1, and the script's delay is
+ // 2 seconds. However in Chromium, due to preload scanner, the script
+ // loading might take 4 seconds, because the first request by preload
+ // scanner of the source Document takes 2 seconds (between t=1 and t=3)
+ // which blocks the second request by #prepare-a-script that takes
+ // another 2 seconds (between t=3 and t=5).
+
+ // t=6 sec: After all possible script evaluation points, test whether
+ // the script/events were evaluated/fired or not.
+ // As we have concurrent tests, a single global step_timeout() is
+ // used instead of multiple `t.step_timeout()` etc.,
+ // to avoid potential race conditions between `t.step_timeout()`s.
+ return new Promise(resolve => {
+ step_timeout(() => {
+ tWindowErrorEvent.done();
+ tScriptLoadEvent.done();
+ tScriptErrorEvent.done();
+
+ t.step_func_done(() => {
+ assert_false(sourceWindow.didExecute,
+ "The script must not have executed in source window");
+ assert_false(destWindow.didExecute,
+ "The script must not have executed in destination window");
+ })();
+ resolve();
+ }, 4000);
+ });
+}
+
+async_test(t => {
+ t.step_timeout(() => {
+ assert_equals(window.didExecute, undefined,
+ "The script must not have executed in the top-level window");
+ t.done();
+ },
+ 4000);
+}, "Sanity check around top-level Window");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py
new file mode 100644
index 0000000000..dbcfe9b8d0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/moving-between-documents-iframe.py
@@ -0,0 +1,102 @@
+import random
+import time
+
+from wptserve.utils import isomorphic_decode
+
+
+"""
+This script serves
+"""
+
+def main(request, response):
+ inlineOrExternal = request.GET.first(b"inlineOrExternal", b"null")
+ hasBlockingStylesheet = request.GET.first(b"hasBlockingStylesheet", b"true") == b"true"
+ result = request.GET.first(b"result", b"success")
+ type = u"text/javascript" if request.GET.first(b"type", b"classic") == b"classic" else u"module"
+
+ response.headers.set(b"Content-Type", b"text/html; charset=utf-8")
+ response.headers.set(b"Transfer-Encoding", b"chunked")
+ response.write_status_headers()
+
+ # Step 1: Start parsing.
+ body = u"""<!DOCTYPE html>
+ <head>
+ <script>
+ parent.postMessage("fox", "*");
+ </script>
+ """
+
+ if hasBlockingStylesheet:
+ body += u"""
+ <link rel="stylesheet" href="slow-flag-setter.py?result=css&cache=%f">
+ """ % random.random()
+
+ body += u"""
+ </head>
+ <body>
+ """
+
+ if inlineOrExternal == b"inline" or inlineOrExternal == b"external" or inlineOrExternal == b"empty-src":
+ body += u"""
+ <streaming-element>
+ """
+
+ # Trigger DOM processing
+ body += u"A" * 100000
+
+ response.writer.write(u"%x\r\n" % len(body))
+ response.writer.write(body)
+ response.writer.write(u"\r\n")
+
+ body = u""
+
+ if inlineOrExternal == b"inline":
+ time.sleep(1)
+ body += u"""
+ <script id="s1" type="%s"
+ onload="scriptOnLoad()"
+ onerror="scriptOnError(event)">
+ if (!window.readyToEvaluate) {
+ window.didExecute = "executed too early";
+ } else {
+ window.didExecute = "executed";
+ }
+ """ % type
+ if result == b"parse-error":
+ body += u"1=2 parse error\n"
+
+ body += u"""
+ </script>
+ </streaming-element>
+ """
+ elif inlineOrExternal == b"external":
+ time.sleep(1)
+ body += u"""
+ <script id="s1" type="%s"
+ src="slow-flag-setter.py?result=%s&cache=%s"
+ onload="scriptOnLoad()"
+ onerror="scriptOnError(event)"></script>
+ </streaming-element>
+ """ % (type, isomorphic_decode(result), random.random())
+ elif inlineOrExternal == b"empty-src":
+ time.sleep(1)
+ body += u"""
+ <script id="s1" type="%s"
+ src=""
+ onload="scriptOnLoad()"
+ onerror="scriptOnError(event)"></script>
+ </streaming-element>
+ """ % (type,)
+
+ # // if readyToEvaluate is false, the script is probably
+ # // wasn't blocked by stylesheets as expected.
+
+ # Trigger DOM processing
+ body += u"B" * 100000
+
+ response.writer.write(u"%x\r\n" % len(body))
+ response.writer.write(body)
+ response.writer.write(u"\r\n")
+
+ response.writer.write(u"0\r\n")
+ response.writer.write(u"\r\n")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/slow-flag-setter.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/slow-flag-setter.py
new file mode 100644
index 0000000000..20d7ed4bd0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/resources/slow-flag-setter.py
@@ -0,0 +1,29 @@
+
+import time
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+
+ result = request.GET.first(b"result", b"success")
+ if result == b"css":
+ time.sleep(3)
+ headers = [(b"Content-Type", b"text/css")]
+ body = u""
+ else:
+ time.sleep(2)
+
+ body = u"""
+ fetch('exec');
+ console.log('exec');
+ if (!window.readyToEvaluate) {
+ window.didExecute = "executed too early";
+ } else {
+ window.didExecute = "executed";
+ }
+ """
+ if result == b"parse-error":
+ body = u"1=2 parse error;"
+ if result == b"fetch-error":
+ return 404, [(b'Content-Type', b'text/plain')], u"""window.didExecute = "fetch error";"""
+
+ return headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/tools/generate.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/tools/generate.py
new file mode 100644
index 0000000000..80a655e821
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/moving-between-documents/tools/generate.py
@@ -0,0 +1,61 @@
+template = '''<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>Moving script elements between documents</title>
+<!-- This is generated by tools/generate.py. Do not manually edit. -->
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/moving-between-documents-helper.js"></script>
+
+<body>
+<script>
+runTest("%s", "%s", "%s", "%s", "%s");
+</script>
+'''
+
+n = 0
+for timing in ["before-prepare", "after-prepare", "move-back"]:
+ for destType in ["iframe", "createHTMLDocument"]:
+ for inlineOrExternal in ["inline", "external", "empty-src"]:
+ for result in ["fetch-error", "parse-error", "success"]:
+ for type in ["classic", "module"]:
+ # The |inlineOrExternal| keyword creates a certain kind of script,
+ # and the |result| keyword can influence the generated script in
+ # different ways i.e., giving the script a parse-error, or creating
+ # a script that fails to load. When we're creating an inline script,
+ # it doesn't make sense to test the fetch-error case, so we ignore
+ # this combination, as the server will not react to it in any
+ # meaningful way.
+ if inlineOrExternal == "inline" and result == "fetch-error":
+ continue
+
+ if inlineOrExternal == "empty-src":
+ # The "empty-src" tests aim to exercise #prepare-a-script step 26
+ # substep 2, where the <script> has a src attribute that is empty:
+ # "If src is the empty string, queue a task to fire an event named
+ # error at the element, and return."
+ # Therefore, the server will generate a script that does not have a
+ # "parse-error" or "fetch-error", so we can ignore these combinations.
+ if result != "success":
+ continue
+
+ # The "empty-src" tests check that the parser document <=> node document
+ # check is implemented correctly in #prepare-a-script. Therefore we're
+ # only interested in tests that move the <script> before #prepare-a-script.
+ if timing != "before-prepare":
+ continue
+
+ # The current test helper uses
+ # #has-a-style-sheet-that-is-blocking-scripts to block script
+ # evaluation after #prepare-a-script, but in some cases this
+ # doesn't work:
+ # - inline scripts to createHTMLDocument
+ if timing != "before-prepare" and destType == "createHTMLDocument" and inlineOrExternal == "inline":
+ continue
+ # - module inline scripts https://github.com/whatwg/html/issues/3890
+ if timing != "before-prepare" and inlineOrExternal == "inline" and type == "module":
+ continue
+
+ with open('%s-%s-%s-%s-%s.html' % (timing, destType, result, inlineOrExternal, type), 'w') as f:
+ f.write(template % (timing, destType, result, inlineOrExternal, type))
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors-iframe.html
new file mode 100644
index 0000000000..255e79e191
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors-iframe.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<script src="cacheable-script-throw.py?iframe"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors.sub.html
new file mode 100644
index 0000000000..61643c5f08
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/muted-errors.sub.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<title>Muted Errors</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error
+// If script's muted errors is true, then set message to "Script error.",
+// urlString to the empty string, line and col to 0, and errorValue to null.
+ setup({allow_uncaught_exception: true});
+
+ window.log = [];
+ window.addEventListener("error", ev => log.push(ev));
+
+ function check(shouldBeMuted) {
+ assert_equals(log.length, 1);
+ var ev = log[0];
+ log = [];
+ if (shouldBeMuted) {
+ assert_equals(ev.message, "Script error.");
+ assert_equals(ev.error, null, 'error');
+ assert_equals(ev.filename, "", 'filename');
+ assert_equals(ev.lineno, 0, 'lineno');
+ assert_equals(ev.colno, 0, 'colno');
+ } else {
+ assert_not_equals(ev.message, "Script error.");
+ assert_not_equals(ev.error, null);
+ }
+ }
+
+ var test1 = async_test("Errors for same-origin script shouldn't be muted");
+ var check1 = test1.step_func_done(() => check(false));
+
+ var test2 = async_test("Errors for cross-origin script should be muted");
+ var check2 = test2.step_func_done(() => check(true));
+
+ var test3 = async_test("Errors for cross-origin script should be muted " +
+ "even if the script is once loaded as same-origin");
+ function step3() {
+ var script = document.createElement('script');
+ script.setAttribute('src', "//{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py?iframe");
+ script.onerror = test3.unreached_func();
+ script.onload = test3.step_func_done(() => check(true));
+ document.body.appendChild(script);
+ }
+
+ var test4 = async_test("Errors for same-origin scripts redirected to a " +
+ "cross-origin url and redirected back to " +
+ "same-origin should be muted");
+ var check4 = test4.step_func_done(() => check(true));
+
+ var test5 = async_test("Errors for cross-origin scripts redirected to a " +
+ "same-origin url should be muted");
+ var check5 = test5.step_func_done(() => check(true));
+
+ const test6 = async_test("Non-synthetic errors for same-origin scripts redirected to a " +
+ "cross-origin URL and redirected back to same-origin should be " +
+ "muted");
+ const check6 = test6.step_func_done(() => check(true));
+
+ const test7 = async_test("Syntax error for same-origin script redirected to a " +
+ "cross-origin URL and redirected back to same-origin should be " +
+ "muted");
+ const check7 = test7.step_func_done(() => check(true));
+
+ function unreachable() { log.push("unexpected"); }
+</script>
+<script src="cacheable-script-throw.py" onerror="test1.unreached_func()()" onload="check1()"></script>
+<script src="//{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py"
+ onerror="test2.unreached_func()()" onload="check2()"></script>
+<iframe src="//{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/muted-errors-iframe.html"
+ onerror="test3.unreached_func()()" onload="step3()"></iframe>
+<script src="/fetch/api/resources/redirect.py?location=
+//{{domains[www2]}}:{{ports[http][0]}}/fetch/api/resources/redirect.py?location=
+//{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py?same-cross-same"
+onerror="test4.unreached_func()()" onload="check4()"></script>
+<script src="//{{domains[www2]}}:{{ports[http][0]}}/fetch/api/resources/redirect.py?location=
+//{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/cacheable-script-throw.py?cross-same"
+onerror="test5.unreached_func()()" onload="check5()"></script>
+<script src="//{{domains[www2]}}:{{ports[http][0]}}/fetch/api/resources/redirect.py?location=
+//{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/resources/throw.js"
+onerror="test6.unreached_func()()" onload="check6()"></script>
+<script src="//{{domains[www2]}}:{{ports[http][0]}}/fetch/api/resources/redirect.py?location=
+//{{host}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/resources/syntax-error.js"
+onerror="test7.unreached_func()()" onload="check7()"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-reflect.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-reflect.html
new file mode 100644
index 0000000000..d6a850f58f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-reflect.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>noModule IDL attribute must reflect nomodule content attribute</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script id="classicWithoutNomodule"></script>
+<script id="classicWithNomodule" nomodule></script>
+<script id="moduleWithoutNomodule" type=module></script>
+<script id="moduleWithNomodule" type=module nomodule></script>
+<script>
+
+test(() => {
+ assert_false(document.getElementById('classicWithoutNomodule').noModule);
+}, 'noModule IDL attribute on a parser created classic script element without nomodule content attribute');
+
+test(() => {
+ assert_true(document.getElementById('classicWithNomodule').noModule);
+}, 'noModule IDL attribute on a parser created classic script element with nomodule content attribute');
+
+test(() => {
+ assert_false(document.getElementById('moduleWithoutNomodule').noModule);
+}, 'noModule IDL attribute on a parser created module script element without nomodule content attribute');
+
+test(() => {
+ assert_true(document.getElementById('moduleWithNomodule').noModule);
+}, 'noModule IDL attribute on a parser created module script element with nomodule content attribute');
+
+
+test(() => {
+ const script = document.createElement('script');
+ assert_false(script.noModule);
+}, 'noModule IDL attribute on a dynamically created script element without nomodule content attribute');
+
+test(() => {
+ const script = document.createElement('script');
+ script.setAttribute('nomodule', 'nomodule');
+ assert_true(script.noModule);
+}, 'noModule IDL attribute on a dynamically created script element after nomodule content attribute is set to "nomodule"');
+
+test(() => {
+ const script = document.createElement('script');
+ script.setAttribute('nomodule', '');
+ assert_true(script.noModule);
+}, 'noModule IDL attribute on a dynamically created script element after nomodule content attribute is set to ""');
+
+test(() => {
+ const script = document.createElement('script');
+ script.setAttribute('nomodule', 'nomodule');
+ assert_true(script.noModule);
+ script.removeAttribute('nomodule');
+ assert_false(script.noModule);
+}, 'noModule IDL attribute on a dynamically created script element after nomodule content attribute had been removed');
+
+test(() => {
+ const script = document.createElement('script');
+ assert_false(script.hasAttribute('nomodule'));
+ script.noModule = true;
+ assert_true(script.hasAttribute('nomodule'));
+}, 'noModule IDL attribute must add nomodule content attribute on setting to true');
+
+test(() => {
+ const script = document.createElement('script');
+ script.setAttribute('nomodule', 'nomodule');
+ script.noModule = false;
+ assert_false(script.hasAttribute('nomodule'));
+}, 'noModule IDL attribute must remove nomodule content attribute on setting to false');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html
new file mode 100644
index 0000000000..25de796830
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>External classic scripts with nomodule content attribute must not run</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!-- Load this script synchronously to ensure test cases below can load it in 200ms -->
+<script src="resources/set-script-executed.js"></script>
+</head>
+<body>
+<script>
+let supportsNoModule = "noModule" in document.getElementsByTagName("script")[0];
+
+waitForLoadEvent = new Promise((resolve) => {
+ window.onload = resolve;
+});
+
+promise_test(() => {
+ window.executed = false;
+ let loaded = false;
+ let errored = false;
+
+ let script = document.createElement('script');
+
+ script.src = './resources/set-script-executed.js';
+ script.onload = () => loaded = true;
+ script.onerror = () => errored = true;
+ script.noModule = false;
+ document.body.appendChild(script);
+
+ return waitForLoadEvent.then(() => {
+ assert_true(supportsNoModule);
+ assert_true(executed);
+ assert_true(loaded);
+ assert_false(errored);
+ });
+}, 'An asynchronously loaded classic script with noModule set to false must run');
+
+promise_test(() => {
+ window.executed = false;
+ let loaded = false;
+ let errored = false;
+
+ let script = document.createElement('script');
+ script.src = './resources/set-script-executed.js';
+ script.onload = () => loaded = true;
+ script.onerror = () => errored = true;
+ script.noModule = true;
+ document.body.appendChild(script);
+
+ return waitForLoadEvent.then(() => {
+ assert_true(supportsNoModule);
+ assert_false(executed);
+ assert_false(loaded);
+ assert_false(errored);
+ });
+}, 'An asynchronously loaded classic script with noModule set to true must not run');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script.html
new file mode 100644
index 0000000000..138b33c9fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>An external module script with nomodule must run</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script nomodule type="module" src="./resources/exports-cocoa.js"></script>
+<script>
+
+waitForLoadEvent = new Promise((resolve) => {
+ window.onload = resolve;
+});
+
+promise_test(() => {
+ return waitForLoadEvent.then(() => {
+ assert_equals(typeof cocoa, 'undefined');
+ assert_equals(typeof exportedCocoa, 'object');
+ assert_equals(exportedCocoa.taste(), 'awesome');
+ });
+}, 'An external module script with nomodule content attribute must run');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts.html
new file mode 100644
index 0000000000..588d59975c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Inline classic scripts with nomodule content attribute must not run</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+window.executed = true;
+</script>
+<script>
+
+test(() => {
+ assert_true(executed);
+}, 'An inline classic script without nomodule content attribute must run');
+
+
+window.executed = false;
+</script>
+<script nomodule>
+window.executed = true;
+</script>
+<script>
+
+test(() => {
+ assert_false(executed);
+}, 'An inline classic script with nomodule content attribute must not run');
+
+</script>
+<script>
+
+test(() => {
+ window.executed = false;
+ const element = document.createElement("script");
+ element.noModule = false;
+ element.textContent = `window.executed = true`;
+ document.body.appendChild(element);
+ assert_true(window.executed);
+}, 'An inline classic script element dynamically inserted after noModule was set to false must run.');
+
+test(() => {
+ window.executed = false;
+ const element = document.createElement("script");
+ element.noModule = true;
+ element.textContent = `window.executed = true`;
+ document.body.appendChild(element);
+ assert_false(window.executed);
+}, 'An inline classic script element dynamically inserted after noModule was set to true must not run.');
+
+window.executed = false;
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-module-script.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-module-script.html
new file mode 100644
index 0000000000..b11c25932e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-module-script.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>An inline module script with nomodule must run</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script nomodule type="module">
+import Cocoa from "./resources/cocoa-module.js";
+var cocoa = new Cocoa();
+window.exportedCocoa = cocoa;
+</script>
+<script>
+
+waitForLoadEvent = new Promise((resolve) => {
+ window.onload = resolve;
+});
+
+promise_test(() => {
+ return waitForLoadEvent.then(() => {
+ assert_equals(typeof cocoa, 'undefined');
+ assert_equals(typeof exportedCocoa, 'object');
+ assert_equals(exportedCocoa.taste(), 'awesome');
+ });
+}, 'An inline module script with nomodule content attribute must run');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html
new file mode 100644
index 0000000000..9f6207c9a5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>External classic scripts with nomodule content attribute must not run</title>
+<link rel="author" title="Yusuke Suzuki" href="mailto:utatane.tea@gmail.com">
+<link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+window.executed = false;
+window.loaded = false;
+window.errored = false;
+</script>
+<script src="./resources/set-script-executed.js" onload="loaded = true" onerror="errored = false"></script>
+<script>
+
+test(() => {
+ assert_true(executed);
+ assert_true(loaded);
+ assert_false(errored);
+}, 'A synchronously loaded external classic script without nomodule content attribute must run');
+
+window.executed = false;
+window.loaded = false;
+window.errored = false;
+</script>
+<script nomodule src="./resources/set-script-executed.js" onload="loaded = true" onerror="errored = false"></script>
+<script>
+
+test(() => {
+ assert_false(executed);
+ assert_false(loaded);
+ assert_false(errored);
+}, 'A synchronously loaded external classic script with nomodule content attribute must not run');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/promise-reject-and-remove.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/promise-reject-and-remove.html
new file mode 100644
index 0000000000..a3b2730e56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/promise-reject-and-remove.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async_test(t => {
+ window.onload = t.step_func_done();
+}, 'Removing iframe in promise reject handler should not crash');
+</script>
+<iframe src="resources/promise-reject-and-remove-iframe.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16be.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16be.js
new file mode 100644
index 0000000000..8a529e10b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16be.js
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16le.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16le.js
new file mode 100644
index 0000000000..578f7f1951
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-16le.js
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-8.js
new file mode 100644
index 0000000000..fb88bdda2a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/bom-utf-8.js
@@ -0,0 +1,2 @@
+// JavaScript file with UTF-8 BOM.
+window.executed_utf8_bom = '三æ‘ã‹ãªå­';
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cocoa-module.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cocoa-module.js
new file mode 100644
index 0000000000..24360a7bfe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cocoa-module.js
@@ -0,0 +1,5 @@
+export default class Cocoa {
+ taste() {
+ return "awesome";
+ }
+};
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py
new file mode 100644
index 0000000000..abac1901b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py
@@ -0,0 +1,20 @@
+def main(request, response):
+ origin = request.headers.get(b"origin")
+
+ if origin is not None:
+ response.headers.set(b"Access-Control-Allow-Origin", origin)
+ response.headers.set(b"Access-Control-Allow-Methods", b"GET")
+ response.headers.set(b"Access-Control-Allow-Credentials", b"true")
+
+ if request.method == u"OPTIONS":
+ return u""
+
+ headers = [(b"Content-Type", b"text/javascript")]
+ milk = request.cookies.first(b"milk", None)
+
+ if milk is None:
+ return headers, u"var included = false;"
+ elif milk.value == b"yes":
+ return headers, u"var included = true;"
+
+ return headers, u"var included = false;"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/exports-cocoa.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/exports-cocoa.js
new file mode 100644
index 0000000000..02967bc631
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/exports-cocoa.js
@@ -0,0 +1,3 @@
+import Cocoa from "./cocoa-module.js";
+var cocoa = new Cocoa();
+window.exportedCocoa = cocoa;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/flag-setter.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/flag-setter.js
new file mode 100644
index 0000000000..3274e5bfeb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/flag-setter.js
@@ -0,0 +1,3 @@
+"use strict";
+
+window.didExecute = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events-helpers.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events-helpers.js
new file mode 100644
index 0000000000..bbd6b09c6c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events-helpers.js
@@ -0,0 +1,47 @@
+"use strict";
+// Helper functions to be used from load-error-events*.html tests.
+
+function event_test(name, load_to_be_fired, error_to_be_fired) {
+ return {
+ test: async_test(name),
+ executed: false,
+ load_event_to_be_fired: load_to_be_fired,
+ error_event_to_be_fired: error_to_be_fired
+ };
+}
+
+// Should be used as load/error event handlers of script tags,
+// with |t| = the object returned by event_test().
+function onLoad(t) {
+ t.test.step(function() {
+ if (t.load_event_to_be_fired) {
+ assert_true(t.executed,
+ 'Load event should be fired after script execution');
+ // Delay done() a little so that if an error event happens
+ // the assert_unreached is reached and fails the test.
+ t.test.step_timeout(() => t.test.done(), 100);
+ } else {
+ assert_unreached('Load event should not be fired.');
+ }
+ });
+};
+function onError(t) {
+ t.test.step(function() {
+ if (t.error_event_to_be_fired) {
+ assert_false(t.executed);
+ // Delay done() a little so that if a load event happens
+ // the assert_unreached is reached and fails the test.
+ t.test.step_timeout(() => t.test.done(), 100);
+ } else {
+ assert_unreached('Error event should not be fired.');
+ }
+ });
+};
+
+// To be called from inline scripts, which expect no load/error events.
+function onExecute(t) {
+ t.executed = true;
+ // Delay done() a little so that if a load/error event happens
+ // the assert_unreached is reached and fails the test.
+ t.test.step_timeout(() => t.test.done(), 100);
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events.py
new file mode 100644
index 0000000000..1eb82cd497
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/load-error-events.py
@@ -0,0 +1,15 @@
+import re
+
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ test = request.GET.first(b'test')
+ assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+ if test.find(b'_load') >= 0:
+ status = 200
+ content = b'"use strict"; %s.executed = true;' % test
+ else:
+ status = 404
+ content = b'"use strict"; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+ return status, headers, content
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/promise-reject-and-remove-iframe.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/promise-reject-and-remove-iframe.html
new file mode 100644
index 0000000000..6da274469f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/promise-reject-and-remove-iframe.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+const promise = Promise.reject();
+
+window.onload = () => {
+ promise.catch(() => parent.document.querySelector('iframe').remove());
+};
+</script>
+
+<!-- Load a slow script to delay window.onload for a while.
+ Without this, crashes are flaky. -->
+<script src="/common/slow.py"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/script-type-and-language-js.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/script-type-and-language-js.js
new file mode 100644
index 0000000000..d357bc4994
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/script-type-and-language-js.js
@@ -0,0 +1,141 @@
+function testAttribute(attr, val, shouldRun) {
+ test(function() {
+ assert_false(window.ran, "ran variable not reset");
+ let script;
+ if (document.contentType === 'image/svg+xml') {
+ // SVG
+ script = document.createElementNS("http://www.w3.org/2000/svg", "script");
+ } else {
+ // HTML or XHTML
+ script = document.createElement("script");
+ }
+ script.setAttribute(attr, val);
+ script.textContent = "window.ran = true;";
+ document.querySelector('#script-placeholder').appendChild(script);
+ assert_equals(window.ran, shouldRun);
+ }, "Script should" + (shouldRun ? "" : "n't") + " run with " + attr + "=" +
+ format_value(val));
+ window.ran = false;
+}
+function testTypeShouldRun(type) {
+ testAttribute("type", type, true);
+}
+function testLanguageShouldRun(lang) {
+ testAttribute("language", lang, true);
+}
+function testTypeShouldNotRun(type) {
+ testAttribute("type", type, false);
+}
+function testLanguageShouldNotRunUnlessSVG(lang) {
+ // In SVGs, there is no concrete spec but all browsers agree that
+ // language attributes have no effects and thus script elements
+ // without type attributes are always expected to run regardless of
+ // language attributes.
+ const expectedToRun = document.contentType === 'image/svg+xml';
+ testAttribute("language", lang, expectedToRun);
+}
+
+// Unlike `test*()` methods above, there should be a (parser-inserted) script
+// with an invalid type/language that would set `window.ran` to true just
+// before `testParserInsertedDidNotRun()`, and
+// `testParserInsertedDidNotRun()` asserts that the script did not run.
+// `window.ran` should be reset where needed. For example:
+// <script>window.ran = false;</script>
+// <script type="invalid-type">window.ran = true;</script>
+// <script>testParserInsertedDidNotRun('type=invalid-type');</script>
+function testParserInsertedDidNotRun(description) {
+ test(() => assert_false(window.ran),
+ "Script shouldn't run with " + description + " (parser-inserted)");
+ window.ran = false;
+}
+
+// When prefixed by "application/", these match with
+// https://mimesniff.spec.whatwg.org/#javascript-mime-type
+const application = [
+ "ecmascript",
+ "javascript",
+ "x-ecmascript",
+ "x-javascript"
+];
+
+// When prefixed by "text/", these match with
+// https://mimesniff.spec.whatwg.org/#javascript-mime-type
+const text = [
+ "ecmascript",
+ "javascript",
+ "javascript1.0",
+ "javascript1.1",
+ "javascript1.2",
+ "javascript1.3",
+ "javascript1.4",
+ "javascript1.5",
+ "jscript",
+ "livescript",
+ "x-ecmascript",
+ "x-javascript"
+];
+
+const legacyTypes = [
+ "javascript1.6",
+ "javascript1.7",
+ "javascript1.8",
+ "javascript1.9"
+];
+
+const spaces = [" ", "\t", "\n", "\r", "\f"];
+
+window.ran = false;
+
+// Type attribute
+
+testTypeShouldRun("");
+testTypeShouldNotRun(" ");
+
+application.map(t => "application/" + t).forEach(testTypeShouldRun);
+application.map(t => ("application/" + t).toUpperCase()).forEach(
+ testTypeShouldRun);
+
+spaces.forEach(function(s) {
+ application.map(t => "application/" + t + s).forEach(testTypeShouldRun);
+ application.map(t => s + "application/" + t).forEach(testTypeShouldRun);
+});
+
+application.map(t => "application/" + t + "\0").forEach(testTypeShouldNotRun);
+application.map(t => "application/" + t + "\0foo").forEach(
+ testTypeShouldNotRun);
+
+text.map(t => "text/" + t).forEach(testTypeShouldRun);
+text.map(t => ("text/" + t).toUpperCase()).forEach(testTypeShouldRun);
+
+legacyTypes.map(t => "text/" + t).forEach(testTypeShouldNotRun);
+
+spaces.forEach(function(s) {
+ text.map(t => "text/" + t + s).forEach(testTypeShouldRun);
+ text.map(t => s + "text/" + t).forEach(testTypeShouldRun);
+});
+
+text.map(t => "text/" + t + "\0").forEach(testTypeShouldNotRun);
+text.map(t => "text/" + t + "\0foo").forEach(testTypeShouldNotRun);
+
+text.forEach(testTypeShouldNotRun);
+legacyTypes.forEach(testTypeShouldNotRun);
+
+// Language attribute
+
+testLanguageShouldRun("");
+testLanguageShouldNotRunUnlessSVG(" ");
+
+text.forEach(testLanguageShouldRun);
+text.map(t => t.toUpperCase()).forEach(testLanguageShouldRun);
+
+legacyTypes.forEach(testLanguageShouldNotRunUnlessSVG);
+
+spaces.forEach(function(s) {
+ text.map(t => t + s).forEach(testLanguageShouldNotRunUnlessSVG);
+ text.map(t => s + t).forEach(testLanguageShouldNotRunUnlessSVG);
+});
+text.map(t => t + "xyz").forEach(testLanguageShouldNotRunUnlessSVG);
+text.map(t => "xyz" + t).forEach(testLanguageShouldNotRunUnlessSVG);
+
+text.map(t => t + "\0").forEach(testLanguageShouldNotRunUnlessSVG);
+text.map(t => t + "\0foo").forEach(testLanguageShouldNotRunUnlessSVG);
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/set-script-executed.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/set-script-executed.js
new file mode 100644
index 0000000000..a6095097dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/set-script-executed.js
@@ -0,0 +1 @@
+window.executed = true;
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/syntax-error.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/syntax-error.js
new file mode 100644
index 0000000000..40dc81dcfa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/syntax-error.js
@@ -0,0 +1 @@
+This cannot be parsed as JavaScript
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/throw.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/throw.js
new file mode 100644
index 0000000000..be53dd1ef3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/throw.js
@@ -0,0 +1 @@
+document.querySelector(":::not-going-to-be-valid");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html
new file mode 100644
index 0000000000..c5ac0d0a62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Script @type: unknown parameters</title>
+ <link rel="author" title="askalski" href="github.com/askalski">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <div id="log"></div>
+
+ <!-- "Step1" tests -->
+ <!-- charset is set incorrectly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a correct setting in "charset" attribute of script tag.
+ -->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=utf-8" charset="windows-1250">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the file charset is set incorrectly
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+ <!-- charset is set correctly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a incorrect setting in "charset" attribute of script tag.
+ -->
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=windows-1250" charset="utf-8">
+ </script>
+ <script>
+ //the charset is set correctly via Content Type "text/javascript;charset=windows-1250" in respones
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- end of step1 tests, now step2 tests -->
+ <!-- in this case, the response's Content Type does not bring charset information.
+ Second step takes block character encoding if available.-->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript" charset="utf-8">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the file charset is set incorrectly in "charset" tag of <script> above
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+ <!-- charset is set correctly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a incorrect setting in "charset" attribute of script tag.
+ -->
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript" charset="windows-1250">
+ </script>
+ <script>
+ //the charset is set correctly via content attribute in <script> above
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- end of step2 tests, now step3 tests -->
+ <!-- in this case, neither response's Content Type nor charset attribute bring correct charset information.
+ Third step takes this document's character encoding (declared correctly as UTF-8).-->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the tested file is in windows-1250, and document is utf-8
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript">
+ </script>
+ <script>
+ //these strings should match, both document and tested file are utf-8
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- the last portion of tests (step4) are in file script-charset-02.html
+
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html
new file mode 100644
index 0000000000..63cbe838e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<head>
+ <title>Script encoding for document encoding windows-1250</title>
+ <link rel="author" title="askalski" href="github.com/askalski">
+ <link rel="author" title="Aaqa Ishtyaq" href="github.com/aaqaishtyaq">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <div id="log"></div>
+ <!-- to avoid conflating tests for script encoding declaring the encoding at the top of file. i.e, windows-1250-->
+ <meta charset="windows-1250">
+ <script>
+ test(function() {
+ assert_equals(document.characterSet, "windows-1250")
+ }, "assumption: document encoding is windows-1250");
+ </script>
+
+ <!-- in this case, neither response's Content Type nor charset attribute bring correct charset information.
+ -->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript">
+ </script>
+
+ <script>
+ test(function() {
+ //these string should match since, windows-1250 is the fallback encoding.
+ assert_equals(window.getSomeString(), "\u015b\u0107\u0105\u017c\u017a");
+ }, "windows-1250 script decoded using document encoding (also windows-1250)");
+ </script>
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript">
+ </script>
+ <script>
+ //these strings should match, since this string is the result of decoding the utf-8 text as windows-1250.
+ test(function() {
+ assert_equals(window.getSomeString(), "\u0139\u203a\xc4\u2021\xc4\u2026\u0139\u013d\u0139\u015f");
+ }, "UTF-8 script decoded using document encoding (windows-1250)");
+ </script>
+
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html
new file mode 100644
index 0000000000..4ff4cc6b0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+<title>Script changing @charset</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+async_test(function() {
+ var s = document.createElement("script");
+ s.src = "external-script-windows1250.js";
+ s.charset = "windows-1250";
+ document.body.appendChild(s);
+ s.charset = "utf-8";
+ window.onload = this.step_func_done(function() {
+ assert_equals(window.getSomeString(), "\u015b\u0107\u0105\u017c\u017a");
+ });
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.sub.html
new file mode 100644
index 0000000000..5886ab6f32
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.sub.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTMLScriptElement: crossorigin attribute network test</title>
+<link rel="author" title="KiChjang" href="mailto:kungfukeith11@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+ <script type="text/javascript">
+ var test1 = async_test("same-origin use-credentials");
+ var test2 = async_test("same-origin invalid");
+ var test3 = async_test("same-origin missing");
+ var test4 = async_test("cross-origin use-credentials");
+ var test5 = async_test("cross-origin invalid");
+ var test6 = async_test("cross-origin missing");
+ var test7 = async_test("cross-origin use-credentials mixed case");
+ var test8 = async_test("cross-origin use-credentials non-ASCII");
+
+ var same = "resources/cross-origin.py";
+ var cross = new URL(same, location);
+ cross.port = {{ports[http][1]}};
+
+ var script1 = document.createElement("script");
+ script1.src = same;
+ script1.crossOrigin = "use-credentials";
+
+ var script2 = document.createElement("script");
+ script2.src = same;
+ script2.crossOrigin = "gibberish";
+
+ var script3 = document.createElement("script");
+ script3.src = same;
+
+ var script4 = document.createElement("script");
+ script4.src = cross;
+ script4.crossOrigin = "use-credentials";
+
+ var script5 = document.createElement("script");
+ script5.src = cross;
+ script5.crossOrigin = "gibberish";
+
+ var script6 = document.createElement("script");
+ script6.src = cross;
+
+ var script7 = document.createElement("script");
+ script7.src = cross;
+ script7.crossOrigin = "UsE-cReDenTiAlS";
+
+ var script8 = document.createElement("script");
+ script8.src = cross;
+ script8.crossOrigin = "uſe-credentialſ";
+
+ document.cookie = "milk=yes";
+
+ document.body.appendChild(script1);
+ script1.onload = function() {
+ test1.step(function() {
+ assert_true(included, "credentials included (credentialsMode include)");
+ test1.done();
+ });
+ };
+
+ document.body.appendChild(script2);
+ script2.onload = function() {
+ test2.step(function() {
+ assert_true(included, "credentials included (credentialsMode same-origin)");
+ test2.done();
+ });
+ };
+
+ document.body.appendChild(script3);
+ script3.onload = function() {
+ test3.step(function() {
+ assert_true(included, "credentials included (credentialsMode include)");
+ test3.done();
+ });
+ };
+
+ document.body.appendChild(script4);
+ script4.onload = function() {
+ test4.step(function() {
+ assert_true(included, "credentials included (credentialsMode include)");
+ test4.done();
+ });
+ };
+
+ document.body.appendChild(script5);
+ script5.onload = function() {
+ test5.step(function() {
+ assert_false(included, "credentials excluded (credentialsMode same-origin)");
+ test5.done();
+ });
+ };
+
+ document.body.appendChild(script6);
+ script6.onload = function() {
+ test6.step(function() {
+ assert_true(included, "credentials included (credentialsMode include)");
+ test6.done();
+ });
+ };
+
+ document.body.appendChild(script7);
+ script7.onload = function() {
+ test7.step(function() {
+ assert_true(included, "credentials included (credentialsMode include)");
+ test7.done();
+ });
+ };
+
+ document.body.appendChild(script8);
+ script8.onload = function() {
+ test8.step(function() {
+ assert_false(included, "credentials excluded (credentialsMode same-origin)");
+ test8.done();
+ });
+ };
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html
new file mode 100644
index 0000000000..52857a08ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTMLScriptElement: crossOrigin IDL attribute</title>
+<link rel="author" title="KiChjang" href="mailto:kungfukeith11@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script id="script1"></script>
+<script id="script2" crossorigin=""></script>
+<script id="script3" crossorigin="foo"></script>
+<script id="script4" crossorigin="anonymous"></script>
+<script id="script5" crossorigin="use-credentials"></script>
+<script>
+test(function() {
+ var script1 = document.getElementById("script1");
+ var script2 = document.getElementById("script2");
+ var script3 = document.getElementById("script3");
+ var script4 = document.getElementById("script4");
+ var script5 = document.getElementById("script5");
+
+ assert_equals(script1.crossOrigin, null, "Missing value default should be null");
+ assert_equals(script2.crossOrigin, "anonymous", "Empty string should map to anonymous");
+ assert_equals(script3.crossOrigin, "anonymous", "Invalid value default should be anonymous");
+ assert_equals(script4.crossOrigin, "anonymous", "anonymous should be parsed correctly");
+ assert_equals(script5.crossOrigin, "use-credentials", "use-credentials should be parsed correctly");
+
+ script1.crossOrigin = "bar";
+ assert_equals(script1.crossOrigin, "anonymous", "Setting to invalid value would default to anonymous");
+
+ script2.crossOrigin = null;
+ assert_equals(script2.crossOrigin, null, "Resetting to null should work");
+
+ script4.crossOrigin = "use-credentials";
+ assert_equals(script4.crossOrigin, "use-credentials", "Switching from anonymous to use-credentials should work");
+
+ script5.crossOrigin = "anonymous";
+ assert_equals(script5.crossOrigin, "anonymous", "Switching from use-credentials to anonymous should work");
+}, document.title);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer-xhtml.xhtml
new file mode 100644
index 0000000000..3f4a50f779
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer-xhtml.xhtml
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>XHTML Test: HTMLScriptElement - defer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta charset="utf-8" />
+</head>
+<body>
+<div id="log"></div>
+
+<script>
+
+let script_run_status = "inline";
+let t = async_test("the defer script run later");
+
+</script>
+
+<script type="text/javascript" src="defer.js" defer="defer"></script>
+
+<script>
+
+t.step(() => {
+ assert_equals(script_run_status, "inline", "the script run status");
+ script_run_status = "deferred";
+});
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer.html
new file mode 100644
index 0000000000..80eb98dc75
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-defer.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: HTMLScriptElement - defer</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+
+let script_run_status = "inline";
+let t = async_test("the defer script run later");
+
+</script>
+
+<script type="text/javascript" src="defer.js" defer></script>
+
+<script>
+
+t.step(() => {
+ assert_equals(script_run_status, "inline", "the script run status");
+ script_run_status = "deferred";
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml
new file mode 100644
index 0000000000..69c4ef1f81
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml
@@ -0,0 +1,22 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Scripts with for and event attributes</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <script>
+ var run = false;
+ </script>
+ <script for="window" event="bar">
+ // This script should not run, but should not cause a parse error either.
+ run = true;
+ </script>
+ <script>
+ test(function() {
+ assert_false(run, "Script was unexpectedly run.")
+ }, "Scripts with for and event attributes should not run.")
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html
new file mode 100644
index 0000000000..552ea7041a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<title>Scripts with for and event attributes</title>
+<link rel="author" title="Matheus Kerschbaum" href="mailto:matjk7@gmail.com">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var expected = [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ false,
+ true,
+ true,
+];
+var run = expected.map(function() { return false });
+</script>
+<script for="w&#x130;ndow" event="onload">
+run[0] = true;
+</script>
+<script for="window" event="onload x">
+run[1] = true;
+</script>
+<script for="window" event="onload(x">
+run[2] = true;
+</script>
+<script for="window" event="onload(x)">
+run[3] = true;
+</script>
+<script for="window" event="onclick">
+run[4] = true;
+</script>
+<script for="" event="onload">
+run[5] = true;
+</script>
+<script for="window" event="">
+run[6] = true;
+</script>
+<script for="" event="">
+run[7] = true;
+</script>
+<script for="&#xa0;window" event="onload">
+run[8] = true;
+</script>
+<script for="window&#xa0;" event="onload">
+run[9] = true;
+</script>
+<script for="window" event="&#xa0;onload">
+run[10] = true;
+</script>
+<script for="window" event="onload&#xa0;">
+run[11] = true;
+</script>
+<script for=" window " event=" onload ">
+run[12] = true;
+</script>
+<script for=" window " event=" onload() ">
+run[13] = true;
+</script>
+<script for="object" event="handler">
+run[14] = true;
+</script>
+<script event="handler">
+run[15] = true;
+</script>
+<script for="object">
+run[16] = true;
+</script>
+<script>
+test(function() {
+ for (var i = 0; i < run.length; ++i) {
+ test(function() {
+ var script = document.querySelectorAll("script[for], script[event]")[i];
+ assert_equals(run[i], expected[i],
+ "script for=" + format_value(script.getAttribute("for")) +
+ " event=" + format_value(script.getAttribute("event")));
+ }, "Script " + i);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml
new file mode 100644
index 0000000000..8dd9ceb9a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml
@@ -0,0 +1,36 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Script inside noembed, noframes and iframe</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+var run = [];
+</script>
+<div id="test">
+<noembed>
+<script>
+run.push("noembed");
+</script>
+</noembed>
+<noframes>
+<script>
+run.push("noframes");
+</script>
+</noframes>
+<iframe>
+<script>
+run.push("iframe");
+</script>
+</iframe>
+</div>
+<script>
+test(function() {
+ assert_array_equals(run, ["noembed", "noframes", "iframe"], "Haven't run.");
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html
new file mode 100644
index 0000000000..2f3ce2368d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Script is not executed after script thread is shutdown</title>
+<script>
+onload = function() {
+ script_executed = parent.script_executed;
+ s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.src = 'script-not-executed-after-shutdown.js?pipe=trickle(d3)';
+ document.body.appendChild(s);
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html
new file mode 100644
index 0000000000..eb4def3ec4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Script is not executed after script thread is shutdown</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="testiframe" src="script-not-executed-after-shutdown-child.html"></iframe>
+<script>
+async_test(function(t) {
+ window.script_executed = t.unreached_func("script executed in removed iframe");
+ let iframe = document.getElementById("testiframe");
+ iframe.onload = function() {
+ iframe.parentNode.removeChild(iframe);
+ };
+ setTimeout(function() {
+ t.done();
+ }, 5000);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js
new file mode 100644
index 0000000000..ccdf14c0cd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js
@@ -0,0 +1 @@
+script_executed();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py
new file mode 100644
index 0000000000..4ff5be7374
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ body = u"test2_token = \"script executed\";"
+ return 200, headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html
new file mode 100644
index 0000000000..44ad30b018
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>var test1_token = "script not executed";</script>
+<script src="script-not-found-not-executed.py"></script>
+<script>
+test(function(){
+ assert_equals(test1_token, "script not executed");
+}, "Script that 404");
+</script>
+<script>var test2_token = "script not executed";</script>
+<script src="script-not-found-not-executed-2.py"></script>
+<script>
+test(function(){
+ assert_equals(test2_token, "script executed");
+}, "Script that does not 404");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py
new file mode 100644
index 0000000000..9354d42703
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/javascript")]
+ body = u"test1_token = \"script executed\";"
+ return 404, headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html
new file mode 100644
index 0000000000..0fe39b11a8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is defined in the error event of a parser-inserted script that actually started a fetch (but just had it fail).</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "Some text");
+ });
+</script>
+<iframe src="support/script-onerror-insertion-point-1-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html
new file mode 100644
index 0000000000..6d3f3ef09e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is not defined in the error event of a
+ parser-inserted script that has an unparseable URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "text");
+ });
+</script>
+<iframe src="support/script-onerror-insertion-point-2-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html
new file mode 100644
index 0000000000..ce3ddeee65
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is defined in the load event of a parser-inserted script.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "Some text");
+ });
+</script>
+<iframe src="support/script-onload-insertion-point-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html
new file mode 100644
index 0000000000..85f2d4dcfa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Script: setting onload to a string</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var s = document.createElement("script");
+ assert_equals(s.onload, null);
+ var dummy = function() {};
+ s.onload = dummy;
+ assert_equals(s.onload, dummy);
+ s.onload = "w('load DOM appended')";
+ assert_equals(s.onload, null);
+}, "Setting onload to a string should convert to null.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-referrerpolicy-idl.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-referrerpolicy-idl.html
new file mode 100644
index 0000000000..bf01cb83b8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-referrerpolicy-idl.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> referrerPolicy IDL</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#referrer-policy-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+ test(() => {
+ const script = document.createElement('script');
+ document.body.appendChild(script);
+ assert_equals(script.referrerPolicy,"",'Missing content attribute should reflect as empty');
+ script.setAttribute('referrerpolicy','no-referrer');
+ assert_equals(script.referrerPolicy,"no-referrer",'Valid value should reflect');
+ script.setAttribute('referrerpolicy','');
+ assert_equals(script.referrerPolicy,"",'Empty string should reflect as empty');
+ script.setAttribute('referrerpolicy','invalid-value-here');
+ assert_equals(script.referrerPolicy,"",'Invalid values should reflect as empty');
+ script.referrerPolicy = 'no-referrer';
+ assert_equals(script.referrerPolicy,"no-referrer",'Valid value via IDL');
+ script.referrerPolicy = null;
+ assert_equals(script.referrerPolicy,"",'Null should reflect as empty');
+ },'Missing/invalid/null referrerPolicy should reflect as the empty string')
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-supports.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-supports.html
new file mode 100644
index 0000000000..495056fce9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-supports.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLScriptElement.supports</title>
+<link rel=help href="https://html.spec.whatwg.org/#dom-script-supports">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(typeof HTMLScriptElement.supports, 'function');
+}, 'Type of HTMLScriptElement.supports is function');
+
+test(function() {
+ assert_true(HTMLScriptElement.supports('classic'));
+}, 'HTMLScriptElement.supports resurns true for \'classic\'');
+
+test(function() {
+ assert_true(HTMLScriptElement.supports('module'));
+}, 'HTMLScriptElement.supports resurns true for \'module\'');
+
+test(function() {
+ assert_false(HTMLScriptElement.supports('application/ecmascript'));
+ assert_false(HTMLScriptElement.supports('application/javascript'));
+ assert_false(HTMLScriptElement.supports('application/x-ecmascript'));
+ assert_false(HTMLScriptElement.supports('application/x-javascript'));
+ assert_false(HTMLScriptElement.supports('text/ecmascript'));
+ assert_false(HTMLScriptElement.supports('text/javascript'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.0'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.1'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.2'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.3'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.4'));
+ assert_false(HTMLScriptElement.supports('text/javascript1.5'));
+ assert_false(HTMLScriptElement.supports('text/jscript'));
+ assert_false(HTMLScriptElement.supports('text/livescript'));
+ assert_false(HTMLScriptElement.supports('text/x-ecmascript'));
+ assert_false(HTMLScriptElement.supports('text/x-javascript'));
+}, 'HTMLScriptElement.supports returns false for JavaScript MIME types');
+
+test(function() {
+ assert_false(HTMLScriptElement.supports(''));
+ assert_false(HTMLScriptElement.supports(' '));
+ assert_false(HTMLScriptElement.supports('classic '));
+ assert_false(HTMLScriptElement.supports('module '));
+ assert_false(HTMLScriptElement.supports(' classic '));
+ assert_false(HTMLScriptElement.supports(' module '));
+ assert_false(HTMLScriptElement.supports('classics'));
+ assert_false(HTMLScriptElement.supports('modules'));
+ assert_false(HTMLScriptElement.supports('Classic'));
+ assert_false(HTMLScriptElement.supports('Module'));
+ assert_false(HTMLScriptElement.supports('unsupported'));
+}, 'HTMLScriptElement.supports returns false for unsupported types');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications-csp.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications-csp.html
new file mode 100644
index 0000000000..a991151066
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications-csp.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<head>
+<meta charset=utf-8>
+<title>Modify HTMLScriptElement's text after #prepare-a-script that violates CSP</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta http-equiv="content-security-policy" content="script-src
+ 'nonce-allow'
+ 'sha256-2+5xh6b9uuIi4GaJtmHWtgR2nwRXJpBtMY4nVaOBpfc='
+">
+<!-- The hash is that of the original content of `script0`. -->
+
+<script nonce="allow">
+window.t = async_test("Modify inline script element's text " +
+ "after prepare-a-script before evaluation (CSP)");
+
+const updatedText =
+ 't.unreached_func("CSP check was done against the original text but the updated text was evaluated")();';
+
+function changeScriptText() {
+ document.querySelector('#script0').textContent = updatedText;
+}
+
+t.step_timeout(changeScriptText, 500);
+</script>
+
+<!-- This is "a style sheet that is blocking scripts" and thus ... -->
+<link rel="stylesheet" href="/common/slow.py?pipe=trickle(d1)"></link>
+
+<!-- This inline script becomes a parser-blocking script, and thus
+the step_timeout is evaluated after script0 is inserted into DOM,
+prepare-a-script'ed, but before its evaluation. -->
+<script id="script0">
+t.step(() => {
+ // When this is evaluated after the stylesheet is loaded,
+ // script0's textContent is modified by the async script above,
+ // but the evaluated script is still the original script here,
+ // not what is overwritten, because "child text content" is taken in
+ // #prepare-a-script and passed to "creating a classic script".
+ var s = document.getElementById('script0');
+ assert_equals(s.textContent, updatedText,
+ "<script>'s textContent should be already modified");
+ t.done();
+ });
+</script>
+<script nonce="allow">
+// If this makes the test fail, it indicates `script0` (the original or updated
+// text) was not evaluated, probably blocked by CSP that was checked against the
+// updated text.
+t.unreached_func("CSP check was done against the updated text")();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications.html
new file mode 100644
index 0000000000..cb54da6995
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-modifications.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<head>
+<meta charset=utf-8>
+<title>Modify HTMLScriptElement's text after #prepare-a-script</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+var t = async_test("Modify inline script element's text " +
+ "after prepare-a-script before evaluation");
+
+function changeScriptText() {
+ document.querySelector('#script0').textContent =
+ 't.unreached_func("This should not be evaluated")();';
+}
+
+t.step_timeout(changeScriptText, 500);
+</script>
+
+<!-- This is "a style sheet that is blocking scripts" and thus ... -->
+<link rel="stylesheet" href="/common/slow.py?pipe=trickle(d1)"></link>
+
+<!-- This inline script becomes a parser-blocking script, and thus
+the step_timeout is evaluated after script0 is inserted into DOM,
+prepare-a-script'ed, but before its evaluation. -->
+<script id="script0">
+t.step(() => {
+ // When this is evaluated after the stylesheet is loaded,
+ // script0's textContent is modified by the async script above,
+ // but the evaluated script is still the original script here,
+ // not what is overwritten, because "child text content" is taken in
+ // #prepare-a-script and passed to "creating a classic script".
+ var s = document.getElementById('script0');
+ assert_equals(s.textContent,
+ 't.unreached_func("This should not be evaluated")();',
+ "<script>'s textContent should be already modified");
+ t.done();
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml
new file mode 100644
index 0000000000..33a4635db3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>HTMLScriptElement.text</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-text"/>
+<script src="/resources/testharness.js"/>
+<script src="/resources/testharnessreport.js"/>
+</head>
+<body>
+<div id="log"></div>
+<script>
+<x>7;</x>
+<![CDATA[
+ var x = "y";
+]]>
+</script>
+<script>
+var script;
+setup(function() {
+ script = document.body.getElementsByTagName("script")[0];
+})
+test(function() {
+ assert_equals(script.text, '\n\n\n var x = "y";\n\n')
+ assert_equals(script.textContent, '\n7;\n\n var x = "y";\n\n')
+}, "Getter with CDATA section")
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html
new file mode 100644
index 0000000000..6e86472246
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLScriptElement.text</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-script-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var script;
+setup(function() {
+ script = document.createElement("script")
+ script.appendChild(document.createComment("COMMENT"))
+ script.appendChild(document.createTextNode(" TEXT "))
+ script.appendChild(document.createProcessingInstruction("P", "I"))
+ script.appendChild(document.createElement("a"))
+ .appendChild(document.createTextNode("ELEMENT"))
+})
+
+test(function() {
+ assert_equals(script.text, " TEXT ")
+ assert_equals(script.textContent, " TEXT ELEMENT")
+}, "Getter")
+
+test(function() {
+ script.text = " text "
+ assert_equals(script.text, " text ")
+ assert_equals(script.textContent, " text ")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, " text ")
+ assert_equals(script.firstChild, script.lastChild)
+ assert_array_equals(script.childNodes, [script.firstChild])
+}, "Setter (non-empty string)")
+
+test(function() {
+ script.text = ""
+ assert_equals(script.text, "")
+ assert_equals(script.textContent, "")
+ assert_equals(script.firstChild, null)
+}, "Setter (empty string)")
+
+test(function() {
+ script.text = null
+ assert_equals(script.text, "null")
+ assert_equals(script.textContent, "null")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, "null")
+ assert_equals(script.firstChild, script.lastChild)
+}, "Setter (null)")
+
+test(function() {
+ script.text = undefined
+ assert_equals(script.text, "undefined")
+ assert_equals(script.textContent, "undefined")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, "undefined")
+ assert_equals(script.firstChild, script.lastChild)
+}, "Setter (undefined)")
+
+test(function() {
+ var s = document.createElement("script");
+ var text = document.createTextNode("one");
+ s.appendChild(text);
+
+ assert_equals(s.firstChild, text);
+ assert_equals(text.nodeValue, "one");
+
+ s.text = "two";
+ assert_not_equals(s.firstChild, text);
+ assert_equals(text.nodeValue, "one");
+ assert_equals(s.firstChild.nodeValue, "two");
+}, "Setter (text node reuse)")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-empty.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-empty.html
new file mode 100644
index 0000000000..6ce1b279f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-empty.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<title>Script @type and @language: empty strings</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<!-- Setup -->
+<script>
+window.run1 = window.run2 = window.run3 = window.run4 = false;
+</script>
+
+<!-- Systems under test -->
+<script type="">
+window.run1 = true;
+</script>
+
+<script type="" language="foo">
+window.run2 = true;
+</script>
+
+<script type="" language="">
+window.run3 = true;
+</script>
+
+<script language="">
+window.run4 = true;
+</script>
+
+<!-- Asserts -->
+<script>
+test(() => {
+ assert_true(window.run1);
+}, "A script with empty type and no language should run");
+
+test(() => {
+ assert_true(window.run2);
+}, "A script with empty type and a random language should run");
+
+test(() => {
+ assert_true(window.run3);
+}, "A script with empty type and empty language should run");
+
+test(() => {
+ assert_true(window.run4);
+}, "A script with no type and empty language should run");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-svg.svg b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-svg.svg
new file mode 100644
index 0000000000..2f31d4d75c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-svg.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+<metadata>
+ <h:link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages" />
+ <h:link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script" />
+</metadata>
+<h:script src="/resources/testharness.js"/>
+<h:script src="/resources/testharnessreport.js"/>
+<h:div id="script-placeholder"/>
+<h:script src="resources/script-type-and-language-js.js"/>
+<script>window.ran = false;</script>
+<script type="javascript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript');</script>
+<script type="javascript1.0">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.0');</script>
+<script type="javascript1.1">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.1');</script>
+<script type="javascript1.2">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.2');</script>
+<script type="javascript1.3">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.3');</script>
+<script type="javascript1.4">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.4');</script>
+<script type="javascript1.5">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.5');</script>
+<script type="javascript1.6">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.6');</script>
+<script type="javascript1.7">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.7');</script>
+<script type="livescript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=livescript');</script>
+<script type="ecmascript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=ecmascript');</script>
+<script type="jscript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=jscript');</script>
+</svg>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml.xhtml
new file mode 100644
index 0000000000..0bfdfce3c4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml.xhtml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Script @type and @language: JavaScript types</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="script-placeholder"/>
+<script src="resources/script-type-and-language-js.js"></script>
+
+<script>ran = false;</script>
+<script type="javascript">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript');</script>
+<script type="javascript1.0">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.0');</script>
+<script type="javascript1.1">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.1');</script>
+<script type="javascript1.2">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.2');</script>
+<script type="javascript1.3">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.3');</script>
+<script type="javascript1.4">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.4');</script>
+<script type="javascript1.5">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.5');</script>
+<script type="javascript1.6">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.6');</script>
+<script type="javascript1.7">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.7');</script>
+<script type="livescript">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=livescript');</script>
+<script type="ecmascript">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=ecmascript');</script>
+<script type="jscript">ran = true;</script>
+<script>testParserInsertedDidNotRun('type=jscript');</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js.html
new file mode 100644
index 0000000000..009123de2b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-js.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Script @type and @language: JavaScript types</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="script-placeholder"></div>
+<script src="resources/script-type-and-language-js.js"></script>
+
+<script>window.ran = false;</script>
+<script type="javascript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript');</script>
+<script type="javascript1.0">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.0');</script>
+<script type="javascript1.1">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.1');</script>
+<script type="javascript1.2">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.2');</script>
+<script type="javascript1.3">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.3');</script>
+<script type="javascript1.4">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.4');</script>
+<script type="javascript1.5">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.5');</script>
+<script type="javascript1.6">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.6');</script>
+<script type="javascript1.7">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=javascript1.7');</script>
+<script type="livescript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=livescript');</script>
+<script type="ecmascript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=ecmascript');</script>
+<script type="jscript">window.ran = true;</script>
+<script>testParserInsertedDidNotRun('type=jscript');</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-with-params.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-with-params.html
new file mode 100644
index 0000000000..977ee7d0a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-and-language-with-params.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>Script @type and @language: unknown type parameters</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<!-- Setup -->
+<script>
+window.run1 = window.run2 = window.run3 = false;
+</script>
+
+<!-- Systems under test -->
+<script type="text/javascript;charset=UTF-8">
+window.run1 = true;
+</script>
+
+<script type="text/javascript;x-test=abc">
+window.run2 = true;
+</script>
+
+<script language="javascript" type="text/javascript;charset=UTF-8">
+window.run3 = true;
+</script>
+
+<!-- Asserts -->
+<script>
+test(() => {
+ assert_false(window.run1);
+}, "A script with a charset param in its type should not run");
+
+test(() => {
+ assert_false(window.run2);
+}, "A script with an x-test param in its type should not run");
+
+test(() => {
+ assert_false(window.run3);
+}, "A script with a charset param in its type should not run, even with language=javascript");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-whitespace.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-whitespace.html
new file mode 100644
index 0000000000..5e8acb1a17
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-type-whitespace.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>&lt;script type> non-ASCII whitespace handling</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function testParserInsertedDidNotRun(description) {
+ test(() => assert_false(window.ran),
+ "Script shouldn't run with " + description + " (parser-inserted)");
+ window.ran = false;
+}
+</script>
+
+<script>window.ran = false;</script>
+<script type="text/javascript&#x000B;">window.ran = true;</script>
+<script>testParserInsertedDidNotRun("type=\"text/javascript&#x000B;\"");</script>
+
+<script type="text/javascript&#x0085;">window.ran = true;</script>
+<script>testParserInsertedDidNotRun("type=\"text/javascript&#x0085;\"");</script>
+
+<script type="text/javascript&#x00A0;">window.ran = true;</script>
+<script>testParserInsertedDidNotRun("type=\"text/javascript&#x00A0;\"");</script>
+
+<script type="text/javascript&#x1680;">window.ran = true;</script>
+<script>testParserInsertedDidNotRun("type=\"text/javascript&#x1680;\"");</script>
+
+<script type="text/javascript&#x3000;">window.ran = true;</script>
+<script>testParserInsertedDidNotRun("type=\"text/javascript&#x3000;\"");</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html
new file mode 100644
index 0000000000..a2671a78f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>JS is disabled on documents created without a browsing context</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function(t) {
+ var doc = document.implementation.createHTMLDocument();
+ window.fail_test = t.unreached_func('should not have been called');
+
+ var script = doc.createElement('script');
+ script.textContent = 'fail_test();';
+ doc.documentElement.appendChild(script);
+}, 'script on document returned by createHTMLDocument should not execute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-json-then-js.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-json-then-js.py
new file mode 100644
index 0000000000..9610734d44
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-json-then-js.py
@@ -0,0 +1,21 @@
+# Respond with valid JSON to the first request with the given key,
+# and with valid JavaScript to the second. Used for testing scenarios where
+# the same request URL results in different responses on subsequent requests.
+def main(request, response):
+ try:
+ stash_key = request.GET.first(b"key")
+
+ run_count = request.server.stash.take(stash_key)
+ if not run_count:
+ run_count = 0
+
+ if run_count == 0:
+ response.headers.set(b"Content-Type", b"text/json")
+ response.content = '{"hello": "world"}'
+ else:
+ response.headers.set(b"Content-Type", b"application/javascript")
+ response.content = "export default 'hello';"
+
+ request.server.stash.put(stash_key, run_count + 1)
+ except:
+ response.set_error(400, u"Not enough parameters")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py
new file mode 100644
index 0000000000..675b3fc3eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py
@@ -0,0 +1,17 @@
+import os
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ directory = os.path.dirname(isomorphic_decode(__file__))
+
+ try:
+ file_name = request.GET.first(b"fn")
+ content_type = request.GET.first(b"ct")
+ with open(os.path.join(directory, isomorphic_decode(file_name)), u"rb") as fh:
+ content = fh.read()
+
+ response.headers.set(b"Content-Type", content_type)
+ response.content = content
+ except:
+ response.set_error(400, u"Not enough parameters or file not found")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html
new file mode 100644
index 0000000000..d9b0c84ca4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html
@@ -0,0 +1,2 @@
+Some <script src="nosuchscripthere.js"
+ onerror="document.write('text'); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html
new file mode 100644
index 0000000000..a9ee80026a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html
@@ -0,0 +1,2 @@
+Some <script src="http://this is not parseable:-80/"
+ onerror="document.write('text'); document.close(); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html
new file mode 100644
index 0000000000..f0236b4fbb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html
@@ -0,0 +1,2 @@
+Some <script src="script-onload-insertion-point-helper.js"
+ onload="document.write('xt'); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js
new file mode 100644
index 0000000000..8a96a0b783
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js
@@ -0,0 +1 @@
+document.write("te");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html
new file mode 100644
index 0000000000..8676319b20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Parsing XHTML: Node's node document</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Parsing XHTML: Node's node document must be set to that of the element to which it will be appended">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#parsing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl"></template>';
+
+ var template = doc.querySelector('#tmpl');
+
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ assert_equals(template.ownerDocument, doc.body.ownerDocument,
+ 'Wrong template node owner document');
+ var ownerDoc = template.content.ownerDocument;
+ assert_not_equals(ownerDoc, doc, 'Wrong template content owner document');
+ assert_not_equals(ownerDoc, document, 'Wrong template content owner document');
+ assert_equals(ownerDoc.defaultView, null,
+ 'Template content owner document should not have a browsing context');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test empty template');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl"><div>Div content</div></template>';
+
+ var template = doc.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc.body.ownerDocument,
+ 'Wrong template node owner document');
+
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var div = template.content.querySelector('div');
+ assert_equals(template.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test not empty template');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = ''
+ + '<template id="tmpl"><div>Div content</div> And some more text'
+ + '<template id="tmpl2"><div>Template content</div></template>'
+ + '</template>';
+
+ var template = doc.querySelector('#tmpl');
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+ assert_not_equals(nestedTemplate, null, 'Nested template element should not be null');
+ assert_not_equals(nestedTemplate.content, undefined,
+ 'Content attribute of nested template element should not be undefined');
+ assert_not_equals(nestedTemplate.content, null,
+ 'Content attribute of nested template element should not be null');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template node owner document');
+
+
+ var div = nestedTemplate.content.querySelector('div');
+ assert_equals(nestedTemplate.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test nested templates');
+
+
+
+testInIFrame('../resources/template-child-nodes-div.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var div = template.content.querySelector('div');
+ assert_equals(template.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test loading XHTML document from a file');
+
+
+
+testInIFrame('../resources/template-child-nodes-nested.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong template node owner document');
+
+ var div = nestedTemplate.content.querySelector('div');
+ assert_equals(nestedTemplate.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test loading of XHTML document '
+ + 'with nested templates from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/tag-name.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/tag-name.xhtml
new file mode 100644
index 0000000000..a1e293d1cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/tag-name.xhtml
@@ -0,0 +1,16 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>tagName in template</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<template><div></div></template>
+<div id="log"></div>
+<script><![CDATA[
+test(function() {
+ assert_equals(document.getElementsByTagName("template")[0].content.firstChild.tagName, 'div', "tagName case");
+}, "tagName case");
+]]></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html
new file mode 100644
index 0000000000..40abda5684
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Child nodes of template element in XHTML documents</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Child nodes of template element in XHTML documents are always appended to the template content (instead of template itself)">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#parsing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl1">'
+ + '<div id="div1">This is div inside template</div>'
+ + '<div id="div2">This is another div inside template</div>'
+ + '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.childNodes.length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of template element in XHTML documents must be appended to template content');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl1">'
+ + '<div id="div1">This is div inside template</div>'
+ + '<div id="div2">This is another div inside template</div>'
+ + '<template id="tmpl2">'
+ + '<div id="div3">This is div inside nested template</div>'
+ + '<div id="div4">This is another div inside nested template</div>'
+ + '</template>' + '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.childNodes.length, 3,
+ 'Wrong number of template content child nodes');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+
+ assert_equals(nestedTemplate.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(nestedTemplate.content.childNodes.length, 2,
+ 'Wrong number of nested template content child nodes');
+
+}, 'Child nodes of nested template element in XHTML documents must be appended to template content');
+
+
+
+testInIFrame('../resources/template-child-nodes-div.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.querySelectorAll('div').length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of template element in XHTML documents must be appended to template content. '
+ + 'Test loading XHTML document from a file');
+
+
+testInIFrame('../resources/template-child-nodes-nested.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+
+ assert_equals(nestedTemplate.content.querySelectorAll('div').length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of nested template element in XHTML documents must be appended to template content. '
+ + 'Test loading XHTML document from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html
new file mode 100644
index 0000000000..416a3bc615
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: serialize template contents instead of template element</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Template contents should be serialized instead of template element if serializing template element in XHTML document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#serializing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template xmlns="http://www.w3.org/1999/xhtml"><div id="div1">some text</div></template>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element');
+
+
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ nestedTemplate.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template xmlns="http://www.w3.org/1999/xhtml"><template><div id="div1">some text</div></template></template>',
+ 'template element is serialized incorrectly');
+
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test nested template');
+
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+ doc.body = doc.createElement('body');
+ doc.body.appendChild(template);
+
+ assert_equals(doc.documentElement.outerHTML, '<html xmlns="http://www.w3.org/1999/xhtml"><body><template><div id="div1">some text</div></template></body></html>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test serializing whole document');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html
new file mode 100644
index 0000000000..55c8b2e30c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>Template Reftest Reference</title>
+<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru"/>
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html
new file mode 100644
index 0000000000..fc310f47c8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+ <title>Template Test: check that template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="Test checks that the template contents are hidden implicitly">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template>
+ <span style="color:red">Test fails if you can see this text</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html
new file mode 100644
index 0000000000..92f3d81eac
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+ <title>Template Test: check that template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="The template element itself must be hidden by default">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template style="border: 1px solid; width: 100px; height: 100px">
+ <span style="color:red">Test fails if you can see this text or border around it</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html
new file mode 100644
index 0000000000..4c477fde79
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+ <title>HTML Templates: template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="The template element itself must be hidden by default">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+ <style>
+ template {
+ border: 1px solid;
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template>
+ <span style="color:red">Test fails if you can see this text or border around it</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html
new file mode 100644
index 0000000000..c668d90953
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Clone template node: All the children of template content are copied if 'copy children flag' set to true</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="Clone template node: all the children of template content are copied if 'copy children flag' set to true">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#node-clone-additions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute should not be undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute should not be null');
+
+ assert_equals(copy.content.childNodes.length, 2,
+ 'Wrong number of template content\'s copy child nodes');
+ assert_not_equals(copy.content.querySelector('#div1'), null,
+ 'Template child node should be copied');
+ assert_not_equals(copy.content.querySelector('#div2'), null,
+ 'Template child node should be copied');
+
+}, 'Clone template node. Test call to cloneNode(true)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode();
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute should not be undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute should not be null');
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+
+}, 'Clone template node. Test call to cloneNode() with the default parameter '
+ + '(false by default)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(false);
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute is undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute is null');
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+
+}, 'Clone template node. Test call to cloneNode(false)');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html
new file mode 100644
index 0000000000..a2afc23041
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: ownerDocument of cloned template content is set to template content owner</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="ownerDocument of cloned template content is set to template content owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#node-clone-additions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+function checkOwnerDocument(node, doc) {
+ if ((node !== null) && (node !== undefined)) {
+ assert_equals(node.ownerDocument, doc,
+ 'Wrong ownerDocument of the template copy\'s node ' + node.nodeName);
+ for (var i = 0; i < node.childNodes.length; i++) {
+ if (node.childNodes[i].nodeType === Node.ELEMENT_NODE) {
+ checkOwnerDocument(node.childNodes[i], doc);
+ if (node.childNodes[i].nodeName === 'TEMPLATE') {
+ checkOwnerDocument(node.childNodes[i].content, doc);
+ }
+ }
+ }
+ }
+}
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_equals(copy.content.childNodes.length, 2,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning with children');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(false);
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning without children');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode();
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloneNode() with no arguments (false by default)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '<template id="tmpl2">' +
+ '<div id="div3">This is div inside nested template</div>' +
+ '<div id="div4">This is another div inside nested template</div>' +
+ '</template>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_equals(copy.content.childNodes.length, 3,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning nested template');
+
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+ var copy = template.cloneNode(true);
+
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test loading HTML document from file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html
new file mode 100644
index 0000000000..d063acded9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document type is HTML document</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="The template contents owner document type is HTML document, if template is declared in HTML document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.querySelector('template');
+ var content_owner = template.content.ownerDocument;
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(content_owner.createElement('DIV').localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has browsing context and the template ' +
+ 'is created by HTML parser)');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.createElement('template');
+ var content_owner = template.content.ownerDocument;
+ var div = doc.createElement('DIV');
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(div.localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has browsing context and the template ' +
+ 'is created by createElement())');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var content_owner = template.content.ownerDocument;
+ var div = doc.createElement('DIV');
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(div.localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has no browsing context and the template is created ' +
+ 'by createElement())');
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template><div>Hello!</div></template>';
+ var template = doc.querySelector('template');
+ var content_owner = template.content.ownerDocument;
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(content_owner.createElement('DIV').localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has no browsing context and the template is created via innerHTML)');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html
new file mode 100644
index 0000000000..a087f788e5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document (no browsing context)</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="Even if template's enclosing document has no browsing context, it gets its own template contents owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ doc.body.appendChild(template);
+
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template content owner');
+
+}, 'Test the template contents owner document when enclosing document has '
+ + 'no browsing content. Template element is created by createElement()');
+
+
+
+test(function() {
+ var doc = newHTMLDocument();
+
+ doc.body.innerHTML = '<template><div>some text</div></template>';
+
+ var template = doc.querySelector('template');
+
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template content owner');
+
+}, 'Test the template contents owner document when enclosing document has '
+ + 'no browsing content. Template element is created by innerHTML');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html
new file mode 100644
index 0000000000..cf2e30b643
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document (there's browsing context)</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="If template's enclosing document has browsing context, then templates content owner must be a new Document node without browsing context">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+testInIFrame(null, function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created by createElement()');
+
+
+
+testInIFrame(null, function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ doc.body.innerHTML = '<template><div>some text</div></template>';
+
+ var template = doc.querySelector('template');
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created via innerHTML');
+
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created by HTML parser');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html
new file mode 100644
index 0000000000..4a61dc8d3b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html
@@ -0,0 +1,172 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents is a DocumentFragment</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="The template contents must be a DocumentFragment">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a DocumentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (empty template)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<div>This is a div</div><span>This is a span</span>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a DocumentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template)');
+
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<div>This is a div</div>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template '
+ + 'containing div which is an Element instance)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = 'Some text';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (not empty template '
+ + 'containing text node)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<template id="t2">Some text</template>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+ var nestedTemplate = template.content.querySelector("#t2");
+ assert_equals(nestedTemplate.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Nested template content should be a documentFragment');
+
+ assert_class_string(nestedTemplate.content, 'DocumentFragment',
+ 'Nested template content class should be a DocumentFragment');
+
+
+}, 'The template contents must be a DocumentFragment (nested template '
+ + 'containing a text node)');
+
+
+testInIFrame('../resources/template-contents-empty.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+
+}, 'The template contents must be a DocumentFragment (the empty template tag '
+ + 'inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template '
+ + 'tag inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents-text.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (the template tag '
+ + 'with some text inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents-nested.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+ var nestedTemplate = template.content.querySelector("template");
+
+ assert_equals(nestedTemplate.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Nested template content should be a documentFragment');
+ assert_class_string(nestedTemplate.content, 'DocumentFragment',
+ 'Nested template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (the template tag '
+ + 'with nested template tag inside HTML file loaded in iframe)');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html
new file mode 100644
index 0000000000..0968b37f92
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: innerHTML of template element replaces all referenced by the content attribute</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="innerHTML of template element replaces all referenced by the content attribute">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#innerhtml-on-templates">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div1 = doc.createElement('div');
+ div1.setAttribute('id', 'div1');
+ template.content.appendChild(div1);
+
+ assert_not_equals(template.content.querySelector('#div1'), null,
+ 'Element should present in template content');
+
+ template.innerHTML = '<div id="div2"></div>';
+
+ assert_equals(template.content.querySelector('#div1'), null,
+ 'Template content should be replaced by innerHTML');
+ assert_not_equals(template.content.querySelector('#div2'), null,
+ 'Element should present in template content');
+
+}, 'innerHTML of template element replaces all referenced by the content attribute');
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div1 = doc.createElement('div');
+ div1.setAttribute('id', 'div1');
+ template.content.appendChild(div1);
+
+ assert_not_equals(template.content.querySelector('#div1'), null,
+ 'Element should present in template content');
+
+ template.innerHTML = '';
+
+ assert_false(template.content.hasChildNodes(),
+ 'Template content should be removed by innerHTML');
+
+}, 'innerHTML of template element replaces all referenced by the content attribute. '
+ + 'Test empty HTML string');
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div1 = doc.createElement('div');
+ div1.setAttribute('id', 'div1');
+ nestedTemplate.content.appendChild(div1);
+
+ assert_not_equals(nestedTemplate.content.querySelector('#div1'), null,
+ 'Element should present in template content');
+
+ nestedTemplate.innerHTML = '<div id="div2"></div>';
+
+ assert_equals(nestedTemplate.content.querySelector('#div1'), null,
+ 'Template content should be replaced by innerHTML');
+ assert_not_equals(nestedTemplate.content.querySelector('#div2'), null,
+ 'Element should present in template content');
+
+}, 'innerHTML of template element replaces all referenced by the content attribute. '
+ + 'Test nested template');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+ assert_not_equals(template.content.querySelector('div'), null,
+ 'Div element should present in template content');
+
+ template.innerHTML = '<span>span internals</span>';
+
+ assert_equals(template.content.querySelector('div'), null,
+ 'div element should be replaced by span in template content');
+
+ assert_not_equals(template.content.querySelector('span'), null,
+ 'span element should present in template content');
+
+
+}, 'innerHTML of template element replaces all referenced by the content attribute. '
+ + 'Test loading of HTML document from a file');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html
new file mode 100644
index 0000000000..2cb149853f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains several &lt;/template&gt; tag in HTML body without start one</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ </template>
+ <div>The file contains several &lt;/template&gt; tag in HTML body without start one</div>
+ </template></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html
new file mode 100644
index 0000000000..02d0c7be65
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ </template>
+ <title>The file contains several &lt;/template&gt; tag in HTML head without start one</title>
+ </template></template>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html
new file mode 100644
index 0000000000..b84d55595f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains frameset with the template and frameset end tag in it</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+</head>
+<frameset>
+ <template></frameset></template>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html
new file mode 100644
index 0000000000..e4e45bcea5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open div tag, but without end div tag, in the head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <div>Hello, template
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html
new file mode 100644
index 0000000000..9db2b4af06
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open table, tr, td tags, but without end td, tr, table tags, in the head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <table>
+ <tr>
+ <td>Hello, cell one!
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html
new file mode 100644
index 0000000000..0de652cf36
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html tabindex="5">
+<head>
+ <title>The file contains html root element with attributes and some in the body</title>
+ <link rel="author" title="Sergey G. Grekhovv" href="mailto:sgrekhov@unipro.ru">
+</head>
+<body>
+<template id="tmpl"><html class="htmlClass"></html></template><html id="htmlId" tabindex="5">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml
new file mode 100644
index 0000000000..14db5004dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Template tag with children div tags inside</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"/>
+</head>
+<body>
+ <p>Template tag with div tags inside</p>
+ <template>
+ <div>This is div inside template</div>
+ <div>This is another div inside template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml
new file mode 100644
index 0000000000..406fa6c3d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Template tag with children div tags inside another template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"/>
+</head>
+<body>
+ <p>Template tag with children div tags inside another template tag</p>
+ <template>
+ <template>
+ <div>This is div inside template</div>
+ <div>This is another div inside template</div>
+ </template>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html
new file mode 100644
index 0000000000..b9dd5f47a8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Empty template tag with attribute content</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template content='some text'></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html
new file mode 100644
index 0000000000..a1f246fd63
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>BODY tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><body></body></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html
new file mode 100644
index 0000000000..304acf3025
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html
new file mode 100644
index 0000000000..f1a539cc08
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Empty template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html
new file mode 100644
index 0000000000..4331367df3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>FRAMESET tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><frameset></frameset></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html
new file mode 100644
index 0000000000..1e3a337e8d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HEAD tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><head></head></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html
new file mode 100644
index 0000000000..5dd3a28e6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HTML tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><html></html></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html
new file mode 100644
index 0000000000..dc2dc6f15f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+ <title>Contains second template tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<body>
+ <template>
+ <template>
+ <div>Inside nested template</div>
+ </template>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html
new file mode 100644
index 0000000000..4639b4dc8e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open table, tr, td tags, without end td, tr, table tags</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <table>
+ <tr>
+ <td>Hello, cell one!
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html
new file mode 100644
index 0000000000..a401848efc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Some text inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>Some text</template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html
new file mode 100644
index 0000000000..07256c06a3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html
new file mode 100644
index 0000000000..d64848c8db
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html
new file mode 100644
index 0000000000..4801178454
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Template tag inside frameset</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<frameset>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html
new file mode 100644
index 0000000000..6bab00ea99
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Template tag inside head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <div>Hello, template</div>
+ </template>
+</head>
+<body>
+ Nothing interesting here
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html
new file mode 100644
index 0000000000..f6e9ab58e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains two template elements</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template id="template1">
+ <div>Hello, template</div>
+ </template>
+
+ <template id="template2">
+ <div>Hello, from second template</div>
+ </template>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html
new file mode 100644
index 0000000000..1539afbe1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: serialize template contents instead of template element</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="template contents should be serialized instead of template element if serializing template element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#serializing-html-templates">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template><div id="div1">some text</div></template>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ nestedTemplate.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template><template><div id="div1">some text</div></template></template>',
+ 'template element is serialized incorrectly');
+
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test nested template');
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+ doc.body.appendChild(template);
+
+ assert_equals(doc.documentElement.outerHTML, '<html><head><title>Test Document</title></head><body><template><div id="div1">some text</div></template></body></html>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test serializing whole document');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html
new file mode 100644
index 0000000000..b4c11b841f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Content attribute of template element is read-only</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Content attribute of template element is read-only">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test empty template');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var el1 = doc.createElement('div');
+ var el2 = doc.createElement('span');
+ el1.appendChild(el2);
+
+ template.content.appendChild(el1);
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test not empty template populated by appendchild()');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template>Text<div>DIV</div></template>';
+
+ var template = doc.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test not empty template populated by innerHTML');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="template1" content="Some text as a content"></template>';
+
+ var template = doc.querySelector('#template1');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test that custom content attribute named \'content\' doesn\'t ' +
+ 'make content IDL attribute writable');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="template1" content="<div id=div1>Div content</div>"></template>';
+
+ var template = doc.querySelector('#template1');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+ assert_equals(template.content.childNodes.length, 0,
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test that custom content attribute named \'content\' doesn\'t ' +
+ 'affect content IDL attribute');
+
+
+testInIFrame('../resources/template-contents-attribute.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. '
+ + 'Text value of content attribute of template tag should be ignored, '
+ + 'when loading document from a file');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. '
+ + 'Test content attribute of a document loaded from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html
new file mode 100644
index 0000000000..0c60c10738
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html
@@ -0,0 +1,192 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: When node's document changes its owner document should be changed</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="When a template element's node document changes, the template element's content DocumentFragment must be adopted into the new node document's template contents owner document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ var template = doc1.createElement('template');
+
+ assert_equals(template.ownerDocument, doc1, 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of an empty template and its content changes');
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ doc1.body.innerHTML = '<template id="tmpl"><div>Div content</div> And some more text</template>';
+
+ var template = doc1.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc1,
+ 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of a not empty template and its content changes');
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ doc1.body.innerHTML = ''
+ + '<template id="tmpl"><div>Div content</div> And some more text'
+ + '<template id="tmpl2"><div>Template content</div></template>'
+ + '</template>';
+
+ var template = doc1.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc1, 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template node owner document');
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(nestedTemplate.ownerDocument,
+ template2.content.ownerDocument,
+ 'Nested template node owner document should be changed');
+ assert_equals(nestedTemplate.content.ownerDocument,
+ template2.content.ownerDocument,
+ 'Nested template content owner document should be changed');
+ assert_equals(nestedTemplate.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Owner document of the nested template content descendants should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of nested template and its content changes');
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var template = doc1.body.querySelector('template');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test document loaded from a file');
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var doc2 = newHTMLDocument();
+ var template = doc2.createElement('template');
+ var div = doc2.createElement('div');
+ template.content.appendChild(div);
+
+ doc1.body.appendChild(template);
+
+ assert_not_equals(template.ownerDocument, doc2,
+ 'Template node owner document should be changed');
+ assert_not_equals(template.content.ownerDocument, doc2,
+ 'Template content owner document should be changed');
+ assert_not_equals(div.ownerDocument, doc2,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(template.ownerDocument, doc1,
+ 'Template node owner document should be changed');
+ // doc1 has browsing context so it cannot be template.content.ownerDocument
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Template content owner document should be a new document');
+ assert_equals(div.ownerDocument, template.content.ownerDocument,
+ 'Template content descendants owner document should be ' +
+ 'template content document owner');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Adobt template element into a document that has a browsing context');
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var template = doc1.querySelector('template');
+ var div = template.content.querySelector('div');
+ var templateContentOwner = template.content.ownerDocument;
+
+ var doc2 = document;
+
+ doc2.body.appendChild(template);
+
+ assert_not_equals(template.ownerDocument, doc1,
+ 'Template node owner document should be changed');
+ assert_not_equals(template.content.ownerDocument, templateContentOwner,
+ 'Template content owner document should be changed');
+ assert_not_equals(div.ownerDocument, templateContentOwner,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(template.ownerDocument, doc2,
+ 'Template node owner document should be changed');
+ // doc2 has browsing context, so it cannot be template.content.ownerDocument
+ assert_not_equals(template.content.ownerDocument, doc2,
+ 'Template content owner document should be a new document');
+ assert_equals(div.ownerDocument, template.content.ownerDocument,
+ 'Template content descendants owner document should be ' +
+ 'template content document owner');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test the case when both old and new owner documents of template element ' +
+ 'have browsing context');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html
new file mode 100644
index 0000000000..caa1beab47
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the body element.</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the body element">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+function templateIsAChild(element) {
+ element.innerHTML = '<template>some text</template>';
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsDisallowedAsAChild(element) {
+ element.innerHTML = '<template>some text</template>';
+
+ assert_equals(element.querySelector('template'), null,
+ 'Template element should not be allowed as a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnIndirectChild(element) {
+ element.innerHTML = '<div><template>some text</template></div>';
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsDisallowedAsAnIndirectChild(element) {
+ element.innerHTML = '<div><template>some text</template></div>';
+
+ assert_equals(element.querySelector('template'), null,
+ 'Template element should not be allowed as indirect descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnAppendedChild(doc, element) {
+ var template = doc.createElement('template');
+
+ element.appendChild(template);
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnAppendedIndirectChild(doc, element) {
+ var template = doc.createElement('template');
+ var div = doc.createElement('div');
+ div.appendChild(template);
+
+ element.appendChild(div);
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+var doc = newHTMLDocument();
+var frameset = doc.createElement('frameset');
+
+var parameters = [['Template element as a descendant of the BODY element. ' +
+ 'Template element is created by innerHTML',
+ doc.body],
+ ['Template element as a descendant of the HEAD element. ' +
+ 'Template element is created by innerHTML',
+ doc.head],
+ ];
+// Template element as a descendant of the HEAD and BODY elements
+generate_tests(templateIsAChild, parameters);
+
+parameters = [['Template element as a descendant of the FRAMESET element. ' +
+ 'Template element is created by innerHTML',
+ frameset],
+ ];
+// Template element should be disallowed as a descendant of the FRAMESET elements
+generate_tests(templateIsDisallowedAsAChild, parameters);
+
+
+parameters = [['Template element as an indirect descendant of the BODY element. ' +
+ 'Template element is created by innerHTML',
+ doc.body],
+ ['Template element as an indirect descendant of the HEAD element. ' +
+ 'Template element is created by innerHTML',
+ doc.head],
+ ];
+// Template element as an indirect descendant of the HEAD, BODY and FRAMESET elements
+generate_tests(templateIsAnIndirectChild, parameters);
+
+parameters = [['Template element as an indirect descendant of the FRAMESET element. ' +
+ 'Template element is created by innerHTML',
+ frameset],
+ ];
+// Template element should be disallowed as an indirect descendant of the FRAMESET elements
+generate_tests(templateIsDisallowedAsAnIndirectChild, parameters);
+
+
+
+parameters = [['Template element as a descendant of the BODY element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.body],
+ ['Template element as a descendant of the HEAD element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.head],
+ ['Template element as a descendant of the FRAMESET element. ' +
+ 'Template element is appended by appendChild()',
+ doc, frameset]
+ ];
+// Template element as a descendant of the HEAD, BODY and FRAMESET elements
+generate_tests(templateIsAnAppendedChild, parameters);
+
+
+
+parameters = [['Template element as an indirect descendant of the BODY element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.body],
+ ['Template element as an indirect descendant of the HEAD element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.head],
+ ['Template element as an indirect descendant of the FRAMESET element. ' +
+ 'Template element is appended by appendChild()',
+ doc, frameset]
+ ];
+// Template element as a descendant of the HEAD, BODY and FRAMESET elements
+generate_tests(templateIsAnAppendedIndirectChild, parameters);
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-construction-in-inactive-document-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-construction-in-inactive-document-crash.html
new file mode 100644
index 0000000000..496a47b2c5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-construction-in-inactive-document-crash.html
@@ -0,0 +1,5 @@
+<iframe id="i"></iframe>
+<script>
+i.contentDocument.documentElement.appendChild(document.body);
+</script>
+<template><script></script></template>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy.html
new file mode 100644
index 0000000000..823c0c830f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<meta name="author" title="Takayoshi Kochi" href="mailto:kochi@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<div id="parent">
+ <template id="tmpl"><span>Happy Templating!</span></template>
+</div>
+<script>
+test(() => {
+ var parent = document.getElementById('parent');
+ var tmpl = document.getElementById('tmpl');
+
+ assert_equals(tmpl.innerHTML, '<span>Happy Templating!</span>');
+ var span = tmpl.content.querySelector('span');
+
+ // Hierarchy checks at various combinations.
+ assert_throws_dom('HierarchyRequestError', () => {
+ tmpl.content.appendChild(parent);
+ }, 'Template content should throw if any of ancestor is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ tmpl.content.appendChild(tmpl);
+ }, 'Template content should throw if its host is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ span.appendChild(parent);
+ }, 'Template content child should throw if any of ancestor is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ span.appendChild(tmpl);
+ }, 'Template content child should throw template\'s host is being appended.');
+}, "Template content should throw when its ancestor is being appended.");
+
+test(() => {
+ var parent = document.getElementById('parent');
+ var tmpl = document.getElementById('tmpl');
+
+ assert_equals(tmpl.innerHTML, '<span>Happy Templating!</span>');
+ var span = tmpl.content.querySelector('span');
+
+ var tmpl_doc = tmpl.content.ownerDocument;
+ assert_equals(tmpl.ownerDocument, document);
+ assert_not_equals(tmpl_doc, document);
+
+ var new_doc = document.implementation.createHTMLDocument();
+ assert_not_equals(new_doc, document);
+ assert_not_equals(new_doc, tmpl_doc);
+
+ // Try moving tmpl.content to new_doc and check the results.
+ const tmplContentNodeDocument = tmpl.content.ownerDocument;
+ const tmplContentAdoptResult = new_doc.adoptNode(tmpl.content);
+ assert_equals(tmpl.content, tmplContentAdoptResult);
+ assert_equals(tmpl.ownerDocument, document);
+ assert_equals(tmpl.content.ownerDocument, tmplContentNodeDocument);
+
+ // Hierarchy checks at various combinations.
+ assert_throws_dom('HierarchyRequestError', () => {
+ tmpl.content.appendChild(parent);
+ }, 'Template content should throw if any of ancestor is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ tmpl.content.appendChild(tmpl);
+ }, 'Template content should throw if its host is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ span.appendChild(parent);
+ }, 'Template content child should throw if any of ancestor is being appended.');
+ assert_throws_dom('HierarchyRequestError', () => {
+ span.appendChild(tmpl);
+ }, 'Template content child should throw template\'s host is being appended.');
+
+ // Sanity check: template.content before and after move.
+ var tmpl_content_reference = tmpl.content;
+ assert_equals(tmpl.content.firstChild, span,
+ '<span> should be kept until it is removed, even after ' +
+ 'adopted to another document.');
+ new_doc.body.appendChild(tmpl.content);
+ assert_equals(tmpl.content.firstChild, null,
+ '<span> should be removed from template content.');
+ assert_equals(tmpl_content_reference, tmpl.content,
+ 'template.content should be identical before and after ' +
+ 'moving its children.');
+}, 'Template content should throw exception when its ancestor in ' +
+ 'a different document but connected via host is being append.');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html
new file mode 100644
index 0000000000..66c564c77a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html
@@ -0,0 +1,7 @@
+<iframe id="i"></iframe>
+<script>
+var t = i.contentDocument.createElement("template");
+i.contentDocument.documentElement.appendChild(t);
+i.remove();
+t.content;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html
new file mode 100644
index 0000000000..89c56d1663
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html
@@ -0,0 +1,7 @@
+<div id="d">
+<iframe id="i"></iframe>
+<template id="t"> </template>
+</div>
+<script>
+i.contentDocument.documentElement.appendChild(d);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html
new file mode 100644
index 0000000000..da76c6b04f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Node document of the template content attribute must be template contents owner</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Node document of the template content attribute must be template contents owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+ template.appendChild(nestedTemplate);
+
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Nested template element created by createElement');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template><template></template></template>';
+ var template = doc.querySelector('template');
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Nested template element created by innerHTML');
+
+testInIFrame('../resources/two-templates.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template1 = doc.querySelector('#template1');
+ var template2 = doc.querySelector('#template2');
+
+ // when there is a browsing context, template contents owner is only accessible via template.content.ownerDocument
+ // because template contents owner is bounded to document
+ // verify that multiple templates share the same instance of template contents owner
+
+ assert_equals(template1.content.ownerDocument, template2.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Load HTML file with multiple template elements');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html
new file mode 100644
index 0000000000..b9e790daf8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: HTML elements in template content</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Template may contain any element, except the html element, the head element, the body element, or the frameset element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+HTML5_ELEMENTS.forEach(function(value) {
+ if (value !== 'body' && value !== 'html' && value !== 'head' && value !== 'frameset') {
+
+ test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var element = doc.createElement(value);
+ template.content.appendChild(element);
+ var valueToTest = template.content.querySelector(value);
+
+ doc.body.appendChild(template);
+
+ assert_not_equals(valueToTest, null);
+ }, 'Template may contain ' + value + ' element');
+
+ }
+});
+
+
+
+var parameters = [];
+
+HTML5_ELEMENTS.forEach(function(value) {
+ if (value !== 'body' && value !== 'html' && value !== 'head' && value !== 'frameset') {
+
+ test(function() {
+ var doc = newHTMLDocument();
+
+ if (isVoidElement(value)) {
+ doc.body.innerHTML = '<template><' + value + '/></template>';
+ } else {
+ doc.body.innerHTML = '<template><' + value + '></' + value + '></template>';
+ }
+
+ var template = doc.querySelector('template');
+ var element = template.content.querySelector(value);
+
+ assert_not_equals(element, null);
+ }, 'Template may contain ' + value + ' element. '
+ + 'The template element and contents are added via body.innerHTML');
+
+ }
+});
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html
new file mode 100644
index 0000000000..70028c5ecd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the body element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the body element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-contents.html', function(ctx) {
+ var doc = ctx.iframes[0].contentDocument;
+
+ assert_not_equals(doc.body.querySelector('template'), null,
+ 'Template element should be a descendant of the body element');
+
+}, 'Template element as a descendant of the body element. Test loading from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html
new file mode 100644
index 0000000000..ce20a7413e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the frameset element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can not be a descendant of the frameset element">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#parsing-main-inframeset">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ assert_equals(frameset.querySelector('template'), null,
+ 'Template element should not be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. Test loading from a file');
+
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ frameset.innerHTML = '';
+ assert_equals(doc.querySelector('template'), null,
+ 'Initial conditions are not satisfied');
+
+ frameset.innerHTML = '<template>some text</template>';
+
+ assert_equals(frameset.querySelector('template'), null,
+ 'Template element should not be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. '
+ + 'Test template element is assigned to frameset\'s innerHTML)');
+
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ var template = doc.createElement('template');
+ frameset.appendChild(template);
+
+ assert_equals(frameset.querySelectorAll('template').length, 1,
+ 'Template element should be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. '
+ + 'Test template element appended to frameset by appendChild()');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html
new file mode 100644
index 0000000000..611ec50bb4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the head element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the head element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-descendant-head.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ assert_not_equals(doc.head.querySelector('template'), null,
+ 'Template element should be a descendant of the head element');
+
+}, 'Template element as a descendant of the head element. Test loading from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-element-clone-into-inactive-document-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-element-clone-into-inactive-document-crash.html
new file mode 100644
index 0000000000..56b199d1eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-element-clone-into-inactive-document-crash.html
@@ -0,0 +1,7 @@
+<template id="t"> </template>
+<iframe id="i"></iframe>
+<script>
+var doc = i.contentDocument;
+i.remove();
+doc.importNode(t, true);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-set-inner-html-in-inactive-document-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-set-inner-html-in-inactive-document-crash.html
new file mode 100644
index 0000000000..79a76ee76f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-set-inner-html-in-inactive-document-crash.html
@@ -0,0 +1,6 @@
+<iframe id="i"></iframe>
+<script>
+ var doc = i.contentDocument;
+ i.remove();
+ doc.createElement("template").innerHTML = "";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-table-crash.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-table-crash.html
new file mode 100644
index 0000000000..0f6a49874d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-table-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://crbug.com/1212619">
+<meta name="assert" content="The renderer should not crash.">
+
+<template id=tmpl></template>
+<table id=tbl>
+ <script>
+ tmpl.appendChild(tbl);
+ </script>
+ Crash
+</table>