Skip to content

Commit f29722d

Browse files
domenicclaude
andcommitted
Convert CSSStyleDeclaration to webidl2js
CSSStyleDeclaration was the only CSSOM class not using webidl2js wrappers. This converts it, enabling proper WebIDL type conversion, CEReactions, and PutForwards handling. It also introduces the spec's CSSStyleProperties subclass (with per-CSS-property attributes) as a separate interface, resolving several TODOs. - Add CSSStyleDeclaration.webidl with the standard IDL from the spec - Rename CSSStyleDeclaration.js to CSSStyleDeclaration-impl.js and refactor as a webidl2js impl class (private fields, idiomatic DOMException creation, supportedPropertyIndices/supportsPropertyIndex) - Add CSSStyleProperties-impl.js extending CSSStyleDeclaration, with CSS property attribute descriptors on its prototype - Extend generate-css-style-properties.js to also generate CSSStyleProperties.webidl - Update CSSStyleRule/CSSKeyframeRule/CSSNestedDeclarations to use CSSStyleProperties, CSSPageRule/CSSFontFaceRule to use CSSStyleDeclaration, and ElementCSSInlineStyle to use CSSStyleProperties — all via webidl2js wrappers, removing manual setter hacks - Remove prepareValue() and parseCSS() helpers from css-values.js (webidl2js handles string coercion; callers use csstree directly) - Inline v.trim() in property handler setters now that prepareValue is gone Fixes jsdom/cssstyle#113. Fixes jsdom/cssstyle#235. Fixes jsdom/cssstyle#242. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4aaacc6 commit f29722d

103 files changed

Lines changed: 831 additions & 442 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ node_modules
88
test/web-platform-tests/tuwpt-manifest.json
99
npm-debug.log*
1010

11+
.wireit
1112
lib/generated/
13+
lib/jsdom/living/css/CSSStyleProperties.webidl

lib/jsdom/living/css/CSSFontFaceRule-impl.js

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,23 @@
11
"use strict";
22

33
const CSSRuleImpl = require("./CSSRule-impl.js").implementation;
4-
const { CSSStyleDeclaration } = require("./CSSStyleDeclaration.js");
5-
const { wrapperForImpl } = require("../../../generated/idl/utils.js");
4+
const CSSStyleDeclaration = require("../../../generated/idl/CSSStyleDeclaration.js");
65

