@depup/jsdom 29.0.2-depup.0 → 29.1.1-depup.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -8
- package/changes.json +24 -12
- package/lib/generated/css-property-definitions.js +72 -53
- package/lib/generated/css-property-descriptors.js +26 -24
- package/lib/generated/css-property-metadata.js +8 -24
- package/lib/generated/idl/CSSStyleProperties.js +82 -0
- package/lib/jsdom/living/css/CSSGroupingRule-impl.js +4 -1
- package/lib/jsdom/living/css/CSSStyleDeclaration-impl.js +10 -3
- package/lib/jsdom/living/css/CSSStyleSheet-impl.js +7 -1
- package/lib/jsdom/living/css/helpers/computed-style.js +43 -10
- package/lib/jsdom/living/css/helpers/css-values.js +20 -0
- package/lib/jsdom/living/css/helpers/generic-property-descriptor.js +4 -1
- package/lib/jsdom/living/css/helpers/shorthand-properties.js +11 -7
- package/lib/jsdom/living/css/helpers/stylesheets.js +2 -3
- package/lib/jsdom/living/css/properties/background.js +32 -33
- package/lib/jsdom/living/nodes/Document-impl.js +4 -0
- package/lib/jsdom/living/nodes/Node-impl.js +6 -3
- package/package.json +38 -26
|
@@ -799,8 +799,8 @@ module.exports = new Map([
|
|
|
799
799
|
{
|
|
800
800
|
"caseSensitive": false,
|
|
801
801
|
"dimensionTypes": {
|
|
802
|
-
"
|
|
803
|
-
"type": "
|
|
802
|
+
"ratio": {
|
|
803
|
+
"type": "ratio"
|
|
804
804
|
}
|
|
805
805
|
}
|
|
806
806
|
}
|
|
@@ -3674,6 +3674,12 @@ module.exports = new Map([
|
|
|
3674
3674
|
"caseSensitive": false
|
|
3675
3675
|
}
|
|
3676
3676
|
],
|
|
3677
|
+
[
|
|
3678
|
+
"frame-sizing",
|
|
3679
|
+
{
|
|
3680
|
+
"caseSensitive": false
|
|
3681
|
+
}
|
|
3682
|
+
],
|
|
3677
3683
|
[
|
|
3678
3684
|
"gap",
|
|
3679
3685
|
{
|
|
@@ -5120,8 +5126,6 @@ module.exports = new Map([
|
|
|
5120
5126
|
"caseSensitive": false,
|
|
5121
5127
|
"dimensionTypes": {
|
|
5122
5128
|
"length": {
|
|
5123
|
-
"max": null,
|
|
5124
|
-
"min": 0,
|
|
5125
5129
|
"type": "length"
|
|
5126
5130
|
}
|
|
5127
5131
|
}
|
|
@@ -5133,8 +5137,6 @@ module.exports = new Map([
|
|
|
5133
5137
|
"caseSensitive": false,
|
|
5134
5138
|
"dimensionTypes": {
|
|
5135
5139
|
"length": {
|
|
5136
|
-
"max": null,
|
|
5137
|
-
"min": 0,
|
|
5138
5140
|
"type": "length"
|
|
5139
5141
|
}
|
|
5140
5142
|
}
|
|
@@ -5146,8 +5148,6 @@ module.exports = new Map([
|
|
|
5146
5148
|
"caseSensitive": false,
|
|
5147
5149
|
"dimensionTypes": {
|
|
5148
5150
|
"length": {
|
|
5149
|
-
"max": null,
|
|
5150
|
-
"min": 0,
|
|
5151
5151
|
"type": "length"
|
|
5152
5152
|
}
|
|
5153
5153
|
}
|
|
@@ -5159,8 +5159,6 @@ module.exports = new Map([
|
|
|
5159
5159
|
"caseSensitive": false,
|
|
5160
5160
|
"dimensionTypes": {
|
|
5161
5161
|
"length": {
|
|
5162
|
-
"max": null,
|
|
5163
|
-
"min": 0,
|
|
5164
5162
|
"type": "length"
|
|
5165
5163
|
}
|
|
5166
5164
|
}
|
|
@@ -5172,8 +5170,6 @@ module.exports = new Map([
|
|
|
5172
5170
|
"caseSensitive": false,
|
|
5173
5171
|
"dimensionTypes": {
|
|
5174
5172
|
"length": {
|
|
5175
|
-
"max": null,
|
|
5176
|
-
"min": 0,
|
|
5177
5173
|
"type": "length"
|
|
5178
5174
|
}
|
|
5179
5175
|
}
|
|
@@ -5185,8 +5181,6 @@ module.exports = new Map([
|
|
|
5185
5181
|
"caseSensitive": false,
|
|
5186
5182
|
"dimensionTypes": {
|
|
5187
5183
|
"length": {
|
|
5188
|
-
"max": null,
|
|
5189
|
-
"min": 0,
|
|
5190
5184
|
"type": "length"
|
|
5191
5185
|
}
|
|
5192
5186
|
}
|
|
@@ -5198,8 +5192,6 @@ module.exports = new Map([
|
|
|
5198
5192
|
"caseSensitive": false,
|
|
5199
5193
|
"dimensionTypes": {
|
|
5200
5194
|
"length": {
|
|
5201
|
-
"max": null,
|
|
5202
|
-
"min": 0,
|
|
5203
5195
|
"type": "length"
|
|
5204
5196
|
}
|
|
5205
5197
|
}
|
|
@@ -5211,8 +5203,6 @@ module.exports = new Map([
|
|
|
5211
5203
|
"caseSensitive": false,
|
|
5212
5204
|
"dimensionTypes": {
|
|
5213
5205
|
"length": {
|
|
5214
|
-
"max": null,
|
|
5215
|
-
"min": 0,
|
|
5216
5206
|
"type": "length"
|
|
5217
5207
|
}
|
|
5218
5208
|
}
|
|
@@ -5224,8 +5214,6 @@ module.exports = new Map([
|
|
|
5224
5214
|
"caseSensitive": false,
|
|
5225
5215
|
"dimensionTypes": {
|
|
5226
5216
|
"length": {
|
|
5227
|
-
"max": null,
|
|
5228
|
-
"min": 0,
|
|
5229
5217
|
"type": "length"
|
|
5230
5218
|
}
|
|
5231
5219
|
}
|
|
@@ -5237,8 +5225,6 @@ module.exports = new Map([
|
|
|
5237
5225
|
"caseSensitive": false,
|
|
5238
5226
|
"dimensionTypes": {
|
|
5239
5227
|
"length": {
|
|
5240
|
-
"max": null,
|
|
5241
|
-
"min": 0,
|
|
5242
5228
|
"type": "length"
|
|
5243
5229
|
}
|
|
5244
5230
|
}
|
|
@@ -5250,8 +5236,6 @@ module.exports = new Map([
|
|
|
5250
5236
|
"caseSensitive": false,
|
|
5251
5237
|
"dimensionTypes": {
|
|
5252
5238
|
"length": {
|
|
5253
|
-
"max": null,
|
|
5254
|
-
"min": 0,
|
|
5255
5239
|
"type": "length"
|
|
5256
5240
|
}
|
|
5257
5241
|
}
|
|
@@ -32661,6 +32661,86 @@ exports.install = (globalObject, globalNames) => {
|
|
|
32661
32661
|
}
|
|
32662
32662
|
}
|
|
32663
32663
|
|
|
32664
|
+
get "frame-sizing"() {
|
|
32665
|
+
const esValue = this !== null && this !== undefined ? this : globalObject;
|
|
32666
|
+
|
|
32667
|
+
if (!exports.is(esValue)) {
|
|
32668
|
+
throw new globalObject.TypeError(
|
|
32669
|
+
"'get frame-sizing' called on an object that is not a valid instance of CSSStyleProperties."
|
|
32670
|
+
);
|
|
32671
|
+
}
|
|
32672
|
+
|
|
32673
|
+
ceReactionsPreSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32674
|
+
try {
|
|
32675
|
+
return utils.tryWrapperForImpl(esValue[implSymbol]["frame-sizing"]);
|
|
32676
|
+
} finally {
|
|
32677
|
+
ceReactionsPostSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32678
|
+
}
|
|
32679
|
+
}
|
|
32680
|
+
|
|
32681
|
+
set "frame-sizing"(V) {
|
|
32682
|
+
const esValue = this !== null && this !== undefined ? this : globalObject;
|
|
32683
|
+
|
|
32684
|
+
if (!exports.is(esValue)) {
|
|
32685
|
+
throw new globalObject.TypeError(
|
|
32686
|
+
"'set frame-sizing' called on an object that is not a valid instance of CSSStyleProperties."
|
|
32687
|
+
);
|
|
32688
|
+
}
|
|
32689
|
+
|
|
32690
|
+
V = conversions["DOMString"](V, {
|
|
32691
|
+
context: "Failed to set the 'frame-sizing' property on 'CSSStyleProperties': The provided value",
|
|
32692
|
+
globals: globalObject,
|
|
32693
|
+
treatNullAsEmptyString: true
|
|
32694
|
+
});
|
|
32695
|
+
|
|
32696
|
+
ceReactionsPreSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32697
|
+
try {
|
|
32698
|
+
esValue[implSymbol]["frame-sizing"] = V;
|
|
32699
|
+
} finally {
|
|
32700
|
+
ceReactionsPostSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32701
|
+
}
|
|
32702
|
+
}
|
|
32703
|
+
|
|
32704
|
+
get frameSizing() {
|
|
32705
|
+
const esValue = this !== null && this !== undefined ? this : globalObject;
|
|
32706
|
+
|
|
32707
|
+
if (!exports.is(esValue)) {
|
|
32708
|
+
throw new globalObject.TypeError(
|
|
32709
|
+
"'get frameSizing' called on an object that is not a valid instance of CSSStyleProperties."
|
|
32710
|
+
);
|
|
32711
|
+
}
|
|
32712
|
+
|
|
32713
|
+
ceReactionsPreSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32714
|
+
try {
|
|
32715
|
+
return utils.tryWrapperForImpl(esValue[implSymbol]["frameSizing"]);
|
|
32716
|
+
} finally {
|
|
32717
|
+
ceReactionsPostSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32718
|
+
}
|
|
32719
|
+
}
|
|
32720
|
+
|
|
32721
|
+
set frameSizing(V) {
|
|
32722
|
+
const esValue = this !== null && this !== undefined ? this : globalObject;
|
|
32723
|
+
|
|
32724
|
+
if (!exports.is(esValue)) {
|
|
32725
|
+
throw new globalObject.TypeError(
|
|
32726
|
+
"'set frameSizing' called on an object that is not a valid instance of CSSStyleProperties."
|
|
32727
|
+
);
|
|
32728
|
+
}
|
|
32729
|
+
|
|
32730
|
+
V = conversions["DOMString"](V, {
|
|
32731
|
+
context: "Failed to set the 'frameSizing' property on 'CSSStyleProperties': The provided value",
|
|
32732
|
+
globals: globalObject,
|
|
32733
|
+
treatNullAsEmptyString: true
|
|
32734
|
+
});
|
|
32735
|
+
|
|
32736
|
+
ceReactionsPreSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32737
|
+
try {
|
|
32738
|
+
esValue[implSymbol]["frameSizing"] = V;
|
|
32739
|
+
} finally {
|
|
32740
|
+
ceReactionsPostSteps_jsdom_living_helpers_custom_elements(globalObject);
|
|
32741
|
+
}
|
|
32742
|
+
}
|
|
32743
|
+
|
|
32664
32744
|
get gap() {
|
|
32665
32745
|
const esValue = this !== null && this !== undefined ? this : globalObject;
|
|
32666
32746
|
|
|
@@ -65773,6 +65853,8 @@ exports.install = (globalObject, globalNames) => {
|
|
|
65773
65853
|
footnotePolicy: { enumerable: true },
|
|
65774
65854
|
"forced-color-adjust": { enumerable: true },
|
|
65775
65855
|
forcedColorAdjust: { enumerable: true },
|
|
65856
|
+
"frame-sizing": { enumerable: true },
|
|
65857
|
+
frameSizing: { enumerable: true },
|
|
65776
65858
|
gap: { enumerable: true },
|
|
65777
65859
|
"glyph-orientation-vertical": { enumerable: true },
|
|
65778
65860
|
glyphOrientationVertical: { enumerable: true },
|
|
@@ -12,11 +12,14 @@ class CSSGroupingRuleImpl extends CSSRuleImpl {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
insertRule(rule, index) {
|
|
15
|
-
|
|
15
|
+
const result = this.cssRules._insert(rule, index, this._isInNestingContext(), this, this.parentStyleSheet);
|
|
16
|
+
this.parentStyleSheet?.ownerNode?._ownerDocument._clearStyleCache();
|
|
17
|
+
return result;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
deleteRule(index) {
|
|
19
21
|
this.cssRules._remove(index);
|
|
22
|
+
this.parentStyleSheet?.ownerNode?._ownerDocument._clearStyleCache();
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
_isInNestingContext() {
|
|
@@ -391,10 +391,17 @@ class CSSStyleDeclarationImpl {
|
|
|
391
391
|
case "padding": {
|
|
392
392
|
return this.#resolvePositionShorthand(property);
|
|
393
393
|
}
|
|
394
|
+
case "border":
|
|
395
|
+
case "border-top":
|
|
396
|
+
case "border-right":
|
|
397
|
+
case "border-bottom":
|
|
398
|
+
case "border-left":
|
|
399
|
+
case "border-width":
|
|
400
|
+
case "border-style":
|
|
401
|
+
case "border-color": {
|
|
402
|
+
return this.#resolveBorderShorthands(property);
|
|
403
|
+
}
|
|
394
404
|
default: {
|
|
395
|
-
if (property.startsWith("border")) {
|
|
396
|
-
return this.#resolveBorderShorthands(property);
|
|
397
|
-
}
|
|
398
405
|
return value;
|
|
399
406
|
}
|
|
400
407
|
}
|
|
@@ -37,7 +37,9 @@ class CSSStyleSheetImpl extends StyleSheetImpl {
|
|
|
37
37
|
]);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const result = this.cssRules._insertParsed(parsed, index, null, this);
|
|
41
|
+
this.ownerNode?._ownerDocument._clearStyleCache();
|
|
42
|
+
return result;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
deleteRule(index) {
|
|
@@ -45,6 +47,7 @@ class CSSStyleSheetImpl extends StyleSheetImpl {
|
|
|
45
47
|
this.#checkModificationAllowed();
|
|
46
48
|
|
|
47
49
|
this.cssRules._remove(index);
|
|
50
|
+
this.ownerNode?._ownerDocument._clearStyleCache();
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
// Legacy method
|
|
@@ -81,6 +84,8 @@ class CSSStyleSheetImpl extends StyleSheetImpl {
|
|
|
81
84
|
|
|
82
85
|
// Parse and populate
|
|
83
86
|
cssParser.parseIntoStyleSheet(text, this._globalObject, this);
|
|
87
|
+
|
|
88
|
+
this.ownerNode?._ownerDocument._clearStyleCache();
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
replace(text) {
|
|
@@ -107,6 +112,7 @@ class CSSStyleSheetImpl extends StyleSheetImpl {
|
|
|
107
112
|
this.cssRules._clear();
|
|
108
113
|
cssParser.parseIntoStyleSheet(text, this._globalObject, this);
|
|
109
114
|
this.#disallowModification = false;
|
|
115
|
+
this.ownerNode?._ownerDocument._clearStyleCache();
|
|
110
116
|
|
|
111
117
|
// webidl2js doesn't auto-wrap return values: https://github.com/jsdom/webidl2js/issues/257
|
|
112
118
|
resolve(wrapperForImpl(this));
|
|
@@ -99,9 +99,11 @@ function handleSheet(sheetImpl, elementImpl, declaration, specificities) {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function handleRule(ruleImpl, elementImpl, declaration, specificities) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
if (ruleMightMatchElement(ruleImpl, elementImpl)) {
|
|
103
|
+
const { ast, match } = matches(ruleImpl.selectorText, elementImpl);
|
|
104
|
+
if (match) {
|
|
105
|
+
handleStyle(ruleImpl.style, declaration, specificities, ast);
|
|
106
|
+
}
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -139,6 +141,44 @@ function handlePropertyForInlineStyle(property, declaration, style) {
|
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
function ruleMightMatchElement(ruleImpl, elementImpl) {
|
|
145
|
+
if (!ruleImpl._selectorSubjects) {
|
|
146
|
+
const domSelector = elementImpl._ownerDocument._getDOMSelector();
|
|
147
|
+
ruleImpl._selectorSubjects =
|
|
148
|
+
domSelector.extractSubjects(
|
|
149
|
+
ruleImpl.selectorText,
|
|
150
|
+
elementImpl._ownerDocument.contentType !== "text/html"
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const subjects = ruleImpl._selectorSubjects;
|
|
155
|
+
if (subjects.length === 0) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const id = elementImpl.getAttributeNS(null, "id");
|
|
160
|
+
const { classList } = elementImpl;
|
|
161
|
+
// TODO: Remove toLowerCase() after updating the dom-selector.
|
|
162
|
+
const tag = elementImpl._localName.toLowerCase();
|
|
163
|
+
for (const keys of subjects) {
|
|
164
|
+
let mightMatch = true;
|
|
165
|
+
if (keys.id && keys.id !== id) {
|
|
166
|
+
mightMatch = false;
|
|
167
|
+
} else if (keys.className && !classList.contains(keys.className)) {
|
|
168
|
+
mightMatch = false;
|
|
169
|
+
// TODO: Remove toLowerCase() after updating the dom-selector.
|
|
170
|
+
} else if (keys.tag && keys.tag.toLowerCase() !== tag) {
|
|
171
|
+
mightMatch = false;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (mightMatch) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
142
182
|
function matches(selectorText, elementImpl) {
|
|
143
183
|
const domSelector = elementImpl._ownerDocument._getDOMSelector();
|
|
144
184
|
const { ast, match, pseudoElement } = domSelector.check(selectorText, elementImpl);
|
|
@@ -261,14 +301,7 @@ function replaceGlobalKeywords(property, value, elementImpl, { inherit, initial,
|
|
|
261
301
|
return value;
|
|
262
302
|
}
|
|
263
303
|
|
|
264
|
-
function invalidateStyleCache(elementImpl) {
|
|
265
|
-
if (elementImpl._attached) {
|
|
266
|
-
elementImpl._ownerDocument._styleCache = new WeakMap();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
304
|
exports.SHADOW_DOM_PSEUDO_REGEXP = /^::(?:part|slotted)\(/i;
|
|
271
305
|
exports.getComputedStyleDeclaration = getComputedStyleDeclaration;
|
|
272
306
|
exports.getInheritedPropertyValue = getInheritedPropertyValue;
|
|
273
|
-
exports.invalidateStyleCache = invalidateStyleCache;
|
|
274
307
|
exports.replaceEmptyValueAndKeywords = replaceEmptyValueAndKeywords;
|
|
@@ -27,6 +27,7 @@ const AST_TYPES = Object.freeze({
|
|
|
27
27
|
IDENTIFIER: "Identifier",
|
|
28
28
|
NUMBER: "Number",
|
|
29
29
|
PERCENTAGE: "Percentage",
|
|
30
|
+
RATIO: "Ratio",
|
|
30
31
|
STRING: "String",
|
|
31
32
|
URL: "Url"
|
|
32
33
|
});
|
|
@@ -438,6 +439,24 @@ function serializePercentage(val, opt = {}) {
|
|
|
438
439
|
return `${num}%`;
|
|
439
440
|
}
|
|
440
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Serializes a <ratio> value.
|
|
444
|
+
*
|
|
445
|
+
* @param {Array<object>} val - The AST value.
|
|
446
|
+
* @returns {string|undefined} The serialized ratio.
|
|
447
|
+
*/
|
|
448
|
+
function serializeRatio(val) {
|
|
449
|
+
const res = parseNumericValue(
|
|
450
|
+
val,
|
|
451
|
+
{ max: Number.INFINITY, min: 0 },
|
|
452
|
+
type => type === AST_TYPES.NUMBER
|
|
453
|
+
);
|
|
454
|
+
if (!res) {
|
|
455
|
+
return undefined;
|
|
456
|
+
}
|
|
457
|
+
return `${res.num} / 1`;
|
|
458
|
+
}
|
|
459
|
+
|
|
441
460
|
/**
|
|
442
461
|
* Serializes a <url> value.
|
|
443
462
|
*
|
|
@@ -810,6 +829,7 @@ exports.serializeGradient = serializeGradient;
|
|
|
810
829
|
exports.serializeLength = serializeLength;
|
|
811
830
|
exports.serializeNumber = serializeNumber;
|
|
812
831
|
exports.serializePercentage = serializePercentage;
|
|
832
|
+
exports.serializeRatio = serializeRatio;
|
|
813
833
|
exports.serializeString = serializeString;
|
|
814
834
|
exports.serializeURL = serializeURL;
|
|
815
835
|
exports.splitValue = splitValue;
|
|
@@ -38,7 +38,8 @@ function createGenericPropertyDescriptor(property, { caseSensitive, dimensionTyp
|
|
|
38
38
|
dimension: dimensionType,
|
|
39
39
|
length: lengthType,
|
|
40
40
|
number: numberType,
|
|
41
|
-
percentage: percentageType
|
|
41
|
+
percentage: percentageType,
|
|
42
|
+
ratio: ratioType
|
|
42
43
|
} = dimensionTypes;
|
|
43
44
|
const { color: colorType, image: imageType, paint: paintType } = functionTypes;
|
|
44
45
|
const [{ name, type, value: itemValue }] = parsedValue;
|
|
@@ -76,6 +77,8 @@ function createGenericPropertyDescriptor(property, { caseSensitive, dimensionTyp
|
|
|
76
77
|
val = parsers.serializeLength(parsedValue, lengthType);
|
|
77
78
|
} else if (percentageType) {
|
|
78
79
|
val = parsers.serializePercentage(parsedValue, percentageType);
|
|
80
|
+
} else if (ratioType) {
|
|
81
|
+
val = parsers.serializeRatio(parsedValue, ratioType);
|
|
79
82
|
}
|
|
80
83
|
this._setProperty(property, val, priority);
|
|
81
84
|
break;
|
|
@@ -234,18 +234,22 @@ function replaceBackgroundShorthand(property, properties) {
|
|
|
234
234
|
const isDefaultBox =
|
|
235
235
|
originValue === background.initialValues.get("background-origin") &&
|
|
236
236
|
clipValue === background.initialValues.get("background-clip");
|
|
237
|
+
let boxSet = false;
|
|
237
238
|
for (const longhand of background.initialValues.keys()) {
|
|
238
239
|
const value = bgValue[longhand];
|
|
239
240
|
if (!value) {
|
|
240
241
|
continue;
|
|
241
242
|
}
|
|
242
|
-
if (longhand === "background-origin") {
|
|
243
|
-
if (
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
243
|
+
if (longhand === "background-origin" || longhand === "background-clip") {
|
|
244
|
+
if (isDefaultBox || boxSet) {
|
|
245
|
+
continue;
|
|
246
|
+
} else {
|
|
247
|
+
if (originValue === clipValue) {
|
|
248
|
+
bg.push(originValue);
|
|
249
|
+
} else {
|
|
250
|
+
bg.push(originValue, clipValue);
|
|
251
|
+
}
|
|
252
|
+
boxSet = true;
|
|
249
253
|
}
|
|
250
254
|
} else if (value !== background.initialValues.get(longhand)) {
|
|
251
255
|
if (longhand === "background-position") {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
const { legacyHookDecode } = require("@exodus/bytes/encoding.js");
|
|
3
3
|
const whatwgURL = require("whatwg-url");
|
|
4
4
|
const { parseStyleSheet, parseIntoStyleSheet } = require("./css-parser");
|
|
5
|
-
const { invalidateStyleCache } = require("./computed-style");
|
|
6
5
|
|
|
7
6
|
// TODO: this should really implement https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet
|
|
8
7
|
// It (and the things it calls) is nowhere close right now.
|
|
@@ -54,7 +53,7 @@ exports.removeStyleSheet = (sheet, elementImpl) => {
|
|
|
54
53
|
// Remove the association explicitly; in the spec it's implicit so this step doesn't exist.
|
|
55
54
|
elementImpl.sheet = null;
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
elementImpl._ownerDocument._clearStyleCache();
|
|
58
57
|
|
|
59
58
|
sheet.parentStyleSheet = null;
|
|
60
59
|
sheet.ownerNode = null;
|
|
@@ -112,7 +111,7 @@ exports.addStyleSheet = (sheet, elementImpl) => {
|
|
|
112
111
|
// Set the association explicitly; in the spec it's implicit.
|
|
113
112
|
elementImpl.sheet = sheet;
|
|
114
113
|
|
|
115
|
-
|
|
114
|
+
elementImpl._ownerDocument._clearStyleCache();
|
|
116
115
|
|
|
117
116
|
// TODO: title and disabled stuff
|
|
118
117
|
};
|
|
@@ -194,6 +194,7 @@ const descriptor = {
|
|
|
194
194
|
const isDefaultBox =
|
|
195
195
|
originValue === initialValues.get(backgroundOrigin.property) &&
|
|
196
196
|
clipValue === initialValues.get(backgroundClip.property);
|
|
197
|
+
let boxSet = false;
|
|
197
198
|
for (const [longhand] of shorthandFor) {
|
|
198
199
|
let value;
|
|
199
200
|
if (bgMap.has(longhand)) {
|
|
@@ -205,13 +206,16 @@ const descriptor = {
|
|
|
205
206
|
if (parsers.hasVarFunc(value)) {
|
|
206
207
|
return "";
|
|
207
208
|
}
|
|
208
|
-
if (longhand === backgroundOrigin.property) {
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
209
|
+
if (longhand === backgroundOrigin.property || longhand === backgroundClip.property) {
|
|
210
|
+
if (isDefaultBox || boxSet) {
|
|
211
|
+
continue;
|
|
212
|
+
} else {
|
|
213
|
+
if (originValue === clipValue) {
|
|
214
|
+
bg.push(originValue);
|
|
215
|
+
} else {
|
|
216
|
+
bg.push(originValue, clipValue);
|
|
217
|
+
}
|
|
218
|
+
boxSet = true;
|
|
215
219
|
}
|
|
216
220
|
} else if (longhand === backgroundColor.property) {
|
|
217
221
|
if (i === l - 1 && (value !== initialValues.get(longhand) || bgMap.has(longhand))) {
|
|
@@ -285,7 +289,6 @@ function parse(v) {
|
|
|
285
289
|
const bgPosition = [];
|
|
286
290
|
const bgSize = [];
|
|
287
291
|
const bgRepeat = [];
|
|
288
|
-
const bgBox = [];
|
|
289
292
|
const bgParts = parsers.splitValue(values[i], {
|
|
290
293
|
delimiter: "/"
|
|
291
294
|
});
|
|
@@ -294,17 +297,25 @@ function parse(v) {
|
|
|
294
297
|
}
|
|
295
298
|
const [bgPart1, bgPart2 = ""] = bgParts;
|
|
296
299
|
const parts1 = parsers.splitValue(bgPart1);
|
|
300
|
+
let originFilled = false;
|
|
297
301
|
for (const part of parts1) {
|
|
298
302
|
let partValid = false;
|
|
299
303
|
for (const [longhand, value] of shorthandFor) {
|
|
300
304
|
if (parsers.isValidPropertyValue(longhand, part)) {
|
|
301
305
|
partValid = true;
|
|
302
306
|
switch (longhand) {
|
|
303
|
-
case backgroundClip.property:
|
|
304
|
-
case backgroundOrigin.property: {
|
|
307
|
+
case backgroundClip.property: {
|
|
305
308
|
const parsedValue = value.parse(part);
|
|
306
309
|
if (parsedValue) {
|
|
307
|
-
|
|
310
|
+
bg[longhand] = parsedValue;
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case backgroundOrigin.property: {
|
|
315
|
+
const parsedValue = value.parse(part);
|
|
316
|
+
if (parsedValue && !originFilled) {
|
|
317
|
+
bg[longhand] = parsedValue;
|
|
318
|
+
originFilled = true;
|
|
308
319
|
}
|
|
309
320
|
break;
|
|
310
321
|
}
|
|
@@ -356,11 +367,18 @@ function parse(v) {
|
|
|
356
367
|
if (parsers.isValidPropertyValue(longhand, part)) {
|
|
357
368
|
partValid = true;
|
|
358
369
|
switch (longhand) {
|
|
359
|
-
case backgroundClip.property:
|
|
360
|
-
case backgroundOrigin.property: {
|
|
370
|
+
case backgroundClip.property: {
|
|
361
371
|
const parsedValue = value.parse(part);
|
|
362
372
|
if (parsedValue) {
|
|
363
|
-
|
|
373
|
+
bg[longhand] = parsedValue;
|
|
374
|
+
}
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
case backgroundOrigin.property: {
|
|
378
|
+
const parsedValue = value.parse(part);
|
|
379
|
+
if (parsedValue && !originFilled) {
|
|
380
|
+
bg[longhand] = parsedValue;
|
|
381
|
+
originFilled = true;
|
|
364
382
|
}
|
|
365
383
|
break;
|
|
366
384
|
}
|
|
@@ -426,25 +444,6 @@ function parse(v) {
|
|
|
426
444
|
bg[backgroundRepeat.property] = value;
|
|
427
445
|
}
|
|
428
446
|
}
|
|
429
|
-
if (bgBox.length) {
|
|
430
|
-
switch (bgBox.length) {
|
|
431
|
-
case 1: {
|
|
432
|
-
const [value] = bgBox;
|
|
433
|
-
bg[backgroundOrigin.property] = value;
|
|
434
|
-
bg[backgroundClip.property] = value;
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
case 2: {
|
|
438
|
-
const [value1, value2] = bgBox;
|
|
439
|
-
bg[backgroundOrigin.property] = value1;
|
|
440
|
-
bg[backgroundClip.property] = value2;
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
443
|
-
default: {
|
|
444
|
-
return undefined;
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
447
|
bgValues.push(bg);
|
|
449
448
|
}
|
|
450
449
|
return bgValues;
|
|
@@ -212,6 +212,10 @@ class DocumentImpl extends NodeImpl {
|
|
|
212
212
|
this._baseURLSerializedCache = null;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
_clearStyleCache() {
|
|
216
|
+
this._styleCache = new WeakMap();
|
|
217
|
+
}
|
|
218
|
+
|
|
215
219
|
// The `DOMSelector` instance is lazily created, as it is somewhat expensive to create and not always needed.
|
|
216
220
|
_getDOMSelector() {
|
|
217
221
|
if (!this.#domSelector) {
|
|
@@ -19,7 +19,6 @@ const {
|
|
|
19
19
|
isShadowRoot, shadowIncludingRoot, assignSlot, assignSlotableForTree, assignSlotable, signalSlotChange, isSlot,
|
|
20
20
|
shadowIncludingInclusiveDescendantsIterator, shadowIncludingDescendantsIterator
|
|
21
21
|
} = require("../helpers/shadow-dom");
|
|
22
|
-
const { invalidateStyleCache } = require("../css/helpers/computed-style");
|
|
23
22
|
|
|
24
23
|
function nodeEquals(a, b) {
|
|
25
24
|
if (a.nodeType !== b.nodeType) {
|
|
@@ -240,11 +239,15 @@ class NodeImpl extends EventTargetImpl {
|
|
|
240
239
|
this._childNodesList._update();
|
|
241
240
|
}
|
|
242
241
|
this._clearMemoizedQueries();
|
|
243
|
-
|
|
242
|
+
if (this._attached) {
|
|
243
|
+
this._ownerDocument._clearStyleCache();
|
|
244
|
+
}
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
_childTextContentChangeSteps() {
|
|
247
|
-
|
|
248
|
+
if (this._attached) {
|
|
249
|
+
this._ownerDocument._clearStyleCache();
|
|
250
|
+
}
|
|
248
251
|
}
|
|
249
252
|
|
|
250
253
|
_clearMemoizedQueries() {
|