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

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: Rebase. 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
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';
kouhei (in TOK) 2016/08/15 02:10:31 Nit: indent
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 return document.documentElement;
kouhei (in TOK) 2016/08/15 02:10:31 add a comment why we are returning a documentEleme
79 }
80 });
81 </script>
82 <a-a>
83 </template>
84 <script>
85 'use strict';
86
87 test_with_content((w) => {
88 let e = w.document.querySelector('a-a');
89 assert_true(e.matches(':not(:defined)'));
90 assert_equals(Object.getPrototypeOf(e), w.HTMLUnknownElement.prototype);
91 });
92 </script>
93
94 <template data-test="modify tree during creation">
95 <script>
96 'use strict';
97
98 customElements.define('a-a', class extends HTMLElement {
99 constructor() {
100 super();
101 document.querySelector('b').remove();
102 }
103 });
104 </script>
105 <b>
106 <a-a>
107 </b>
108 </template>
109 <script>
110 'use strict';
111
112 test_with_content((w) => {
113 assert_equals(w.document.querySelectorAll('b').length, 0);
114 });
115 </script>
116
117 <template data-test="destructive writes are blocked during construction">
118 <script>
119 'use strict';
120
121 window.invocations = [];
122 customElements.define('a-a', class extends HTMLElement {
123 constructor() {
124 super();
125 invocations.push('constructor');
126 document.write(
127 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
128 }
129 connectedCallback() {
130 invocations.push('connected');
131 }
132 });
133 </script>
134 <a-a>
135 <script>
136 'use strict';
137 invocations.push('parsed');
138 </script>
139 </template>
140 <script>
141 'use strict';
142
143 test_with_content((w) => {
144 assert_array_equals(
145 w.invocations,
146 ['constructor', 'connected', 'parsed'],
147 'the destructive document.write content should have been ignored');
148 });
149 </script>
150
151 <template data-test="non-destructive writes are not blocked">
kouhei (in TOK) 2016/08/15 02:10:31 maybe document why? "Parser pause flag (https://ht
152 <script>
153 'use strict';
154
155 window.invocations = [];
156 customElements.define('a-a', class extends HTMLElement {
157 constructor() {
158 super();
159 invocations.push('constructor');
160 document.write(
161 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
162 }
163 connectedCallback() {
164 invocations.push('connected');
165 }
166 });
167 document.write('<a-a>');
168 invocations.push('post write');
169 </script>
170 <script>
171 'use strict';
172 invocations.push('parsed');
173 </script>
174 </template>
175 <script>
176 'use strict';
177
178 test_with_content((w) => {
179 assert_array_equals(
180 w.invocations,
181 ['constructor', 'connected', 'post write', 'written', 'parsed'],
182 'the non-destructive document.write content should have been inserted');
183 });
184 </script>
185
186 <template data-test="innerHTML is not blocked by custom element constructors">
187 <script>
188 'use strict';
189
190 window.invocations = [];
191 customElements.define('a-a', class extends HTMLElement {
192 constructor() {
193 super();
194 invocations.push(`construct ${this.id}`);
195 if (!this.id) {
196 // If the ID attribute is not set, this was created
197 // synchronously by the parser. Adding children at this point
198 // would cause creation to fail, so embiggen the previous
199 // element instead.
200 document.querySelector('span').innerHTML = `<a-a id="r">`;
201 }
202 }
203 connectedCallback() {
204 invocations.push(`connected ${this.parentNode.localName}/${this.id}`);
205 }
206 });
207 </script>
208 <span></span>
209 <a-a id="q"></a-a>
210 <script>
211 'use strict';
212 invocations.push('parsed');
213 </script>
214 </template>
215 <script>
216 'use strict';
217
218 test_with_content((w) => {
219 assert_array_equals(
220 w.invocations,
221 ['construct ', 'construct r', 'connected span/r', 'connected body/q',
222 'parsed'],
223 'custom element constructors should not block innerHTML');
224 });
225 </script>
226
227
228 <template data-test="parsing without a browsing context should not create custom elements">
229 <body>
230 <script>
231 'use strict';
232
233 let f = parent.findFrameWithWindow(window);
234 f.invocations = [];
235
236 customElements.define('a-a', class extends HTMLElement {
237 constructor() {
238 super();
239 f.invocations.push(this);
240 }
241 });
242 </script>
243 <a-a></a-a>
244 <script>
245 f.detached = document.implementation.createHTMLDocument();
246 f.detached.documentElement.appendChild(document.body);
247 </script>
248 <a-a></a-a>
249 </template>
250 <script>
251 'use strict';
252
253 test_with_content((w) => {
254 let f = findFrameWithWindow(w);
255 assert_array_equals(f.invocations,
256 [f.detached.querySelector('a-a:first-of-type')],
257 'one element should have been constructed');
258 assert_true(f.invocations[0].matches(':defined'),
259 'the element should have been created successfully');
260
261 let elements = f.detached.querySelectorAll('a-a');
262 console.log(f.invocations[0].parentNode);
263 assert_equals(elements.length, 2,
264 'two elements should have been created');
265 assert_equals(Object.getPrototypeOf(elements[1]), w.HTMLElement.prototype,
266 'the second element should be un-upgraded, not failed');
267 });
268 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698