3
3
* https://github.com/NV/CSSOM
4
4
********************************************************************/
5
5
'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' ) ;
12
10
const idlUtils = require ( './utils.js' ) ;
13
11
14
12
class CSSStyleDeclarationImpl {
15
13
/**
16
14
* @constructor
17
- * @see http ://www.w3 .org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
15
+ * @see https ://drafts.csswg .org/cssom/#cssstyledeclaration
18
16
*
19
17
* @param {object } globalObject
20
18
* @param {*[] } args
@@ -25,15 +23,67 @@ class CSSStyleDeclarationImpl {
25
23
this . _globalObject = globalObject ;
26
24
this . _values = Object . create ( null ) ;
27
25
this . _importants = Object . create ( null ) ;
28
- this . _length = 0 ;
26
+ this . _list = [ ] ;
29
27
this . _onChange = onChangeCallback || ( ( ) => { } ) ;
30
28
this . parentRule = null ;
31
29
}
32
30
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
+
33
83
/**
34
84
*
35
85
* @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
37
87
* @return {string } the value of the property if it has been explicitly set for this declaration block.
38
88
* Returns the empty string if the property has not been set.
39
89
*/
@@ -46,24 +96,29 @@ class CSSStyleDeclarationImpl {
46
96
* @param {string } name
47
97
* @param {string } value
48
98
* @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
50
100
*/
51
101
setProperty ( name , value , priority = '' ) {
52
102
if ( value === '' ) {
53
103
this . removeProperty ( name ) ;
54
104
return ;
55
105
}
56
- var isCustomProperty = name . indexOf ( '--' ) === 0 ;
57
- if ( isCustomProperty ) {
106
+
107
+ if ( name . startsWith ( '--' ) ) {
58
108
this . _setProperty ( name , value , priority ) ;
59
109
return ;
60
110
}
61
- var lowercaseName = name . toLowerCase ( ) ;
111
+
112
+ const lowercaseName = name . toLowerCase ( ) ;
62
113
if ( ! allProperties . has ( lowercaseName ) && ! allExtraProperties . has ( lowercaseName ) ) {
63
114
return ;
64
115
}
65
116
66
- this [ lowercaseName ] = value ;
117
+ if ( implementedProperties . has ( lowercaseName ) ) {
118
+ this [ lowercaseName ] = value ;
119
+ } else {
120
+ this . _setProperty ( lowercaseName , value , priority ) ;
121
+ }
67
122
this . _importants [ lowercaseName ] = priority ;
68
123
}
69
124
@@ -84,15 +139,12 @@ class CSSStyleDeclarationImpl {
84
139
}
85
140
if ( this . _values [ name ] ) {
86
141
// 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 ) ;
91
144
}
92
145
} else {
93
146
// New property.
94
- this [ this . _length ] = name ;
95
- this . _length ++ ;
147
+ this . _list . push ( name ) ;
96
148
}
97
149
this . _values [ name ] = value ;
98
150
this . _importants [ name ] = priority ;
@@ -102,7 +154,7 @@ class CSSStyleDeclarationImpl {
102
154
/**
103
155
*
104
156
* @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
106
158
* @return {string } the value of the property if it has been explicitly set for this declaration block.
107
159
* Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property.
108
160
*/
@@ -111,20 +163,20 @@ class CSSStyleDeclarationImpl {
111
163
return '' ;
112
164
}
113
165
114
- var prevValue = this . _values [ name ] ;
166
+ const prevValue = this . _values [ name ] ;
115
167
delete this . _values [ name ] ;
116
168
delete this . _importants [ name ] ;
117
169
118
- var index = Array . prototype . indexOf . call ( this , name ) ;
170
+ const index = this . _list . indexOf ( name ) ;
119
171
if ( index < 0 ) {
120
172
return prevValue ;
121
173
}
122
174
123
175
// That's what WebKit and Opera do
124
- Array . prototype . splice . call ( this , index , 1 ) ;
176
+ this . _list . splice ( index , 1 ) ;
125
177
126
178
// That's what Firefox does
127
- //this[index] = ""
179
+ //this._list [index] = ''
128
180
129
181
this . _onChange ( this . cssText ) ;
130
182
return prevValue ;
@@ -133,129 +185,32 @@ class CSSStyleDeclarationImpl {
133
185
/**
134
186
*
135
187
* @param {String } name
188
+ * @see https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertypriority
136
189
*/
137
190
getPropertyPriority ( name ) {
138
191
return this . _importants [ name ] || '' ;
139
192
}
140
193
141
194
/**
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
143
196
*/
144
197
item ( index ) {
145
- if ( index < 0 || index >= this . _length ) {
198
+ const { _list } = this ;
199
+ if ( index < 0 || index >= _list . length ) {
146
200
return '' ;
147
201
}
148
- return this [ index ] ;
202
+ return _list [ index ] ;
149
203
}
150
204
151
205
[ idlUtils . supportsPropertyIndex ] ( index ) {
152
- return index >= 0 && index < this . _length ;
206
+ return index >= 0 && index < this . _list . length ;
153
207
}
154
208
155
209
[ idlUtils . supportedPropertyIndices ] ( ) {
156
- return Array . prototype . keys . call ( this ) ;
210
+ return this . _list . keys ( ) ;
157
211
}
158
212
}
159
213
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
-
227
214
require ( './properties' ) ( CSSStyleDeclarationImpl . prototype ) ;
228
215
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
-
261
216
exports . implementation = CSSStyleDeclarationImpl ;
0 commit comments