OLD | NEW |
---|---|
(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 Array.prototype.forEach.call(document.querySelectorAll('iframe'), (f) => { | |
domenic
2016/08/05 08:39:50
What does this function do? Returning from within
dominicc (has gone to gerrit)
2016/08/15 01:33:15
Oops. Fixed! :P
| |
23 if (f.contentWindow === w) { | |
24 return f; | |
25 } | |
26 return undefined; | |
27 }); | |
28 return null; | |
29 } | |
30 </script> | |
31 | |
32 <template data-test="the parser synchronously creates elements"> | |
33 <script> | |
34 'use strict'; | |
35 | |
36 window.invocations = []; | |
37 customElements.define('a-a', class extends HTMLElement { | |
38 constructor() { | |
39 super(); | |
40 invocations.push('constructor'); | |
41 } | |
42 static get observedAttributes() { return ['x']; } | |
43 attributeChangedCallback(name, oldValue, newValue, nsuri) { | |
44 invocations.push(`${name}="${newValue}"`); | |
45 } | |
46 connectedCallback() { | |
47 invocations.push('connected'); | |
48 } | |
49 }); | |
50 </script> | |
51 <a-a x="y"> | |
52 <script> | |
53 'use strict'; | |
54 | |
55 invocations.push('script'); | |
56 </script> | |
57 </a-a> | |
58 </template> | |
59 <script> | |
60 'use strict'; | |
61 | |
62 test_with_content((w) => { | |
63 assert_array_equals(w.invocations, | |
64 ['constructor', 'x="y"', 'connected', 'script']); | |
65 }); | |
66 </script> | |
67 | |
68 <template data-test="element creation failure produces unknown element"> | |
69 <script> | |
70 'use strict'; | |
71 | |
72 customElements.define('a-a', class extends HTMLElement { | |
73 constructor() { | |
74 super(); | |
75 return document.documentElement; | |
76 } | |
77 }); | |
78 </script> | |
79 <a-a> | |
80 </template> | |
81 <script> | |
82 'use strict'; | |
83 | |
84 test_with_content((w) => { | |
85 let e = w.document.querySelector('a-a'); | |
86 assert_true(e.matches(':not(:defined)')); | |
87 assert_equals(Object.getPrototypeOf(e), w.HTMLUnknownElement.prototype); | |
88 }); | |
89 </script> | |
90 | |
91 | |
92 <template data-test="remove during creation"> | |
domenic
2016/08/05 08:39:50
What is this testing? That removing works? (It's a
dominicc (has gone to gerrit)
2016/08/15 01:33:15
I just figured this is something which could go wr
| |
93 <script> | |
94 'use strict'; | |
95 | |
96 customElements.define('a-a', class extends HTMLElement { | |
97 constructor() { | |
98 super(); | |
99 parent.findFrameWithWindow(window).remove(); | |
100 } | |
101 }); | |
102 </script> | |
103 <a-a> | |
104 </template> | |
105 <script> | |
106 'use strict'; | |
107 | |
108 test_with_content((w) => { | |
109 assert_equals(findFrameWithWindow(w), null); | |
110 }); | |
111 </script> | |
112 | |
113 <template data-test="modify tree during creation"> | |
114 <script> | |
115 'use strict'; | |
116 | |
117 customElements.define('a-a', class extends HTMLElement { | |
118 constructor() { | |
119 super(); | |
120 document.querySelector('b').remove(); | |
121 } | |
122 }); | |
123 </script> | |
124 <b> | |
125 <a-a> | |
126 </b> | |
127 </template> | |
128 <script> | |
129 'use strict'; | |
130 | |
131 test_with_content((w) => { | |
132 assert_equals(w.document.querySelectorAll('b').length, 0); | |
133 }); | |
134 </script> | |
135 | |
136 <template data-test="destructive writes are blocked during construction"> | |
137 <script> | |
138 'use strict'; | |
139 | |
140 window.invocations = []; | |
141 customElements.define('a-a', class extends HTMLElement { | |
142 constructor() { | |
143 super(); | |
144 invocations.push('constructor'); | |
145 document.write( | |
146 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`); | |
147 } | |
148 connectedCallback() { | |
149 invocations.push('connected'); | |
150 } | |
151 }); | |
152 </script> | |
153 <a-a> | |
154 <script> | |
155 'use strict'; | |
156 invocations.push('parsed'); | |
157 </script> | |
158 </template> | |
159 <script> | |
160 'use strict'; | |
161 | |
162 test_with_content((w) => { | |
163 assert_array_equals( | |
164 w.invocations, | |
165 ['constructor', 'connected', 'parsed'], | |
166 'the destructive document.write content should have been ignored'); | |
167 }); | |
168 </script> | |
169 | |
170 <template data-test="non-destructive writes are not blocked"> | |
171 <script> | |
172 'use strict'; | |
173 | |
174 window.invocations = []; | |
175 customElements.define('a-a', class extends HTMLElement { | |
176 constructor() { | |
177 super(); | |
178 invocations.push('constructor'); | |
179 document.write( | |
180 `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`); | |
181 } | |
182 connectedCallback() { | |
183 invocations.push('connected'); | |
184 } | |
185 }); | |
186 document.write('<a-a>'); | |
187 invocations.push('post write'); | |
188 </script> | |
189 <script> | |
190 'use strict'; | |
191 invocations.push('parsed'); | |
192 </script> | |
193 </template> | |
194 <script> | |
195 'use strict'; | |
196 | |
197 test_with_content((w) => { | |
198 assert_array_equals( | |
199 w.invocations, | |
200 ['constructor', 'connected', 'post write', 'written', 'parsed'], | |
201 'the non-destructive document.write content should have been inserted'); | |
202 }); | |
203 </script> | |
204 | |
205 <template data-test="innerHTML is not blocked by custom element constructors"> | |
206 <script> | |
207 'use strict'; | |
208 | |
209 window.invocations = []; | |
210 customElements.define('a-a', class extends HTMLElement { | |
211 constructor() { | |
212 super(); | |
213 invocations.push(`construct ${this.id}`); | |
214 if (!this.id) { | |
215 // If the ID attribute is not set, this was created | |
216 // synchronously by the parser. Adding children at this point | |
217 // would cause creation to fail, so embiggen the previous | |
218 // element instead. | |
219 document.querySelector('span').innerHTML = `<a-a id="r">`; | |
220 } | |
221 } | |
222 connectedCallback() { | |
223 invocations.push(`connected ${this.parentNode.localName}/${this.id}`); | |
224 } | |
225 }); | |
226 </script> | |
227 <span></span> | |
228 <a-a id="q"></a-a> | |
229 <script> | |
230 'use strict'; | |
231 invocations.push('parsed'); | |
232 </script> | |
233 </template> | |
234 <script> | |
235 'use strict'; | |
236 | |
237 test_with_content((w) => { | |
238 console.log(w.invocations.join()); | |
239 assert_array_equals( | |
240 w.invocations, | |
241 ['construct ', 'construct r', 'connected span/r', 'connected body/q', | |
242 'parsed'], | |
243 'custom element constructors should not block innerHTML'); | |
244 }); | |
245 </script> | |
OLD | NEW |