76
class CSSFontFaceRuleImpl extends CSSRuleImpl {
87
constructor(globalObject, args, privateData) {
98
super(globalObject, args, privateData);
109

11-
// TODO: after moving `CSSStyleDeclaration` to webidl2js, create a `CSSFontFaceDescriptors` subclass and use that
12-
// here instead, per https://drafts.csswg.org/css-fonts-4/#cssfontfacedescriptors.
13-
this._style = new CSSStyleDeclaration(globalObject, [], {
14-
context: wrapperForImpl(this)
10+
this.style = CSSStyleDeclaration.createImpl(globalObject, [], {
11+
parentRule: this
1512
});
1613
}
1714

1815
get type() {
1916
return 5; // FONT_FACE_RULE
2017
}
2118

22-
get style() {
23-
return this._style;
24-
}
25-
26-
// TODO: delete this setter when CSSStyleDeclaration is converted to webidl2js
27-
// (then [PutForwards=cssText] on the WebIDL attribute will handle it)
28-
set style(value) {
29-
this._style.cssText = value;
30-
}
31-
3219
get cssText() {
33-
return `@font-face { ${this._style.cssText} }`;
20+
return `@font-face { ${this.style.cssText} }`;
3421
}
3522
}
3623

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// https://drafts.csswg.org/css-fonts-4/#om-fontface
22
[Exposed=Window]
33
interface CSSFontFaceRule : CSSRule {
4-
// TODO: change to `[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;`
5-
// when `CSSStyleDeclaration` is converted to webidl2js.
6-
// TODO: use `CSSFontFaceDescriptors` instead of `CSSStyleDeclaration` here.
7-
[SameObject] attribute any style;
4+
// TODO: use `CSSFontFaceDescriptors` instead of `CSSStyleDeclaration` here,
5+
// per https://drafts.csswg.org/css-fonts-4/#cssfontfacedescriptors.
6+
[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
87
};

lib/jsdom/living/css/CSSKeyframeRule-impl.js

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
const CSSRuleImpl = require("./CSSRule-impl.js").implementation;
44
const DOMException = require("../../../generated/idl/DOMException.js");
5-
const { CSSStyleDeclaration } = require("./CSSStyleDeclaration.js");
6-
const { wrapperForImpl } = require("../../../generated/idl/utils.js");
5+
const CSSStyleProperties = require("../../../generated/idl/CSSStyleProperties.js");
76
const csstree = require("./helpers/patched-csstree.js");
87

98
function validateKeyframeSelector(selector) {
@@ -35,9 +34,8 @@ class CSSKeyframeRuleImpl extends CSSRuleImpl {
3534
super(globalObject, args, privateData);
3635
this.#keyText = normalizeKeyText(privateData.keyText);
3736

38-
// Populated by `css-parser.js`'s `populateDeclarations()`.
39-
this._style = new CSSStyleDeclaration(globalObject, [], {
40-
context: wrapperForImpl(this)
37+
this.style = CSSStyleProperties.createImpl(globalObject, [], {
38+
parentRule: this
4139
});
4240
}
4341

@@ -64,18 +62,8 @@ class CSSKeyframeRuleImpl extends CSSRuleImpl {
6462
this.#keyText = normalized.join(", ");
6563
}
6664

67-
get style() {
68-
return this._style;
69-
}
70-
71-
// TODO: delete this setter when CSSStyleDeclaration is converted to webidl2js
72-
// (then [PutForwards=cssText] on the WebIDL attribute will handle it)
73-
set style(value) {
74-
this._style.cssText = value;
75-
}
76-
7765
get cssText() {
78-
return `${this.#keyText} { ${this._style.cssText} }`;
66+
return `${this.#keyText} { ${this.style.cssText} }`;
7967
}
8068
}
8169

lib/jsdom/living/css/CSSKeyframeRule.webidl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@
22
[Exposed=Window]
33
interface CSSKeyframeRule : CSSRule {
44
attribute CSSOMString keyText;
5-
// TODO: change to `[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;`
6-
// when `CSSStyleDeclaration` is converted to webidl2js.
7-
// TODO: use `CSSStyleProperties` instead of `CSSStyleDeclaration` here.
8-
[SameObject] attribute any style;
5+
[SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
96
};

lib/jsdom/living/css/CSSNestedDeclarations-impl.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
11
"use strict";
22

33
const CSSRuleImpl = require("./CSSRule-impl.js").implementation;
4-
const { CSSStyleDeclaration } = require("./CSSStyleDeclaration.js");
5-
const { wrapperForImpl } = require("../../../generated/idl/utils.js");
4+
const CSSStyleProperties = require("../../../generated/idl/CSSStyleProperties.js");
65

76
class CSSNestedDeclarationsImpl extends CSSRuleImpl {
87
constructor(globalObject, args, privateData) {
98
super(globalObject, args, privateData);
10-
this._style = new CSSStyleDeclaration(globalObject, [], {
11-
context: wrapperForImpl(this)
9+
this.style = CSSStyleProperties.createImpl(globalObject, [], {
10+
parentRule: this
1211
});
1312
}
1413

15-
get style() {
16-
return this._style;
17-
}
18-
19-
// TODO: delete this setter when CSSStyleDeclaration is converted to webidl2js
20-
// (then [PutForwards=cssText] on the WebIDL attribute will handle it)
21-
set style(value) {
22-
this._style.cssText = value;
23-
}
24-
2514
get cssText() {
26-
return this._style.cssText;
15+
return this.style.cssText;
2716
}
2817
}
2918

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
// https://drafts.csswg.org/css-nesting/#the-cssnestrule
22
[Exposed=Window]
33
interface CSSNestedDeclarations : CSSRule {
4-
// TODO: change to `[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;`
5-
// when `CSSStyleDeclaration` is converted to webidl2js.
6-
// TODO: use `CSSStyleProperties` instead of `CSSStyleDeclaration` here.
7-
[SameObject] attribute any style;
4+
[SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
85
};

lib/jsdom/living/css/CSSPageRule-impl.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"use strict";
22

33
const CSSGroupingRuleImpl = require("./CSSGroupingRule-impl.js").implementation;
4-
const { CSSStyleDeclaration } = require("./CSSStyleDeclaration.js");
5-
const { wrapperForImpl } = require("../../../generated/idl/utils.js");
4+
const CSSStyleDeclaration = require("../../../generated/idl/CSSStyleDeclaration.js");
65

76
const validPagePseudos = new Set(["first", "left", "right", "blank"]);
87

@@ -54,8 +53,8 @@ class CSSPageRuleImpl extends CSSGroupingRuleImpl {
5453
constructor(globalObject, args, privateData) {
5554
super(globalObject, args, privateData);
5655
this.#selectorText = privateData.selectorText;
57-
this._style = new CSSStyleDeclaration(globalObject, [], {
58-
context: wrapperForImpl(this)
56+
this.style = CSSStyleDeclaration.createImpl(globalObject, [], {
57+
parentRule: this
5958
});
6059
}
6160

@@ -74,18 +73,8 @@ class CSSPageRuleImpl extends CSSGroupingRuleImpl {
7473
}
7574
}
7675

77-
get style() {
78-
return this._style;
79-
}
80-
81-
// TODO: delete this setter when CSSStyleDeclaration is converted to webidl2js
82-
// (then [PutForwards=cssText] on the WebIDL attribute will handle it)
83-
set style(value) {
84-
this._style.cssText = value;
85-
}
86-
8776
get cssText() {
88-
const styleText = this._style.cssText;
77+
const styleText = this.style.cssText;
8978
const selector = this.#selectorText ? ` ${this.#selectorText}` : "";
9079
if (styleText) {
9180
return `@page${selector} { ${styleText} }`;

lib/jsdom/living/css/CSSPageRule.webidl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
[Exposed=Window]
33
interface CSSPageRule : CSSGroupingRule {
44
attribute CSSOMString selectorText;
5-
// TODO: change to `[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;`
6-
// when `CSSStyleDeclaration` is converted to webidl2js.
7-
// TODO: use `CSSPageDescriptors` instead of `CSSStyleDeclaration` here.
8-
[SameObject] attribute any style;
5+
6+
// TODO: use `CSSPageDescriptors` instead of `CSSStyleDeclaration` here, per
7+
// https://drafts.csswg.org/cssom/#csspagedescriptors.
8+
[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
99
};

0 commit comments

Comments
 (0)