@@ -29,6 +29,186 @@ 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+
107+ describe ( 'static properties' , ( ) => {
108+ it ( 'supports `tagName`' , ( ) => {
109+ class TagNameClass extends Component {
110+ static tagName = 'x-tag-name-class' ;
111+
112+ render ( ) {
113+ return < input name = "foo" /> ;
114+ }
115+ }
116+ registerElement ( TagNameClass ) ;
117+
118+ function TagNameFunction ( ) {
119+ return < input name = "bar" /> ;
120+ }
121+ TagNameFunction . tagName = 'x-tag-name-function' ;
122+ registerElement ( TagNameFunction ) ;
123+
124+ root . innerHTML = `
125+ <div>
126+ <x-tag-name-class></x-tag-name-class>
127+ <x-tag-name-function></x-tag-name-function>
128+ </div>
129+ ` ;
130+
131+ assert . isTrue ( ! ! document . querySelector ( 'x-tag-name-class' ) ) ;
132+ assert . isTrue ( ! ! document . querySelector ( 'x-tag-name-function' ) ) ;
133+ } ) ;
134+
135+ it ( 'supports `observedAttributes`' , ( ) => {
136+ class ObservedAttributesClass extends Component {
137+ static observedAttributes = [ 'name' ] ;
138+
139+ render ( { name } ) {
140+ return < input name = { name } /> ;
141+ }
142+ }
143+ registerElement ( ObservedAttributesClass , 'x-observed-attributes-class' ) ;
144+
145+ function ObservedAttributesFunction ( { name } ) {
146+ return < input name = { name } /> ;
147+ }
148+ ObservedAttributesFunction . observedAttributes = [ 'name' ] ;
149+ registerElement (
150+ ObservedAttributesFunction ,
151+ 'x-observed-attributes-function'
152+ ) ;
153+
154+ const observedAttributesClassEl = document . createElement (
155+ 'x-observed-attributes-class'
156+ ) ;
157+ const observedAttributesFunctionEl = document . createElement (
158+ 'x-observed-attributes-function'
159+ ) ;
160+
161+ observedAttributesClassEl . setAttribute ( 'name' , 'class-name' ) ;
162+ observedAttributesFunctionEl . setAttribute ( 'name' , 'function-name' ) ;
163+
164+ root . appendChild ( observedAttributesClassEl ) ;
165+ root . appendChild ( observedAttributesFunctionEl ) ;
166+
167+ assert . equal (
168+ root . innerHTML ,
169+ `<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>`
170+ ) ;
171+
172+ observedAttributesClassEl . setAttribute ( 'name' , 'new-class-name' ) ;
173+ observedAttributesFunctionEl . setAttribute ( 'name' , 'new-function-name' ) ;
174+
175+ assert . equal (
176+ root . innerHTML ,
177+ `<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>`
178+ ) ;
179+ } ) ;
180+
181+ it ( 'supports `formAssociated`' , ( ) => {
182+ class FormAssociatedClass extends Component {
183+ static formAssociated = true ;
184+
185+ render ( ) {
186+ return < input name = "foo" /> ;
187+ }
188+ }
189+ registerElement ( FormAssociatedClass , 'x-form-associated-class' , [ ] ) ;
190+
191+ function FormAssociatedFunction ( ) {
192+ return < input name = "bar" /> ;
193+ }
194+ FormAssociatedFunction . formAssociated = true ;
195+ registerElement ( FormAssociatedFunction , 'x-form-associated-function' , [ ] ) ;
196+
197+ root . innerHTML = `
198+ <form id="myForm">
199+ <x-form-associated-class></x-form-associated-class>
200+ <x-form-associated-function></x-form-associated-function>
201+ </form>
202+ ` ;
203+
204+ const myForm = document . getElementById ( 'myForm' ) ;
205+
206+ // The `.elements` property of a form includes all form-associated elements
207+ assert . equal ( myForm . elements [ 0 ] . tagName , 'X-FORM-ASSOCIATED-CLASS' ) ;
208+ assert . equal ( myForm . elements [ 2 ] . tagName , 'X-FORM-ASSOCIATED-FUNCTION' ) ;
209+ } ) ;
210+ } ) ;
211+
32212 function Clock ( { time } ) {
33213 return < span > { time } </ span > ;
34214 }
@@ -285,93 +465,6 @@ describe('web components', () => {
285465 assert . equal ( getShadowHTML ( ) , '<p>Active theme: sunny</p>' ) ;
286466 } ) ;
287467
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-
375468 it ( 'supports controlling light DOM children' , async ( ) => {
376469 function LightDomChildren ( { children } ) {
377470 return (
0 commit comments