Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Side by Side Diff: third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html

Issue 2200613002: The HTML parser synchronously creates custom elements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Eliminate redundant TODOs. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!DOCTYPE html>
2 <script src="../../resources/testharness.js"></script>
3 <script src="../../resources/testharnessreport.js"></script>
4 <script src="resources/custom-elements-helpers.js"></script>
5 <body>
6 <script>
7 'use strict';
8
9 // Looks up the preceeding element (which should be a template
10 // element) and creates a Promise test. The test name is taken from
11 // the template's data-test attribute.
12 //
13 // The content of the template is loaded into an iframe. On load, f
14 // is passed the frame's content window to run assertions.
15 function test_with_content(f) {
16 let t = document.currentScript.previousElementSibling;
17 test_with_window(f, t.dataset.test, t.innerHTML);
18 }
19
20 // Searches the document for an iframe with the specified content window.
21 function findFrameWithWindow(w) {
22 return Array.prototype.find.call(document.querySelectorAll('iframe'), (f) => {
23 return f.contentWindow === w;
24 });
25 }
26
27 test_with_window((w) => {
28 assert_equals(findFrameWithWindow(w).contentWindow, w,
29 'should find the frame with this window');
30 assert_equals(findFrameWithWindow(window), undefined,
31 'should return undefined if there is no such frame');
32 }, 'sanity check the findFrameWithWindow function');
33 </script>
34
35 <template data-test="the parser synchronously creates elements">
36 <script>
37 'use strict';
38
39 window.invocations = [];
40 customElements.define('a-a', class extends HTMLElement {
41 constructor() {
42 super();
43 invocations.push('constructor');
44 }
45 static get observedAttributes() { return ['x']; }
46 attributeChangedCallback(name, oldValue, newValue, nsuri) {
47 invocations.push(`${name}="${newValue}"`);
48 }
49 connectedCallback() {
50 invocations.push('connected');
51 }
52 });
53 </script>
54 <a-a x="y">
55 <script>
56 'use strict';
57
58 invocations.push('script');
59 </script>
60 </a-a>
61 </template>
62 <script>
63 'use strict';
64
65 test_with_content((w) => {
66 assert_array_equals(w.invocations,
67 ['constructor', 'x="y"', 'connected', 'script']);
68 });
69 </script>
70
71 <template data-test="element creation failure produces unknown element">
72 <script>
73 'use strict';
74
75 customElements.define('a-a', class extends HTMLElement {
76 constructor() {
77 super();
78
79 // Returning this different, in-use element causes element
80 // creation to fail in
81 // https://dom.spec.whatwg.org/#concept-create-element steps
82 // 6.4-9, eg: "If result has children then then throw a
83 // NotSupportedError."
84 return document.documentElement;
85 }
86 });
87 </script>
88 <a-a>
89 </template>
90 <script>
91 'use strict';
92
93 test_with_content((w) => {
94 let e = w.document.querySelector('a-a');
95 assert_true(e.matches(':not(:defined)'));
96 assert_equals(Object.getPrototypeOf(e), w.HTMLUnknownElement.prototype);
97 });
98 </script>
99
100 <template data-test="modify tree during creation">
101 <script>
102 'use strict';
103
104 customElements.define('a-a', class extends HTMLElement {
105 constructor() {
106 super();
107 document.querySelector('b').remove();
108 }
109 });
110 </script>
111 <b>
112 <a-a>
113 </b>
114 </template>
115 <script>
116 'use strict';
117
118 test_with_content((w) => {
119 assert_equals(w.document.querySelectorAll('b').length, 0);
120 });
121 </script>
122
123 <template data-test="destructive writes are blocked during construction">
124 <script>
125 // Custom element constructors do not set the insertion point, which
126 // makes document.write() "destructive." However they increment the
127 // ignore-destructive-writes counter, which blocks document.write.
128 // https://html.spec.whatwg.org/#create-an-element-for-the-token
129 // https://github.com/whatwg/html/issues/1630
130 // https://html.spec.whatwg.org/#document.write()
131 'use strict';
132
133 window.invocations = [];
134 customElements.define('a-a', class extends HTMLElement {
135 constructor() {
136 super();
137 invocations.push('constructor');
138 document.write(
139 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
140 }
141 connectedCallback() {
142 invocations.push('connected');
143 }
144 });
145 </script>
146 <a-a>
147 <script>
148 'use strict';
149 invocations.push('parsed');
150 </script>
151 </template>
152 <script>
153 'use strict';
154
155 test_with_content((w) => {
156 assert_array_equals(
157 w.invocations,
158 ['constructor', 'connected', 'parsed'],
159 'the destructive document.write content should have been ignored');
160 });
161 </script>
162
163 <template data-test="non-destructive writes are not blocked">
164 <script>
165 // Script running sets the insertion point, which makes makes
166 // document.write() "non-destructive." Custom elements do not block
167 // non-destructive writes.
168 // https://html.spec.whatwg.org/#create-an-element-for-the-token
169 // https://html.spec.whatwg.org/#document.write()
170 'use strict';
171
172 window.invocations = [];
173 customElements.define('a-a', class extends HTMLElement {
174 constructor() {
175 super();
176 invocations.push('constructor');
177 document.write(
178 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
179 }
180 connectedCallback() {
181 invocations.push('connected');
182 }
183 });
184 document.write('<a-a>');
185 invocations.push('post write');
186 </script>
187 <script>
188 'use strict';
189 invocations.push('parsed');
190 </script>
191 </template>
192 <script>
193 'use strict';
194
195 test_with_content((w) => {
196 assert_array_equals(
197 w.invocations,
198 ['constructor', 'connected', 'post write', 'written', 'parsed'],
199 'the non-destructive document.write content should have been inserted');
200 });
201 </script>
202
203 <template data-test="innerHTML is not blocked by custom element constructors">
204 <script>
205 'use strict';
206
207 window.invocations = [];
208 customElements.define('a-a', class extends HTMLElement {
209 constructor() {
210 super();
211 invocations.push(`construct ${this.id}`);
212 if (!this.id) {
213 // If the ID attribute is not set, this was created
214 // synchronously by the parser. Adding children at this point
215 // would cause creation to fail, so embiggen the previous
216 // element instead.
217 document.querySelector('span').innerHTML = `<a-a id="r">`;
218 }
219 }
220 connectedCallback() {
221 invocations.push(`connected ${this.parentNode.localName}/${this.id}`);
222 }
223 });
224 </script>
225 <span></span>
226 <a-a id="q"></a-a>
227 <script>
228 'use strict';
229 invocations.push('parsed');
230 </script>
231 </template>
232 <script>
233 'use strict';
234
235 test_with_content((w) => {
236 assert_array_equals(
237 w.invocations,
238 ['construct ', 'construct r', 'connected span/r', 'connected body/q',
239 'parsed'],
240 'custom element constructors should not block innerHTML');
241 });
242 </script>
243
244
245 <template data-test="parsing without a browsing context should not create custom elements">
246 <body>
247 <script>
248 'use strict';
249
250 let f = parent.findFrameWithWindow(window);
251 f.invocations = [];
252
253 customElements.define('a-a', class extends HTMLElement {
254 constructor() {
255 super();
256 f.invocations.push(this);
257 }
258 });
259 </script>
260 <a-a></a-a>
261 <script>
262 f.detached = document.implementation.createHTMLDocument();
263 f.detached.documentElement.appendChild(document.body);
264 </script>
265 <a-a></a-a>
266 </template>
267 <script>
268 'use strict';
269
270 test_with_content((w) => {
271 let f = findFrameWithWindow(w);
272 assert_array_equals(f.invocations,
273 [f.detached.querySelector('a-a:first-of-type')],
274 'one element should have been constructed');
275 assert_true(f.invocations[0].matches(':defined'),
276 'the element should have been created successfully');
277
278 let elements = f.detached.querySelectorAll('a-a');
279 console.log(f.invocations[0].parentNode);
280 assert_equals(elements.length, 2,
281 'two elements should have been created');
282 assert_equals(Object.getPrototypeOf(elements[1]), w.HTMLElement.prototype,
283 'the second element should be un-upgraded, not failed');
284 });
285 </script>
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698