File: not-as-classic-script.html

package info (click to toggle)
firefox 147.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,320 kB
  • sloc: cpp: 7,607,359; javascript: 6,533,295; ansic: 3,775,223; python: 1,415,500; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,752; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (158 lines) | stat: -rw-r--r-- 5,703 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script>
setup({allow_uncaught_exception : true});

const t_parse = async_test("Import maps shouldn't be parsed as scripts");
const t_already_started = async_test("The Already Started flag is passed through cloneNode");
const t_evaluate = async_test("Import maps shouldn't be executed as scripts");
const t_external = async_test(
   "External import maps shouldn't be executed as scripts");
const t_change_type = async_test(
   "Import maps shouldn't be executed as scripts after changing type");

const parseErrorHandler = event => {
  event.preventDefault();
  t_parse.unreached_func("An import map is parsed as a classic script")();
};

window.addEventListener("error", parseErrorHandler, {once: true});
</script>

<!-- This import map causes a parse error when parsed as a classic script. -->
<script type="importmap">
{
  "imports": {
  }
}
</script>

<script>
window.removeEventListener("error", parseErrorHandler);
t_parse.done();

const alreadyStartedErrorHandler = event => {
  event.preventDefault();
  t_already_started.unreached_func("An import map is evaluated as a classic script")();
};

window.addEventListener("error", alreadyStartedErrorHandler, {once: true});
</script>

<script>
// Once Already Started is true on a classic script, it cannot be
// converted into an import map.
const dynamicScriptClassic = document.createElement("script");
dynamicScriptClassic.type = "text/javascript";
dynamicScriptClassic.innerText = "t_already_started.step(function() { assert_true(true, 'Classic script connected dynamically.');});";

// Inserting a <script> with contents sets Already Started to true.
document.head.appendChild(dynamicScriptClassic);
document.head.removeChild(dynamicScriptClassic);

// The existing innerText would be a parse error if parsed as an import
// map, but is valid as a classic script.
dynamicScriptClassic.type = "importmap";
document.head.appendChild(dynamicScriptClassic);

// The Already Started flag on a script is persisted upon cloning, so
// the clone won't be parsed as an import map even though its `type`
// was set to "importmap" when it was connected.
const clonedClassicScript = dynamicScriptClassic.cloneNode(/*deep=*/true);
t_already_started.step(function() {
  assert_equals(clonedClassicScript.type, "importmap");
  assert_equals(clonedClassicScript.innerText, dynamicScriptClassic.innerText);
});
document.head.appendChild(clonedClassicScript);

// Creating an empty <script> tag does not set Already Started to true,
// so the type can be changed later.
const dynamicScriptEmpty = document.createElement("script");
dynamicScriptEmpty.type = "text/javascript";
document.head.appendChild(dynamicScriptEmpty);

// The Already Started flag is copied onto clones, so the type can be
// changed later.
const clonedDynamicScriptEmpty = dynamicScriptEmpty.cloneNode(/*deep=*/true);
t_already_started.step(function() {
  assert_equals(clonedDynamicScriptEmpty.type, "text/javascript");
});
clonedDynamicScriptEmpty.setAttribute("type", "importmap");
t_already_started.step(function() {
  assert_equals(clonedDynamicScriptEmpty.type, "importmap");
});

// Since the contents are not empty, connecting the clone will set the
// Already Started flag to true and lock the type into an import map.
document.head.appendChild(clonedDynamicScriptEmpty);
document.head.removeChild(clonedDynamicScriptEmpty);

// This would cause a parse error when parsed as a classic script.
clonedDynamicScriptEmpty.innerText = "{ \"imports\": {  } }";
document.head.appendChild(clonedDynamicScriptEmpty);

// The original element can have its contents set and will executed
// as a classic script. Ensure this is executed by completing the test.
dynamicScriptEmpty.innerText = "t_already_started.done();";
document.head.appendChild(dynamicScriptEmpty);
</script>

<script>
// Remove prior error handler, because the following import maps can
// causes parse errors.
window.removeEventListener("error", alreadyStartedErrorHandler);
</script>

<script>
// A dynamically created import map isn't parsed as a classic script.
const dynamicScript = document.createElement("script");
dynamicScript.type = "importmap";
t_evaluate.step(function() {
  assert_equals(dynamicScript.type, "importmap");
});
dynamicScript.innerText = "t_evaluate.unreached_func('A dynamically-created import map is evaluated')();";
document.head.appendChild(dynamicScript);

// Changing the type shouldn't execute script.
dynamicScript.type = "text/javascript";
t_evaluate.step(function() {
  assert_equals(dynamicScript.type, "text/javascript");
});

// Nor should removing it and re-inserting it.
document.head.removeChild(dynamicScript);
document.head.appendChild(dynamicScript);
</script>

<!-- Test the same with markup. -->
<script type="importmap">
t_evaluate.unreached_func("An import map is evaluated")();
</script>

<script>
t_evaluate.done();
</script>

<script type="importmap" id="changeType">
t_change_type.unreached_func("An import map is evaluated after changing type")();
</script>

<script>
// Change the type from "importmap" to other valid values and ensure
// script never executes.
let changeType = document.getElementById("changeType");
changeType.setAttribute("type", "text/javascript");
changeType.setAttribute("type", "module");
changeType.setAttribute("type", "");
changeType.removeAttribute("type");
t_change_type.done();
</script>

<!-- Import Maps do not execute external scripts. -->
<script type="importmap" src="data:text/javascript,t_external.unreached_func('An external import map is evaluated')();"></script>

<script>
t_external.done();
</script>