@@ -29,6 +29,229 @@ describe('web components', () => {
2929 document . body . removeChild ( root ) ;
3030 } ) ;
3131
32+ describe ( 'options bag' , ( ) => {
33+ it ( 'supports `shadow`' , ( ) => {
34+ function ShadowDom ( ) {
35+ return < div class = "shadow-child" > Shadow DOM</ div > ;
36+ }
37+
38+ registerElement ( ShadowDom , 'x-shadowdom' , [ ] , { shadow : true } ) ;
39+ const el = document . createElement ( 'x-shadowdom' ) ;
40+ root . appendChild ( el ) ;
41+
42+ const shadowRoot = el . shadowRoot ;
43+ assert . isTrue ( ! ! shadowRoot ) ;
44+ } ) ;
45+
46+ it ( 'supports `mode: "open"`' , ( ) => {
47+ function ShadowDomOpen ( ) {
48+ return < div class = "shadow-child" > Shadow DOM Open</ div > ;
49+ }
50+
51+ registerElement ( ShadowDomOpen , 'x-shadowdom-open' , [ ] , {
52+ shadow : true ,
53+ mode : 'open' ,
54+ } ) ;
55+
56+ const el = document . createElement ( 'x-shadowdom-open' ) ;
57+ root . appendChild ( el ) ;
58+
59+ const shadowRoot = el . shadowRoot ;
60+ assert . isTrue ( ! ! shadowRoot ) ;
61+
62+ const child = shadowRoot . querySelector ( '.shadow-child' ) ;
63+ assert . isTrue ( ! ! child ) ;
64+ assert . equal ( child . textContent , 'Shadow DOM Open' ) ;
65+ } ) ;
66+
67+ it ( 'supports `mode: "closed"`' , ( ) => {
68+ function ShadowDomClosed ( ) {
69+ return < div class = "shadow-child" > Shadow DOM Closed</ div > ;
70+ }
71+
72+ registerElement ( ShadowDomClosed , 'x-shadowdom-closed' , [ ] , {
73+ shadow : true ,
74+ mode : 'closed' ,
75+ } ) ;
76+
77+ const el = document . createElement ( 'x-shadowdom-closed' ) ;
78+ root . appendChild ( el ) ;
79+
80+ assert . isTrue ( el . shadowRoot === null ) ;
81+ } ) ;
82+
83+ it ( 'supports `adoptedStyleSheets`' , ( ) => {
84+ function AdoptedStyleSheets ( ) {
85+ return < div class = "styled-child" > Adopted Style Sheets</ div > ;
86+ }
87+
88+ const sheet = new CSSStyleSheet ( ) ;
89+ sheet . replaceSync ( '.styled-child { color: red; }' ) ;
90+
91+ registerElement ( AdoptedStyleSheets , 'x-adopted-style-sheets' , [ ] , {
92+ shadow : true ,
93+ adoptedStyleSheets : [ sheet ] ,
94+ } ) ;
95+
96+ root . innerHTML = `<x-adopted-style-sheets></x-adopted-style-sheets>` ;
97+
98+ const child = document
99+ . querySelector ( 'x-adopted-style-sheets' )
100+ . shadowRoot . querySelector ( '.styled-child' ) ;
101+
102+ const style = getComputedStyle ( child ) ;
103+ assert . equal ( style . color , 'rgb(255, 0, 0)' ) ;
104+ } ) ;
105+
106+ it ( 'supports `serializable`' , async ( ) => {
107+ function SerializableComponent ( ) {
108+ return < div > Serializable Shadow DOM</ div > ;
109+ }
110+
111+ function NonSerializableComponent ( ) {
112+ return < div > Non-serializable Shadow DOM</ div > ;
113+ }
114+
115+ registerElement ( SerializableComponent , 'x-serializable' , [ ] , {
116+ shadow : true ,
117+ serializable : true ,
118+ } ) ;
119+
120+ registerElement ( NonSerializableComponent , 'x-non-serializable' , [ ] , {
121+ shadow : true ,
122+ } ) ;
123+
124+ root . innerHTML = `
125+ <x-serializable></x-serializable>
126+ <x-non-serializable></x-non-serializable>
127+ ` ;
128+
129+ const serializableEl = document . querySelector ( 'x-serializable' ) ;
130+ const nonSerializableEl = document . querySelector ( 'x-non-serializable' ) ;
131+
132+ assert . isTrue ( serializableEl . shadowRoot . serializable ) ;
133+ assert . isFalse ( nonSerializableEl . shadowRoot . serializable ) ;
134+
135+ const serializableHtml = serializableEl . getHTML ( {
136+ serializableShadowRoots : true ,
137+ } ) ;
138+ const nonSerializableHtml = nonSerializableEl . getHTML ( {
139+ serializableShadowRoots : true ,
140+ } ) ;
141+
142+ assert . equal (
143+ serializableHtml ,
144+ '<template shadowrootmode="open" shadowrootserializable=""><div>Serializable Shadow DOM</div></template>'
145+ ) ;
146+ assert . isEmpty ( nonSerializableHtml ) ;
147+ } ) ;
148+ } ) ;
149+
150+ describe ( 'static properties' , ( ) => {
151+ it ( 'supports `tagName`' , ( ) => {
152+ class TagNameClass extends Component {
153+ static tagName = 'x-tag-name-class' ;
154+
155+ render ( ) {
156+ return < input name = "foo" /> ;
157+ }
158+ }
159+ registerElement ( TagNameClass ) ;
160+
161+ function TagNameFunction ( ) {
162+ return < input name = "bar" /> ;
163+ }
164+ TagNameFunction . tagName = 'x-tag-name-function' ;
165+ registerElement ( TagNameFunction ) ;
166+
167+ root . innerHTML = `
168+ <div>
169+ <x-tag-name-class></x-tag-name-class>
170+ <x-tag-name-function></x-tag-name-function>
171+ </div>
172+ ` ;
173+
174+ assert . isTrue ( ! ! document . querySelector ( 'x-tag-name-class' ) ) ;
175+ assert . isTrue ( ! ! document . querySelector ( 'x-tag-name-function' ) ) ;
176+ } ) ;
177+
178+ it ( 'supports `observedAttributes`' , ( ) => {
179+ class ObservedAttributesClass extends Component {
180+ static observedAttributes = [ 'name' ] ;
181+
182+ render ( { name } ) {
183+ return < input name = { name } /> ;
184+ }
185+ }
186+ registerElement ( ObservedAttributesClass , 'x-observed-attributes-class' ) ;
187+
188+ function ObservedAttributesFunction ( { name } ) {
189+ return < input name = { name } /> ;
190+ }
191+ ObservedAttributesFunction . observedAttributes = [ 'name' ] ;
192+ registerElement (
193+ ObservedAttributesFunction ,
194+ 'x-observed-attributes-function'
195+ ) ;
196+
197+ const observedAttributesClassEl = document . createElement (
198+ 'x-observed-attributes-class'
199+ ) ;
200+ const observedAttributesFunctionEl = document . createElement (
201+ 'x-observed-attributes-function'
202+ ) ;
203+
204+ observedAttributesClassEl . setAttribute ( 'name' , 'class-name' ) ;
205+ observedAttributesFunctionEl . setAttribute ( 'name' , 'function-name' ) ;
206+
207+ root . appendChild ( observedAttributesClassEl ) ;
208+ root . appendChild ( observedAttributesFunctionEl ) ;
209+
210+ assert . equal (
211+ root . innerHTML ,
212+ `<x-observed-attributes-class name="class-name"><input name="class-name"></x-observed-attributes-class><x-observed-attributes-function name="function-name"><input name="function-name"></x-observed-attributes-function>`
213+ ) ;
214+
215+ observedAttributesClassEl . setAttribute ( 'name' , 'new-class-name' ) ;
216+ observedAttributesFunctionEl . setAttribute ( 'name' , 'new-function-name' ) ;
217+
218+ assert . equal (
219+ root . innerHTML ,
220+ `<x-observed-attributes-class name="new-class-name"><input name="new-class-name"></x-observed-attributes-class><x-observed-attributes-function name="new-function-name"><input name="new-function-name"></x-observed-attributes-function>`
221+ ) ;
222+ } ) ;
223+
224+ it ( 'supports `formAssociated`' , ( ) => {
225+ class FormAssociatedClass extends Component {
226+ static formAssociated = true ;
227+
228+ render ( ) {
229+ return < input name = "foo" /> ;
230+ }
231+ }
232+ registerElement ( FormAssociatedClass , 'x-form-associated-class' , [ ] ) ;
233+
234+ function FormAssociatedFunction ( ) {
235+ return < input name = "bar" /> ;
236+ }
237+ FormAssociatedFunction . formAssociated = true ;
238+ registerElement ( FormAssociatedFunction , 'x-form-associated-function' , [ ] ) ;
239+
240+ root . innerHTML = `
241+ <form id="myForm">
242+ <x-form-associated-class></x-form-associated-class>
243+ <x-form-associated-function></x-form-associated-function>
244+ </form>
245+ ` ;
246+
247+ const myForm = document . getElementById ( 'myForm' ) ;
248+
249+ // The `.elements` property of a form includes all form-associated elements
250+ assert . equal ( myForm . elements [ 0 ] . tagName , 'X-FORM-ASSOCIATED-CLASS' ) ;
251+ assert . equal ( myForm . elements [ 2 ] . tagName , 'X-FORM-ASSOCIATED-FUNCTION' ) ;
252+ } ) ;
253+ } ) ;
254+
32255 function Clock ( { time } ) {
33256 return < span > { time } </ span > ;
34257 }
@@ -285,93 +508,6 @@ describe('web components', () => {
285508 assert . equal ( getShadowHTML ( ) , '<p>Active theme: sunny</p>' ) ;
286509 } ) ;
287510
288- it ( 'renders element in shadow dom open mode' , async ( ) => {
289- function ShadowDomOpen ( ) {
290- return < div className = "shadow-child" > Shadow DOM Open</ div > ;
291- }
292-
293- registerElement ( ShadowDomOpen , 'x-shadowdom-open' , [ ] , {
294- shadow : true ,
295- mode : 'open' ,
296- } ) ;
297-
298- const el = document . createElement ( 'x-shadowdom-open' ) ;
299- root . appendChild ( el ) ;
300- const shadowRoot = el . shadowRoot ;
301- assert . isTrue ( ! ! shadowRoot ) ;
302- const child = shadowRoot . querySelector ( '.shadow-child' ) ;
303- assert . isTrue ( ! ! child ) ;
304- assert . equal ( child . textContent , 'Shadow DOM Open' ) ;
305- } ) ;
306-
307- it ( 'renders element in shadow dom closed mode' , async ( ) => {
308- function ShadowDomClosed ( ) {
309- return < div className = "shadow-child" > Shadow DOM Closed</ div > ;
310- }
311-
312- registerElement ( ShadowDomClosed , 'x-shadowdom-closed' , [ ] , {
313- shadow : true ,
314- mode : 'closed' ,
315- } ) ;
316-
317- const el = document . createElement ( 'x-shadowdom-closed' ) ;
318- root . appendChild ( el ) ;
319- assert . isTrue ( el . shadowRoot === null ) ;
320- } ) ;
321-
322- it ( 'supports the `formAssociated` property' , async ( ) => {
323- class FormAssociatedClass extends Component {
324- static formAssociated = true ;
325-
326- render ( ) {
327- return < input name = "foo" /> ;
328- }
329- }
330- registerElement ( FormAssociatedClass , 'x-form-associated-class' , [ ] ) ;
331-
332- function FormAssociatedFunction ( ) {
333- return < input name = "bar" /> ;
334- }
335- FormAssociatedFunction . formAssociated = true ;
336- registerElement ( FormAssociatedFunction , 'x-form-associated-function' , [ ] ) ;
337-
338- root . innerHTML = `
339- <form id="myForm">
340- <x-form-associated-class></x-form-associated-class>
341- <x-form-associated-function></x-form-associated-function>
342- </form>
343- ` ;
344-
345- const myForm = document . getElementById ( 'myForm' ) ;
346-
347- // The `.elements` property of a form includes all form-associated elements
348- assert . equal ( myForm . elements [ 0 ] . tagName , 'X-FORM-ASSOCIATED-CLASS' ) ;
349- assert . equal ( myForm . elements [ 2 ] . tagName , 'X-FORM-ASSOCIATED-FUNCTION' ) ;
350- } ) ;
351-
352- it ( 'supports the `adoptedStyleSheets` option' , async ( ) => {
353- function AdoptedStyleSheets ( ) {
354- return < div className = "styled-child" > Adopted Style Sheets</ div > ;
355- }
356-
357- const sheet = new CSSStyleSheet ( ) ;
358- sheet . replaceSync ( '.styled-child { color: red; }' ) ;
359-
360- registerElement ( AdoptedStyleSheets , 'x-adopted-style-sheets' , [ ] , {
361- shadow : true ,
362- adoptedStyleSheets : [ sheet ] ,
363- } ) ;
364-
365- root . innerHTML = `<x-adopted-style-sheets></x-adopted-style-sheets>` ;
366-
367- const child = document
368- . querySelector ( 'x-adopted-style-sheets' )
369- . shadowRoot . querySelector ( '.styled-child' ) ;
370-
371- const style = getComputedStyle ( child ) ;
372- assert . equal ( style . color , 'rgb(255, 0, 0)' ) ;
373- } ) ;
374-
375511 it ( 'supports controlling light DOM children' , async ( ) => {
376512 function LightDomChildren ( { children } ) {
377513 return (
@@ -421,47 +557,4 @@ describe('web components', () => {
421557 '<h1>Light DOM Children</h1><div><slot><p>Child 1</p><p>Child 2</p></slot></div>'
422558 ) ;
423559 } ) ;
424-
425- it ( 'supports the `serializable` option' , async ( ) => {
426- function SerializableComponent ( ) {
427- return < div > Serializable Shadow DOM</ div > ;
428- }
429-
430- function NonSerializableComponent ( ) {
431- return < div > Non-serializable Shadow DOM</ div > ;
432- }
433-
434- registerElement ( SerializableComponent , 'x-serializable' , [ ] , {
435- shadow : true ,
436- serializable : true ,
437- } ) ;
438-
439- registerElement ( NonSerializableComponent , 'x-non-serializable' , [ ] , {
440- shadow : true ,
441- } ) ;
442-
443- root . innerHTML = `
444- <x-serializable></x-serializable>
445- <x-non-serializable></x-non-serializable>
446- ` ;
447-
448- const serializableEl = document . querySelector ( 'x-serializable' ) ;
449- const nonSerializableEl = document . querySelector ( 'x-non-serializable' ) ;
450-
451- assert . isTrue ( serializableEl . shadowRoot . serializable ) ;
452- assert . isFalse ( nonSerializableEl . shadowRoot . serializable ) ;
453-
454- const serializableHtml = serializableEl . getHTML ( {
455- serializableShadowRoots : true ,
456- } ) ;
457- const nonSerializableHtml = nonSerializableEl . getHTML ( {
458- serializableShadowRoots : true ,
459- } ) ;
460-
461- assert . equal (
462- serializableHtml ,
463- '<template shadowrootmode="open" shadowrootserializable=""><div>Serializable Shadow DOM</div></template>'
464- ) ;
465- assert . isEmpty ( nonSerializableHtml ) ;
466- } ) ;
467560} ) ;
0 commit comments