33 * https://github.com/NV/CSSOM
44 ********************************************************************/
55'use strict' ;
6- var CSSOM = require ( 'cssom' ) ;
7- var allProperties = require ( './allProperties' ) ;
8- var allExtraProperties = require ( './allExtraProperties' ) ;
9- var implementedProperties = require ( './implementedProperties' ) ;
10- var { cssPropertyToIDLAttribute } = require ( './parsers' ) ;
11- var getBasicPropertyDescriptor = require ( './utils/getBasicPropertyDescriptor' ) ;
6+ const CSSOM = require ( 'cssom' ) ;
7+ const allProperties = require ( './allProperties' ) ;
8+ const allExtraProperties = require ( './allExtraProperties' ) ;
9+ const implementedProperties = require ( './implementedProperties' ) ;
1210const idlUtils = require ( './utils.js' ) ;
1311
1412class CSSStyleDeclarationImpl {
1513 /**
1614 * @constructor
17- * @see http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
15+ * @see https ://drafts.csswg .org/cssom/#cssstyledeclaration
1816 *
1917 * @param {object } globalObject
2018 * @param {*[] } args
@@ -25,15 +23,67 @@ class CSSStyleDeclarationImpl {
2523 this . _globalObject = globalObject ;
2624 this . _values = Object . create ( null ) ;
2725 this . _importants = Object . create ( null ) ;
28- this . _length = 0 ;
26+ this . _list = [ ] ;
2927 this . _onChange = onChangeCallback || ( ( ) => { } ) ;
3028 this . parentRule = null ;
3129 }
3230
31+ /**
32+ * @see https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
33+ */
34+ get cssText ( ) {
35+ const { _list } = this ;
36+ const properties = [ ] ;
37+ for ( let i = 0 ; i < _list . length ; i ++ ) {
38+ const name = _list [ i ] ;
39+ const value = this . getPropertyValue ( name ) ;
40+ let priority = this . getPropertyPriority ( name ) ;
41+ if ( priority !== '' ) {
42+ priority = ` !${ priority } ` ;
43+ }
44+ properties . push ( `${ name } : ${ value } ${ priority } ;` ) ;
45+ }
46+ return properties . join ( ' ' ) ;
47+ }
48+
49+ set cssText ( value ) {
50+ this . _values = Object . create ( null ) ;
51+ this . _importants = Object . create ( null ) ;
52+ this . _list = [ ] ;
53+ let dummyRule ;
54+ try {
55+ dummyRule = CSSOM . parse ( '#bogus{' + value + '}' ) . cssRules [ 0 ] . style ;
56+ } catch ( err ) {
57+ // malformed css, just return
58+ return ;
59+ }
60+ const rule_length = dummyRule . length ;
61+ for ( let i = 0 ; i < rule_length ; ++ i ) {
62+ const name = dummyRule [ i ] ;
63+ this . setProperty (
64+ dummyRule [ i ] ,
65+ dummyRule . getPropertyValue ( name ) ,
66+ dummyRule . getPropertyPriority ( name )
67+ ) ;
68+ }
69+ this . _onChange ( this . cssText ) ;
70+ }
71+
72+ /**
73+ * @see https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-length
74+ */
75+ get length ( ) {
76+ return this . _list . length ;
77+ }
78+
79+ set length ( value ) {
80+ this . _list . length = value ;
81+ }
82+
3383 /**
3484 *
3585 * @param {string } name
36- * @see http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-getPropertyValue
86+ * @see https ://drafts.csswg .org/cssom/#dom-cssstyledeclaration-getpropertyvalue
3787 * @return {string } the value of the property if it has been explicitly set for this declaration block.
3888 * Returns the empty string if the property has not been set.
3989 */
@@ -46,24 +96,29 @@ class CSSStyleDeclarationImpl {
4696 * @param {string } name
4797 * @param {string } value
4898 * @param {string } [priority=""] "important" or ""
49- * @see http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-setProperty
99+ * @see https ://drafts.csswg .org/cssom/#dom-cssstyledeclaration-setproperty
50100 */
51101 setProperty ( name , value , priority = '' ) {
52102 if ( value === '' ) {
53103 this . removeProperty ( name ) ;
54104 return ;
55105 }
56- var isCustomProperty = name . indexOf ( '--' ) === 0 ;
57- if ( isCustomProperty ) {
106+
107+ if ( name . startsWith ( '--' ) ) {
58108 this . _setProperty ( name , value , priority ) ;
59109 return ;
60110 }
61- var lowercaseName = name . toLowerCase ( ) ;
111+
112+ const lowercaseName = name . toLowerCase ( ) ;
62113 if ( ! allProperties . has ( lowercaseName ) && ! allExtraProperties . has ( lowercaseName ) ) {
63114 return ;
64115 }
65116
66- this [ lowercaseName ] = value ;
117+ if ( implementedProperties . has ( lowercaseName ) ) {
118+ this [ lowercaseName ] = value ;
119+ } else {
120+ this . _setProperty ( lowercaseName , value , priority ) ;
121+ }
67122 this . _importants [ lowercaseName ] = priority ;
68123 }
69124
@@ -84,15 +139,12 @@ class CSSStyleDeclarationImpl {
84139 }
85140 if ( this . _values [ name ] ) {
86141 // Property already exist. Overwrite it.
87- var index = Array . prototype . indexOf . call ( this , name ) ;
88- if ( index < 0 ) {
89- this [ this . _length ] = name ;
90- this . _length ++ ;
142+ if ( ! this . _list . includes ( name ) ) {
143+ this . _list . push ( name ) ;
91144 }
92145 } else {
93146 // New property.
94- this [ this . _length ] = name ;
95- this . _length ++ ;
147+ this . _list . push ( name ) ;
96148 }
97149 this . _values [ name ] = value ;
98150 this . _importants [ name ] = priority ;
@@ -102,7 +154,7 @@ class CSSStyleDeclarationImpl {
102154 /**
103155 *
104156 * @param {string } name
105- * @see http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-removeProperty
157+ * @see https ://drafts.csswg .org/cssom/#dom-cssstyledeclaration-removeproperty
106158 * @return {string } the value of the property if it has been explicitly set for this declaration block.
107159 * Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property.
108160 */
@@ -111,20 +163,20 @@ class CSSStyleDeclarationImpl {
111163 return '' ;
112164 }
113165
114- var prevValue = this . _values [ name ] ;
166+ const prevValue = this . _values [ name ] ;
115167 delete this . _values [ name ] ;
116168 delete this . _importants [ name ] ;
117169
118- var index = Array . prototype . indexOf . call ( this , name ) ;
170+ const index = this . _list . indexOf ( name ) ;
119171 if ( index < 0 ) {
120172 return prevValue ;
121173 }
122174
123175 // That's what WebKit and Opera do
124- Array . prototype . splice . call ( this , index , 1 ) ;
176+ this . _list . splice ( index , 1 ) ;
125177
126178 // That's what Firefox does
127- //this[index] = ""
179+ //this._list [index] = ''
128180
129181 this . _onChange ( this . cssText ) ;
130182 return prevValue ;
@@ -133,129 +185,32 @@ class CSSStyleDeclarationImpl {
133185 /**
134186 *
135187 * @param {String } name
188+ * @see https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertypriority
136189 */
137190 getPropertyPriority ( name ) {
138191 return this . _importants [ name ] || '' ;
139192 }
140193
141194 /**
142- * http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration -item
195+ * @see https ://drafts.csswg .org/cssom/#dom-cssstyledeclaration -item
143196 */
144197 item ( index ) {
145- if ( index < 0 || index >= this . _length ) {
198+ const { _list } = this ;
199+ if ( index < 0 || index >= _list . length ) {
146200 return '' ;
147201 }
148- return this [ index ] ;
202+ return _list [ index ] ;
149203 }
150204
151205 [ idlUtils . supportsPropertyIndex ] ( index ) {
152- return index >= 0 && index < this . _length ;
206+ return index >= 0 && index < this . _list . length ;
153207 }
154208
155209 [ idlUtils . supportedPropertyIndices ] ( ) {
156- return Array . prototype . keys . call ( this ) ;
210+ return this . _list . keys ( ) ;
157211 }
158212}
159213
160- Object . defineProperties ( CSSStyleDeclarationImpl . prototype , {
161- cssText : {
162- get : function ( ) {
163- var properties = [ ] ;
164- var i ;
165- var name ;
166- var value ;
167- var priority ;
168- for ( i = 0 ; i < this . _length ; i ++ ) {
169- name = this [ i ] ;
170- value = this . getPropertyValue ( name ) ;
171- priority = this . getPropertyPriority ( name ) ;
172- if ( priority !== '' ) {
173- priority = ` !${ priority } ` ;
174- }
175- properties . push ( `${ name } : ${ value } ${ priority } ;` ) ;
176- }
177- return properties . join ( ' ' ) ;
178- } ,
179- set : function ( value ) {
180- var i ;
181- this . _values = { } ;
182- Array . prototype . splice . call ( this , 0 , this . _length ) ;
183- this . _importants = { } ;
184- var dummyRule ;
185- try {
186- dummyRule = CSSOM . parse ( '#bogus{' + value + '}' ) . cssRules [ 0 ] . style ;
187- } catch ( err ) {
188- // malformed css, just return
189- return ;
190- }
191- var rule_length = dummyRule . length ;
192- var name ;
193- for ( i = 0 ; i < rule_length ; ++ i ) {
194- name = dummyRule [ i ] ;
195- this . setProperty (
196- dummyRule [ i ] ,
197- dummyRule . getPropertyValue ( name ) ,
198- dummyRule . getPropertyPriority ( name )
199- ) ;
200- }
201- this . _onChange ( this . cssText ) ;
202- } ,
203- enumerable : true ,
204- configurable : true ,
205- } ,
206- length : {
207- get : function ( ) {
208- return this . _length ;
209- } ,
210- /**
211- * This deletes indices if the new length is less then the current
212- * length. If the new length is more, it does nothing, the new indices
213- * will be undefined until set.
214- **/
215- set : function ( value ) {
216- var i ;
217- for ( i = value ; i < this . _length ; i ++ ) {
218- delete this [ i ] ;
219- }
220- this . _length = value ;
221- } ,
222- enumerable : true ,
223- configurable : true ,
224- } ,
225- } ) ;
226-
227214require ( './properties' ) ( CSSStyleDeclarationImpl . prototype ) ;
228215
229- // TODO: Consider using `[Reflect]` for basic properties
230- allProperties . forEach ( function ( property ) {
231- if ( ! implementedProperties . has ( property ) ) {
232- var declaration = getBasicPropertyDescriptor ( property ) ;
233- Object . defineProperty ( CSSStyleDeclarationImpl . prototype , property , declaration ) ;
234- Object . defineProperty (
235- CSSStyleDeclarationImpl . prototype ,
236- cssPropertyToIDLAttribute ( property ) ,
237- declaration
238- ) ;
239- }
240- } ) ;
241-
242- allExtraProperties . forEach ( function ( property ) {
243- if ( ! implementedProperties . has ( property ) ) {
244- var declaration = getBasicPropertyDescriptor ( property ) ;
245- Object . defineProperty ( CSSStyleDeclarationImpl . prototype , property , declaration ) ;
246- Object . defineProperty (
247- CSSStyleDeclarationImpl . prototype ,
248- cssPropertyToIDLAttribute ( property ) ,
249- declaration
250- ) ;
251- if ( property . startsWith ( '-webkit-' ) ) {
252- Object . defineProperty (
253- CSSStyleDeclarationImpl . prototype ,
254- cssPropertyToIDLAttribute ( property , /* lowercaseFirst = */ true ) ,
255- declaration
256- ) ;
257- }
258- }
259- } ) ;
260-
261216exports . implementation = CSSStyleDeclarationImpl ;
0 commit comments