Skip to content

Commit 937b680

Browse files
authored
Keep only valid declarations in cssText setter
* Invalid declarations are now be ignored, and nested rules are not part of declaration lists, thus should not be possible to insert with `.style`. * When a nested rule is given, it is now ignored along with the immediately following declaration. * At-rules now cannot be nested, and unlike selectors, when an at-rule occurs in the string, the parser will not ignore the next declaration unless there is a selector before it.
1 parent c966976 commit 937b680

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

lib/CSSStyleDeclaration.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,19 @@ class CSSStyleDeclaration {
186186
);
187187
if (valueObj?.children) {
188188
const properties = new Map();
189+
let shouldSkipNext = false;
189190
for (const item of valueObj.children) {
191+
if (item.type === "Atrule") {
192+
continue;
193+
}
194+
if (item.type === "Rule") {
195+
shouldSkipNext = true;
196+
continue;
197+
}
198+
if (shouldSkipNext === true) {
199+
shouldSkipNext = false;
200+
continue;
201+
}
190202
const {
191203
important,
192204
property,

test/CSSStyleDeclaration.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,58 @@ describe("CSSStyleDeclaration", () => {
156156
assert.strictEqual(style.cssText, "");
157157
});
158158

159+
it("sets only the valid properties for partially valid cssText", () => {
160+
const node = {
161+
nodeType: 1,
162+
style: {},
163+
ownerDocument: {
164+
defaultView: {
165+
DOMException: globalThis.DOMException
166+
}
167+
}
168+
};
169+
const style = new CSSStyleDeclaration(null, {
170+
context: node
171+
});
172+
173+
// valid property followed by invalid property followed by valid property
174+
style.cssText = "color: green; color: invalid!; background: blue;";
175+
// ignores invalid properties
176+
assert.strictEqual(style.cssText, "color: green; background: blue;");
177+
178+
// only valid properties
179+
style.cssText = "color: olivedrab; color: peru; background: bisque;";
180+
// keeps the last one of the same property
181+
assert.strictEqual(style.cssText, "color: peru; background: bisque;");
182+
183+
// valid property followed by a nested selector rule
184+
style.cssText = "color: olivedrab; &.d { color: peru; }";
185+
// ignores the nested selector rule
186+
assert.strictEqual(style.cssText, "color: olivedrab;");
187+
188+
// valid property followed by a nested selector rule followed by two valid properties and an invalid property
189+
style.cssText =
190+
"color: olivedrab; &.d { color: peru; } color: green; background: red; invalid: rule;";
191+
// ignores the property immediately after the nested rule
192+
assert.strictEqual(style.cssText, "color: olivedrab; background: red;");
193+
194+
// valid property followed by a at-rule followed by a valid property
195+
style.cssText = "color: blue; @media screen { color: red; } color: orange;";
196+
// includes the the property immediately after an at-rule
197+
assert.strictEqual(style.cssText, "color: orange;");
198+
199+
// valid property followed by a nested rule, two at-rules and two valid properties
200+
style.cssText = `
201+
color: blue;
202+
&.d { color: peru; }
203+
@media screen { color: red; }
204+
@layer { color: black; }
205+
color: pink;
206+
background: orange;`;
207+
// ignores the first property found after the nested selector rule along with the at-rules
208+
assert.strictEqual(style.cssText, "color: blue; background: orange;");
209+
});
210+
159211
it("sets internals for Element", () => {
160212
const node = {
161213
nodeType: 1,

0 commit comments

Comments
 (0)