Skip to content

Commit 5486c46

Browse files
committed
Use [ReflectStyle] for basic properties
1 parent 66283a6 commit 5486c46

File tree

4 files changed

+113
-147
lines changed

4 files changed

+113
-147
lines changed

lib/CSSStyleDeclaration-impl.js

+84-129
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@
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');
1210
const idlUtils = require('./utils.js');
1311

1412
class 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-
227214
require('./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-
261216
exports.implementation = CSSStyleDeclarationImpl;

lib/utils/getBasicPropertyDescriptor.js

-14
This file was deleted.

0 commit comments

Comments
 (0)