sheetom 0.1.1 → 0.2.0
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/dist/index.cjs +352 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -9
- package/dist/index.d.ts +64 -9
- package/dist/index.js +345 -38
- package/dist/index.js.map +1 -1
- package/docs/api.md +19 -1
- package/engine-abi.json +3 -3
- package/package.json +16 -15
package/dist/index.cjs
CHANGED
|
@@ -28,9 +28,9 @@ let node_url = require("node:url");
|
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/internal/engine-binding.ts
|
|
30
30
|
const expectedEngineAbiIdentity = Object.freeze({
|
|
31
|
-
abiVersion:
|
|
32
|
-
sheetomVersion: "0.
|
|
33
|
-
syntaxEngineSetSha256: "
|
|
31
|
+
abiVersion: 5,
|
|
32
|
+
sheetomVersion: "0.2.0",
|
|
33
|
+
syntaxEngineSetSha256: "954d76058dc35ad2a5c85e41fd66e35d308856e554c93563e7eee8a4704d4b70"
|
|
34
34
|
});
|
|
35
35
|
var SheetOMEngineBindingError = class extends Error {
|
|
36
36
|
code;
|
|
@@ -380,8 +380,8 @@ function isNativeRuleDescription(value) {
|
|
|
380
380
|
}
|
|
381
381
|
//#endregion
|
|
382
382
|
//#region src/internal/native-rule-syntax.ts
|
|
383
|
-
function normalizeNativeSelector(source, resourceBudget = defaultResourceBudget) {
|
|
384
|
-
return callNative(() => engineBinding.normalizeSelector(source, ...nativeBudgetArguments(resourceBudget)));
|
|
383
|
+
function normalizeNativeSelector(source, resourceBudget = defaultResourceBudget, namespaces = "") {
|
|
384
|
+
return callNative(() => engineBinding.normalizeSelector(source, namespaces, ...nativeBudgetArguments(resourceBudget)));
|
|
385
385
|
}
|
|
386
386
|
function normalizeNativeMedia(source, resourceBudget = defaultResourceBudget) {
|
|
387
387
|
return callNative(() => engineBinding.normalizeMedia(source, ...nativeBudgetArguments(resourceBudget)));
|
|
@@ -420,6 +420,9 @@ function callNative(operation) {
|
|
|
420
420
|
return null;
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
|
+
function supportsNativeCss(source, value) {
|
|
424
|
+
return engineBinding.supportsCss(source, value);
|
|
425
|
+
}
|
|
423
426
|
//#endregion
|
|
424
427
|
//#region src/internal/rule-tree.ts
|
|
425
428
|
/** Owns child-list identity and parent propagation for every live rule node. */
|
|
@@ -599,6 +602,39 @@ function assertInternalConstructor(name) {
|
|
|
599
602
|
}
|
|
600
603
|
//#endregion
|
|
601
604
|
//#region src/index.ts
|
|
605
|
+
/** CSS authoring utilities, without installing or replacing the global CSS namespace. */
|
|
606
|
+
const CSS = {
|
|
607
|
+
/** Serialize a DOMString as a CSS identifier, including lone UTF-16 surrogates. */
|
|
608
|
+
escape(value) {
|
|
609
|
+
requireArguments(arguments.length, 1, "CSS", "escape");
|
|
610
|
+
const input = `${value}`;
|
|
611
|
+
let output = "";
|
|
612
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
613
|
+
const code = input.charCodeAt(index);
|
|
614
|
+
const character = input[index];
|
|
615
|
+
if (code === 0) output += "�";
|
|
616
|
+
else if (code <= 31 || code === 127 || code >= 48 && code <= 57 && (index === 0 || index === 1 && input[0] === "-")) output += `\\${code.toString(16)} `;
|
|
617
|
+
else if (input === "-") output += "\\-";
|
|
618
|
+
else if (code >= 128 || /[a-zA-Z0-9_-]/u.test(character)) output += character;
|
|
619
|
+
else output += `\\${character}`;
|
|
620
|
+
}
|
|
621
|
+
return output;
|
|
622
|
+
},
|
|
623
|
+
/** Test a declaration or supports condition against the pinned authoring capabilities. */
|
|
624
|
+
supports(propertyOrCondition, value) {
|
|
625
|
+
requireArguments(arguments.length, 1, "CSS", "supports");
|
|
626
|
+
try {
|
|
627
|
+
return arguments.length > 1 ? supportsNativeCss(`${propertyOrCondition}`, `${value}`) : supportsNativeCss(`${propertyOrCondition}`);
|
|
628
|
+
} catch (error) {
|
|
629
|
+
rethrowResourceBudgetError(error);
|
|
630
|
+
throw error;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
Object.defineProperty(CSS, Symbol.toStringTag, {
|
|
635
|
+
value: "CSS",
|
|
636
|
+
configurable: true
|
|
637
|
+
});
|
|
602
638
|
const arrayIndexPattern = /^(0|[1-9]\d*)$/;
|
|
603
639
|
const regularSheetMetadata = /* @__PURE__ */ new WeakMap();
|
|
604
640
|
const ruleParentage = /* @__PURE__ */ new WeakMap();
|
|
@@ -606,7 +642,19 @@ const ruleResourceBudgets = /* @__PURE__ */ new WeakMap();
|
|
|
606
642
|
const sheetResourceBudgets = /* @__PURE__ */ new WeakMap();
|
|
607
643
|
const sheetRuleArrays = /* @__PURE__ */ new WeakMap();
|
|
608
644
|
const sheetRuleCounts = /* @__PURE__ */ new WeakMap();
|
|
645
|
+
const sheetNamespaces = /* @__PURE__ */ new WeakMap();
|
|
646
|
+
function namespaceText(sheet) {
|
|
647
|
+
if (!sheet) return "";
|
|
648
|
+
return sheetNamespaces.get(sheet) ?? "";
|
|
649
|
+
}
|
|
650
|
+
function namespaceRulesText(rules) {
|
|
651
|
+
return rules.filter((rule) => rule instanceof CSSNamespaceRule).map((rule) => rule.cssText).join("");
|
|
652
|
+
}
|
|
653
|
+
function permitsNamespaceMutation(rules) {
|
|
654
|
+
return rules.every((rule) => rule instanceof CSSNamespaceRule || rule instanceof CSSImportRule);
|
|
655
|
+
}
|
|
609
656
|
const functionRuleHeaders = /* @__PURE__ */ new WeakMap();
|
|
657
|
+
const mixinRuleHeaders = /* @__PURE__ */ new WeakMap();
|
|
610
658
|
const unsignedLongRange = 2 ** 32;
|
|
611
659
|
const pageMarginRuleNames = /* @__PURE__ */ new Set([
|
|
612
660
|
"top-left-corner",
|
|
@@ -659,8 +707,8 @@ function namedPropertyToCSS(property) {
|
|
|
659
707
|
if (/^(webkit|moz|ms|o)-/.test(cssName)) cssName = `-${cssName}`;
|
|
660
708
|
return cssName;
|
|
661
709
|
}
|
|
662
|
-
function normalizeSelectorText(value, resourceBudget = defaultResourceBudget) {
|
|
663
|
-
return normalizeNativeSelector(value, resourceBudget);
|
|
710
|
+
function normalizeSelectorText(value, resourceBudget = defaultResourceBudget, namespaces = "") {
|
|
711
|
+
return normalizeNativeSelector(value, resourceBudget, namespaces);
|
|
664
712
|
}
|
|
665
713
|
function toUnsignedLong(value) {
|
|
666
714
|
const number = Number(value);
|
|
@@ -1052,6 +1100,112 @@ var CSSFunctionRule = class extends CSSGroupingRule {
|
|
|
1052
1100
|
}
|
|
1053
1101
|
set cssText(_value) {}
|
|
1054
1102
|
};
|
|
1103
|
+
/** Experimental revision-pinned native CSS mixin definition. */
|
|
1104
|
+
var CSSMixinRule = class extends CSSGroupingRule {
|
|
1105
|
+
name;
|
|
1106
|
+
contents = true;
|
|
1107
|
+
#parameters;
|
|
1108
|
+
constructor(name, parameters) {
|
|
1109
|
+
super(0);
|
|
1110
|
+
this.name = serializeNativeIdentifier(name);
|
|
1111
|
+
this.#parameters = parameters.map((parameter) => ({ ...parameter }));
|
|
1112
|
+
const header = serializeFunctionHeader(name, parameters, "*").replace(/^@function /u, "@mixin ");
|
|
1113
|
+
mixinRuleHeaders.set(this, parameters.length === 0 ? header.slice(0, -2) : header);
|
|
1114
|
+
lockOwnProperties(this, "name", "contents");
|
|
1115
|
+
}
|
|
1116
|
+
getParameters() {
|
|
1117
|
+
return this.#parameters.map((parameter) => ({ ...parameter }));
|
|
1118
|
+
}
|
|
1119
|
+
get cssText() {
|
|
1120
|
+
return serializeMixinCssText(this);
|
|
1121
|
+
}
|
|
1122
|
+
set cssText(_value) {}
|
|
1123
|
+
};
|
|
1124
|
+
/** Experimental native CSS mixin application with a contents block. */
|
|
1125
|
+
var CSSApplyBlockRule = class extends CSSGroupingRule {
|
|
1126
|
+
name;
|
|
1127
|
+
#arguments;
|
|
1128
|
+
constructor(name, args, header) {
|
|
1129
|
+
super(0);
|
|
1130
|
+
this.name = serializeNativeIdentifier(name);
|
|
1131
|
+
this.#arguments = [...args];
|
|
1132
|
+
mixinRuleHeaders.set(this, header);
|
|
1133
|
+
lockOwnProperties(this, "name");
|
|
1134
|
+
}
|
|
1135
|
+
getArguments() {
|
|
1136
|
+
return [...this.#arguments];
|
|
1137
|
+
}
|
|
1138
|
+
get cssText() {
|
|
1139
|
+
return serializeMixinCssText(this);
|
|
1140
|
+
}
|
|
1141
|
+
set cssText(_value) {}
|
|
1142
|
+
};
|
|
1143
|
+
/** Experimental native CSS mixin application without a contents block. */
|
|
1144
|
+
var CSSApplyStatementRule = class extends CSSRule {
|
|
1145
|
+
name;
|
|
1146
|
+
#arguments;
|
|
1147
|
+
#header;
|
|
1148
|
+
constructor(name, args, header) {
|
|
1149
|
+
super(0);
|
|
1150
|
+
this.name = serializeNativeIdentifier(name);
|
|
1151
|
+
this.#arguments = [...args];
|
|
1152
|
+
this.#header = header;
|
|
1153
|
+
lockOwnProperties(this, "name");
|
|
1154
|
+
}
|
|
1155
|
+
getArguments() {
|
|
1156
|
+
return [...this.#arguments];
|
|
1157
|
+
}
|
|
1158
|
+
get cssText() {
|
|
1159
|
+
return `${this.#header};`;
|
|
1160
|
+
}
|
|
1161
|
+
set cssText(_value) {}
|
|
1162
|
+
};
|
|
1163
|
+
/** Experimental native CSS mixin contents placeholder with a fallback block. */
|
|
1164
|
+
var CSSContentsBlockRule = class extends CSSGroupingRule {
|
|
1165
|
+
constructor() {
|
|
1166
|
+
super(0);
|
|
1167
|
+
mixinRuleHeaders.set(this, "@contents");
|
|
1168
|
+
}
|
|
1169
|
+
get cssText() {
|
|
1170
|
+
return serializeMixinCssText(this);
|
|
1171
|
+
}
|
|
1172
|
+
set cssText(_value) {}
|
|
1173
|
+
};
|
|
1174
|
+
/** Experimental native CSS mixin contents placeholder without a fallback. */
|
|
1175
|
+
var CSSContentsStatementRule = class extends CSSRule {
|
|
1176
|
+
constructor() {
|
|
1177
|
+
super(0);
|
|
1178
|
+
}
|
|
1179
|
+
get cssText() {
|
|
1180
|
+
return "@contents;";
|
|
1181
|
+
}
|
|
1182
|
+
set cssText(_value) {}
|
|
1183
|
+
};
|
|
1184
|
+
function serializeMixinCssText(root) {
|
|
1185
|
+
const chunks = [];
|
|
1186
|
+
const pending = [root];
|
|
1187
|
+
while (pending.length > 0) {
|
|
1188
|
+
const item = pending.pop();
|
|
1189
|
+
if (typeof item === "string") {
|
|
1190
|
+
chunks.push(item);
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
if (!(item instanceof CSSGroupingRule)) {
|
|
1194
|
+
chunks.push(item.cssText);
|
|
1195
|
+
continue;
|
|
1196
|
+
}
|
|
1197
|
+
const header = groupingRuleHeader(item);
|
|
1198
|
+
chunks.push(header, item instanceof CSSMixinRule ? "{ " : " { ");
|
|
1199
|
+
pending.push(" }");
|
|
1200
|
+
const children = ruleTree.children(item);
|
|
1201
|
+
for (let index = children.length - 1; index >= 0; index -= 1) {
|
|
1202
|
+
pending.push(children[index]);
|
|
1203
|
+
if (index > 0) pending.push(" ");
|
|
1204
|
+
}
|
|
1205
|
+
if (item instanceof CSSStyleRule && item.style.cssText !== "") pending.push(children.length ? `${item.style.cssText} ` : item.style.cssText);
|
|
1206
|
+
}
|
|
1207
|
+
return chunks.join("");
|
|
1208
|
+
}
|
|
1055
1209
|
function serializeFunctionHeader(name, parameters, returnType) {
|
|
1056
1210
|
const serializedParameters = parameters.map((parameter) => {
|
|
1057
1211
|
const type = serializeFunctionType(parameter.type);
|
|
@@ -1314,7 +1468,7 @@ var CSSStyleDeclaration = class {
|
|
|
1314
1468
|
};
|
|
1315
1469
|
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
|
|
1316
1470
|
};
|
|
1317
|
-
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, reportSerializationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule), initialCssText);
|
|
1471
|
+
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, reportSerializationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSPositionTryRule ? "position-try" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule), initialCssText);
|
|
1318
1472
|
return new Proxy(this, {
|
|
1319
1473
|
get(target, property) {
|
|
1320
1474
|
if (typeof property === "string" && arrayIndexPattern.test(property)) return target.item(Number(property)) || void 0;
|
|
@@ -1491,15 +1645,76 @@ var CSSPageRule = class extends CSSGroupingRule {
|
|
|
1491
1645
|
}
|
|
1492
1646
|
set cssText(_value) {}
|
|
1493
1647
|
};
|
|
1494
|
-
/**
|
|
1648
|
+
/** The allowed descriptors of an anchor positioning fallback rule. */
|
|
1649
|
+
var CSSPositionTryDescriptors = class extends CSSStyleDeclaration {};
|
|
1650
|
+
for (const name of [
|
|
1651
|
+
"margin",
|
|
1652
|
+
"margin-top",
|
|
1653
|
+
"margin-right",
|
|
1654
|
+
"margin-bottom",
|
|
1655
|
+
"margin-left",
|
|
1656
|
+
"margin-block",
|
|
1657
|
+
"margin-block-start",
|
|
1658
|
+
"margin-block-end",
|
|
1659
|
+
"margin-inline",
|
|
1660
|
+
"margin-inline-start",
|
|
1661
|
+
"margin-inline-end",
|
|
1662
|
+
"inset",
|
|
1663
|
+
"top",
|
|
1664
|
+
"right",
|
|
1665
|
+
"bottom",
|
|
1666
|
+
"left",
|
|
1667
|
+
"inset-block",
|
|
1668
|
+
"inset-block-start",
|
|
1669
|
+
"inset-block-end",
|
|
1670
|
+
"inset-inline",
|
|
1671
|
+
"inset-inline-start",
|
|
1672
|
+
"inset-inline-end",
|
|
1673
|
+
"width",
|
|
1674
|
+
"min-width",
|
|
1675
|
+
"max-width",
|
|
1676
|
+
"height",
|
|
1677
|
+
"min-height",
|
|
1678
|
+
"max-height",
|
|
1679
|
+
"block-size",
|
|
1680
|
+
"min-block-size",
|
|
1681
|
+
"max-block-size",
|
|
1682
|
+
"inline-size",
|
|
1683
|
+
"min-inline-size",
|
|
1684
|
+
"max-inline-size",
|
|
1685
|
+
"place-self",
|
|
1686
|
+
"align-self",
|
|
1687
|
+
"justify-self",
|
|
1688
|
+
"position-anchor",
|
|
1689
|
+
"position-area"
|
|
1690
|
+
]) {
|
|
1691
|
+
const camelCase = name.replace(/-([a-z])/gu, (_match, letter) => letter.toUpperCase());
|
|
1692
|
+
for (const accessor of /* @__PURE__ */ new Set([name, camelCase])) Object.defineProperty(CSSPositionTryDescriptors.prototype, accessor, {
|
|
1693
|
+
configurable: true,
|
|
1694
|
+
enumerable: true,
|
|
1695
|
+
get() {
|
|
1696
|
+
return this.getPropertyValue(name);
|
|
1697
|
+
},
|
|
1698
|
+
set(value) {
|
|
1699
|
+
this.setProperty(name, value);
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
/** A named anchor positioning fallback rule. */
|
|
1495
1704
|
var CSSPositionTryRule = class extends CSSRule {
|
|
1496
1705
|
name;
|
|
1497
|
-
style;
|
|
1706
|
+
#style;
|
|
1498
1707
|
constructor(name, initialCssText) {
|
|
1499
1708
|
super(0);
|
|
1500
1709
|
this.name = name;
|
|
1501
|
-
this
|
|
1502
|
-
lockOwnProperties(this, "name"
|
|
1710
|
+
this.#style = constructWebIDL(CSSPositionTryDescriptors, [this, initialCssText]);
|
|
1711
|
+
lockOwnProperties(this, "name");
|
|
1712
|
+
}
|
|
1713
|
+
get style() {
|
|
1714
|
+
return this.#style;
|
|
1715
|
+
}
|
|
1716
|
+
set style(cssText) {
|
|
1717
|
+
this.#style.cssText = `${cssText}`;
|
|
1503
1718
|
}
|
|
1504
1719
|
get cssText() {
|
|
1505
1720
|
return `@position-try ${this.name} {${this.style.cssText === "" ? "" : ` ${this.style.cssText}`} }`;
|
|
@@ -1846,6 +2061,9 @@ var CSSFontFeatureValuesRule = class extends CSSRule {
|
|
|
1846
2061
|
var CSSStyleRule = class extends CSSGroupingRule {
|
|
1847
2062
|
style;
|
|
1848
2063
|
#selectorText;
|
|
2064
|
+
#namespaces() {
|
|
2065
|
+
return namespaceText(this.parentStyleSheet);
|
|
2066
|
+
}
|
|
1849
2067
|
constructor(selectorText, normalized, initialCssText) {
|
|
1850
2068
|
super(CSSRule.STYLE_RULE);
|
|
1851
2069
|
this.#selectorText = normalized === normalizedSelectorText ? selectorText : normalizeSelectorText(`${selectorText}`, currentConstructionResourceBudget()) ?? `${selectorText}`;
|
|
@@ -1856,7 +2074,7 @@ var CSSStyleRule = class extends CSSGroupingRule {
|
|
|
1856
2074
|
return this.#selectorText;
|
|
1857
2075
|
}
|
|
1858
2076
|
set selectorText(value) {
|
|
1859
|
-
const normalized = normalizeSelectorText(`${value}`, ruleResourceBudgets.get(this) ?? defaultResourceBudget);
|
|
2077
|
+
const normalized = normalizeSelectorText(`${value}`, ruleResourceBudgets.get(this) ?? defaultResourceBudget, this.#namespaces());
|
|
1860
2078
|
if (normalized === null) return;
|
|
1861
2079
|
this.#selectorText = normalized;
|
|
1862
2080
|
}
|
|
@@ -1912,17 +2130,24 @@ function describeRuleSafe(rule, strict) {
|
|
|
1912
2130
|
declarations: rule.style.serializeSafe(" ", strict),
|
|
1913
2131
|
children: ruleTree.children(rule)
|
|
1914
2132
|
};
|
|
2133
|
+
if (rule instanceof CSSApplyStatementRule && rule.getArguments().length === 1 && rule.getArguments()[0] === "") return {
|
|
2134
|
+
kind: "raw",
|
|
2135
|
+
cssText: `@apply ${rule.name}({ });`
|
|
2136
|
+
};
|
|
1915
2137
|
if (!(rule instanceof CSSGroupingRule)) return {
|
|
1916
2138
|
kind: "raw",
|
|
1917
2139
|
cssText: rule.cssText
|
|
1918
2140
|
};
|
|
1919
2141
|
return {
|
|
1920
2142
|
kind: "block",
|
|
1921
|
-
header: groupingRuleHeader(rule),
|
|
2143
|
+
header: rule instanceof CSSApplyBlockRule && rule.getArguments().length === 1 && rule.getArguments()[0] === "" ? `@apply ${rule.name}({ })` : groupingRuleHeader(rule),
|
|
1922
2144
|
children: ruleTree.children(rule)
|
|
1923
2145
|
};
|
|
1924
2146
|
}
|
|
1925
2147
|
function groupingRuleHeader(rule) {
|
|
2148
|
+
const mixinHeader = mixinRuleHeaders.get(rule);
|
|
2149
|
+
if (mixinHeader !== void 0) return mixinHeader;
|
|
2150
|
+
if (rule instanceof CSSStyleRule) return rule.selectorText;
|
|
1926
2151
|
if (rule instanceof CSSFunctionRule) return functionRuleHeaders.get(rule) ?? "@function";
|
|
1927
2152
|
if (rule instanceof CSSMediaRule) return `@media ${rule.media.mediaText}`;
|
|
1928
2153
|
if (rule instanceof CSSSupportsRule) return `@supports ${rule.conditionText}`;
|
|
@@ -1974,12 +2199,13 @@ function parseImportPrelude(prelude) {
|
|
|
1974
2199
|
supports
|
|
1975
2200
|
};
|
|
1976
2201
|
}
|
|
1977
|
-
function createRuleFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
|
|
1978
|
-
return constructWithResourceBudget(() => createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget), resourceBudget);
|
|
2202
|
+
function createRuleFromNative(description, reportDiagnostic, preserveImports, resourceBudget, parentRule = null) {
|
|
2203
|
+
return constructWithResourceBudget(() => createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget, parentRule), resourceBudget);
|
|
1979
2204
|
}
|
|
1980
|
-
function createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
|
|
2205
|
+
function createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget, parentRule) {
|
|
1981
2206
|
const root = createRuleShellFromNative(description, reportDiagnostic, preserveImports, resourceBudget);
|
|
1982
2207
|
if (!root) return null;
|
|
2208
|
+
attachRuleTree(root, parentRule, parentRule?.parentStyleSheet ?? null);
|
|
1983
2209
|
const pending = [{
|
|
1984
2210
|
description,
|
|
1985
2211
|
rule: root
|
|
@@ -1991,9 +2217,10 @@ function createRuleTreeFromNative(description, reportDiagnostic, preserveImports
|
|
|
1991
2217
|
const childFrames = [];
|
|
1992
2218
|
for (const childDescription of current.description.children) {
|
|
1993
2219
|
if (isNativeMetadataRule(childDescription)) continue;
|
|
2220
|
+
if (!isMixinContextAllowed(childDescription.kind, current.rule)) continue;
|
|
1994
2221
|
const child = createRuleShellFromNative(childDescription, reportDiagnostic, preserveImports, resourceBudget);
|
|
1995
2222
|
if (!child) continue;
|
|
1996
|
-
if (child instanceof CSSFunctionDeclarations && child.style.length === 0) continue;
|
|
2223
|
+
if ((child instanceof CSSFunctionDeclarations || child instanceof CSSNestedDeclarations) && child.style.length === 0) continue;
|
|
1997
2224
|
if (current.rule instanceof CSSKeyframesRule && !(child instanceof CSSKeyframeRule)) continue;
|
|
1998
2225
|
children.push(child);
|
|
1999
2226
|
childFrames.push({
|
|
@@ -2011,7 +2238,7 @@ function createRuleTreeFromNative(description, reportDiagnostic, preserveImports
|
|
|
2011
2238
|
return root;
|
|
2012
2239
|
}
|
|
2013
2240
|
function isNativeMetadataRule(description) {
|
|
2014
|
-
return description.kind === "function-parameter" || description.kind === "property-descriptor" || description.kind === "view-transition-type" || description.kind === "layer-name";
|
|
2241
|
+
return description.kind === "function-parameter" || description.kind === "mixin-argument" || description.kind === "property-descriptor" || description.kind === "view-transition-type" || description.kind === "layer-name";
|
|
2015
2242
|
}
|
|
2016
2243
|
function createRuleShellFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
|
|
2017
2244
|
let rule;
|
|
@@ -2099,7 +2326,8 @@ function createRuleShellFromNative(description, reportDiagnostic, preserveImport
|
|
|
2099
2326
|
description.children.filter((candidate) => candidate.kind === "view-transition-type").map((candidate) => candidate.prelude),
|
|
2100
2327
|
description.cssText
|
|
2101
2328
|
]);
|
|
2102
|
-
case "function":
|
|
2329
|
+
case "function":
|
|
2330
|
+
case "mixin": {
|
|
2103
2331
|
const parameters = description.children.filter((candidate) => candidate.kind === "function-parameter").map((candidate) => {
|
|
2104
2332
|
const defaultValue = candidate.children.find((child) => child.kind === "property-descriptor" && child.prelude === "default-value");
|
|
2105
2333
|
return defaultValue ? {
|
|
@@ -2111,13 +2339,35 @@ function createRuleShellFromNative(description, reportDiagnostic, preserveImport
|
|
|
2111
2339
|
type: candidate.declarations
|
|
2112
2340
|
};
|
|
2113
2341
|
});
|
|
2114
|
-
rule = constructWebIDL(CSSFunctionRule, [
|
|
2342
|
+
rule = description.kind === "mixin" ? constructWebIDL(CSSMixinRule, [description.prelude, parameters]) : constructWebIDL(CSSFunctionRule, [
|
|
2115
2343
|
description.prelude,
|
|
2116
2344
|
parameters,
|
|
2117
2345
|
description.declarations
|
|
2118
2346
|
]);
|
|
2119
2347
|
break;
|
|
2120
2348
|
}
|
|
2349
|
+
case "apply-block":
|
|
2350
|
+
case "apply-statement": {
|
|
2351
|
+
const arguments_ = description.children.filter((child) => child.kind === "mixin-argument");
|
|
2352
|
+
const args = arguments_.map((argument) => argument.declarations);
|
|
2353
|
+
const header = `@apply ${serializeNativeIdentifier(description.prelude)}${args.length ? `(${arguments_.map((argument) => argument.cssText).join(", ")})` : ""}`;
|
|
2354
|
+
rule = description.kind === "apply-block" ? constructWebIDL(CSSApplyBlockRule, [
|
|
2355
|
+
description.prelude,
|
|
2356
|
+
args,
|
|
2357
|
+
header
|
|
2358
|
+
]) : constructWebIDL(CSSApplyStatementRule, [
|
|
2359
|
+
description.prelude,
|
|
2360
|
+
args,
|
|
2361
|
+
header
|
|
2362
|
+
]);
|
|
2363
|
+
break;
|
|
2364
|
+
}
|
|
2365
|
+
case "contents-block":
|
|
2366
|
+
rule = constructWebIDL(CSSContentsBlockRule);
|
|
2367
|
+
break;
|
|
2368
|
+
case "contents-statement":
|
|
2369
|
+
rule = constructWebIDL(CSSContentsStatementRule);
|
|
2370
|
+
break;
|
|
2121
2371
|
case "namespace": return constructWebIDL(CSSNamespaceRule, [
|
|
2122
2372
|
nativeRuleDescriptor(description, "namespace-uri"),
|
|
2123
2373
|
nativeRuleDescriptor(description, "prefix"),
|
|
@@ -2155,7 +2405,7 @@ function nativeRuleDescriptor(description, name) {
|
|
|
2155
2405
|
function hydrateCounterStyleDescriptors(rule, declarations, resourceBudget) {
|
|
2156
2406
|
for (const descriptor of parseNativeCounterStyleDescriptors(declarations, resourceBudget)) rule.setParsedDescriptor(descriptor.name, descriptor.value);
|
|
2157
2407
|
}
|
|
2158
|
-
function parseStrictRule(ruleText, reportDiagnostic, preserveImports = false, parentRule = null, resourceBudget = defaultResourceBudget) {
|
|
2408
|
+
function parseStrictRule(ruleText, reportDiagnostic, preserveImports = false, parentRule = null, resourceBudget = defaultResourceBudget, namespaces = namespaceText(parentRule?.parentStyleSheet ?? null)) {
|
|
2159
2409
|
if (parentRule instanceof CSSPageRule) {
|
|
2160
2410
|
const page = parseNativeRule(`@page { ${ruleText} }`, resourceBudget);
|
|
2161
2411
|
if (page?.kind !== "page" || page.children.length !== 1) return null;
|
|
@@ -2165,7 +2415,41 @@ function parseStrictRule(ruleText, reportDiagnostic, preserveImports = false, pa
|
|
|
2165
2415
|
}
|
|
2166
2416
|
const description = parseNativeRule(ruleText, resourceBudget) ?? (parentRule && hasFunctionAncestor(parentRule) ? parseNativeRuleWithErrorRecovery(ruleText, resourceBudget) : null);
|
|
2167
2417
|
if (!description || description.kind === "import" && !preserveImports) return null;
|
|
2168
|
-
|
|
2418
|
+
if (!isMixinContextAllowed(description.kind, parentRule)) return null;
|
|
2419
|
+
const validSelector = (rule) => {
|
|
2420
|
+
if (rule.kind !== "style" || !rule.prelude.includes("|")) return true;
|
|
2421
|
+
const normalized = normalizeNativeSelector(rule.prelude, resourceBudget, namespaces);
|
|
2422
|
+
if (normalized === null) return false;
|
|
2423
|
+
rule.prelude = normalized;
|
|
2424
|
+
return true;
|
|
2425
|
+
};
|
|
2426
|
+
if (!validSelector(description)) return null;
|
|
2427
|
+
const pending = [description];
|
|
2428
|
+
while (pending.length) {
|
|
2429
|
+
const current = pending.pop();
|
|
2430
|
+
current.children = current.children.filter(validSelector);
|
|
2431
|
+
for (const child of current.children) pending.push(child);
|
|
2432
|
+
}
|
|
2433
|
+
return createRuleFromNative(description, reportDiagnostic, preserveImports, resourceBudget, parentRule);
|
|
2434
|
+
}
|
|
2435
|
+
function isMixinContextAllowed(kind, parent) {
|
|
2436
|
+
if (![
|
|
2437
|
+
"mixin",
|
|
2438
|
+
"apply-block",
|
|
2439
|
+
"apply-statement",
|
|
2440
|
+
"contents-block",
|
|
2441
|
+
"contents-statement",
|
|
2442
|
+
"private"
|
|
2443
|
+
].includes(kind)) return true;
|
|
2444
|
+
let nested = false;
|
|
2445
|
+
let mixin = false;
|
|
2446
|
+
for (let current = parent; current; current = current.parentRule) {
|
|
2447
|
+
if (current instanceof CSSFunctionRule) return false;
|
|
2448
|
+
if (current instanceof CSSStyleRule || current instanceof CSSMixinRule) nested = true;
|
|
2449
|
+
if (current instanceof CSSMixinRule) mixin = true;
|
|
2450
|
+
}
|
|
2451
|
+
if (kind === "mixin") return !nested;
|
|
2452
|
+
return kind.startsWith("contents-") ? mixin : nested;
|
|
2169
2453
|
}
|
|
2170
2454
|
function hasFunctionAncestor(rule) {
|
|
2171
2455
|
let current = rule;
|
|
@@ -2189,11 +2473,17 @@ function genericRuleType(name) {
|
|
|
2189
2473
|
}
|
|
2190
2474
|
}
|
|
2191
2475
|
function parseStyleSheetRules(cssText, reportDiagnostic, preserveImports, resourceBudget) {
|
|
2476
|
+
let namespaces = "";
|
|
2477
|
+
let namespaceRulesAllowed = true;
|
|
2192
2478
|
const rules = [];
|
|
2193
2479
|
let parsedRuleCount = 0;
|
|
2194
2480
|
for (const rawRule of scanTopLevelRules(cssText, resourceBudget)) {
|
|
2195
|
-
const rule = parseStrictRule(rawRule, reportDiagnostic, preserveImports, null, resourceBudget);
|
|
2481
|
+
const rule = parseStrictRule(rawRule, reportDiagnostic, preserveImports, null, resourceBudget, namespaces);
|
|
2196
2482
|
if (rule) {
|
|
2483
|
+
if (rule instanceof CSSNamespaceRule) {
|
|
2484
|
+
if (!namespaceRulesAllowed) continue;
|
|
2485
|
+
namespaces += rule.cssText;
|
|
2486
|
+
} else if (!(rule instanceof CSSImportRule)) namespaceRulesAllowed = false;
|
|
2197
2487
|
parsedRuleCount += ruleForestSize([rule]);
|
|
2198
2488
|
assertRuleCountBudget(parsedRuleCount, resourceBudget);
|
|
2199
2489
|
rules.push(rule);
|
|
@@ -2205,38 +2495,50 @@ function parseStyleSheetRules(cssText, reportDiagnostic, preserveImports, resour
|
|
|
2205
2495
|
assertRuleCountBudget(parsedRuleCount, resourceBudget);
|
|
2206
2496
|
rules.push(opaque);
|
|
2207
2497
|
}
|
|
2208
|
-
return
|
|
2498
|
+
return {
|
|
2499
|
+
rules,
|
|
2500
|
+
namespaces
|
|
2501
|
+
};
|
|
2209
2502
|
}
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2503
|
+
const stylesheetConstructionKey = Symbol("StyleSheet construction");
|
|
2504
|
+
/** Shared stylesheet metadata. Instances are created through CSSStyleSheet. */
|
|
2505
|
+
var StyleSheet = class {
|
|
2213
2506
|
media;
|
|
2214
2507
|
ownerNode = null;
|
|
2215
2508
|
parentStyleSheet = null;
|
|
2216
|
-
ownerRule = null;
|
|
2217
2509
|
title = null;
|
|
2218
2510
|
type = "text/css";
|
|
2219
2511
|
disabled;
|
|
2512
|
+
constructor(options = {}, resourceBudget = defaultResourceBudget, key) {
|
|
2513
|
+
if (key !== stylesheetConstructionKey) throw new TypeError("Illegal constructor");
|
|
2514
|
+
const media = options.media === void 0 ? "" : `${options.media}`;
|
|
2515
|
+
this.media = constructWithResourceBudget(() => constructWebIDL(MediaList, [media]), resourceBudget);
|
|
2516
|
+
this.disabled = Boolean(options.disabled);
|
|
2517
|
+
}
|
|
2518
|
+
get href() {
|
|
2519
|
+
return regularSheetMetadata.get(this)?.href ?? null;
|
|
2520
|
+
}
|
|
2521
|
+
};
|
|
2522
|
+
/** A mutable, browser-shaped authoring stylesheet. */
|
|
2523
|
+
var CSSStyleSheet = class extends StyleSheet {
|
|
2524
|
+
cssRules;
|
|
2525
|
+
ownerRule = null;
|
|
2220
2526
|
#rules = [];
|
|
2221
2527
|
#diagnostics;
|
|
2222
2528
|
#constructedBaseURL;
|
|
2223
2529
|
constructor(options = {}) {
|
|
2224
2530
|
const normalizedOptions = options ?? {};
|
|
2225
2531
|
const resourceBudget = normalizeResourceBudget(normalizedOptions.resourceBudget);
|
|
2532
|
+
super(normalizedOptions, resourceBudget, stylesheetConstructionKey);
|
|
2226
2533
|
sheetResourceBudgets.set(this, resourceBudget);
|
|
2227
2534
|
sheetRuleArrays.set(this, this.#rules);
|
|
2228
2535
|
sheetRuleCounts.set(this, 0);
|
|
2536
|
+
sheetNamespaces.set(this, "");
|
|
2229
2537
|
this.#diagnostics = Boolean(normalizedOptions.diagnostics) ? [] : null;
|
|
2230
2538
|
this.#constructedBaseURL = normalizedOptions.baseURL === void 0 ? "about:blank" : `${normalizedOptions.baseURL}`;
|
|
2231
|
-
const media = normalizedOptions.media === void 0 ? "" : `${normalizedOptions.media}`;
|
|
2232
|
-
this.media = constructWithResourceBudget(() => constructWebIDL(MediaList, [media]), resourceBudget);
|
|
2233
|
-
this.disabled = Boolean(normalizedOptions.disabled);
|
|
2234
2539
|
this.cssRules = constructInternally(() => constructWebIDL(CSSRuleList, [this.#rules]));
|
|
2235
2540
|
lockOwnProperties(this, "cssRules", "media", "ownerNode", "parentStyleSheet", "ownerRule", "title", "type");
|
|
2236
2541
|
}
|
|
2237
|
-
get href() {
|
|
2238
|
-
return regularSheetMetadata.get(this)?.href ?? null;
|
|
2239
|
-
}
|
|
2240
2542
|
get baseURL() {
|
|
2241
2543
|
return regularSheetMetadata.get(this)?.baseURL ?? this.#constructedBaseURL;
|
|
2242
2544
|
}
|
|
@@ -2249,14 +2551,16 @@ var CSSStyleSheet = class {
|
|
|
2249
2551
|
if (normalizedIndex > this.#rules.length) throw new DOMException("The index is outside the allowed range.", "IndexSizeError");
|
|
2250
2552
|
const regular = regularSheetMetadata.has(this);
|
|
2251
2553
|
const resourceBudget = sheetResourceBudgets.get(this) ?? defaultResourceBudget;
|
|
2252
|
-
const rule = parseStrictRule(`${ruleText}`, this.#reportDiagnostic, regular, null, resourceBudget);
|
|
2554
|
+
const rule = parseStrictRule(`${ruleText}`, this.#reportDiagnostic, regular, null, resourceBudget, namespaceText(this));
|
|
2253
2555
|
if (!rule) throw new DOMException("The rule could not be parsed.", "SyntaxError");
|
|
2556
|
+
if (rule instanceof CSSNamespaceRule && !permitsNamespaceMutation(this.#rules)) throw new DOMException("Namespace rules cannot change after other rules exist.", "InvalidStateError");
|
|
2254
2557
|
const precedingRules = this.#rules.slice(0, normalizedIndex);
|
|
2255
2558
|
const followingRules = this.#rules.slice(normalizedIndex);
|
|
2256
2559
|
if (rule instanceof CSSImportRule ? precedingRules.some((candidate) => !(candidate instanceof CSSImportRule)) : followingRules.some((candidate) => candidate instanceof CSSImportRule)) throw new DOMException("The rule violates stylesheet ordering.", "HierarchyRequestError");
|
|
2257
2560
|
const insertedCount = assertRuleInsertionBudget(this, rule, resourceBudget);
|
|
2258
2561
|
attachRuleTree(rule, null, this);
|
|
2259
2562
|
this.#rules.splice(normalizedIndex, 0, rule);
|
|
2563
|
+
if (rule instanceof CSSNamespaceRule) sheetNamespaces.set(this, namespaceRulesText(this.#rules));
|
|
2260
2564
|
adjustSheetRuleCount(this, insertedCount);
|
|
2261
2565
|
return normalizedIndex;
|
|
2262
2566
|
}
|
|
@@ -2264,15 +2568,18 @@ var CSSStyleSheet = class {
|
|
|
2264
2568
|
requireArguments(arguments.length, 1, "CSSStyleSheet", "deleteRule");
|
|
2265
2569
|
const normalizedIndex = toUnsignedLong(index);
|
|
2266
2570
|
if (normalizedIndex >= this.#rules.length) throw new DOMException("The index is outside the allowed range.", "IndexSizeError");
|
|
2571
|
+
if (this.#rules[normalizedIndex] instanceof CSSNamespaceRule && !permitsNamespaceMutation(this.#rules)) throw new DOMException("Namespace rules cannot change while other rules exist.", "InvalidStateError");
|
|
2267
2572
|
const [removed] = this.#rules.splice(normalizedIndex, 1);
|
|
2268
2573
|
if (!removed) return;
|
|
2574
|
+
if (removed instanceof CSSNamespaceRule) sheetNamespaces.set(this, namespaceRulesText(this.#rules));
|
|
2269
2575
|
adjustSheetRuleCount(this, -ruleForestSize([removed]));
|
|
2270
2576
|
attachRuleTree(removed, null, null);
|
|
2271
2577
|
}
|
|
2272
2578
|
replaceSync(cssText) {
|
|
2273
2579
|
requireArguments(arguments.length, 1, "CSSStyleSheet", "replaceSync");
|
|
2274
|
-
const replacement = parseStyleSheetRules(`${cssText}`, this.#reportDiagnostic, regularSheetMetadata.has(this), sheetResourceBudgets.get(this) ?? defaultResourceBudget);
|
|
2580
|
+
const { rules: replacement, namespaces } = parseStyleSheetRules(`${cssText}`, this.#reportDiagnostic, regularSheetMetadata.has(this), sheetResourceBudgets.get(this) ?? defaultResourceBudget);
|
|
2275
2581
|
for (const rule of this.#rules) attachRuleTree(rule, null, null);
|
|
2582
|
+
sheetNamespaces.set(this, namespaces);
|
|
2276
2583
|
for (const rule of replacement) attachRuleTree(rule, null, this);
|
|
2277
2584
|
this.#rules.splice(0, this.#rules.length, ...replacement);
|
|
2278
2585
|
sheetRuleCounts.set(this, ruleForestSize(replacement));
|
|
@@ -2308,8 +2615,13 @@ function parseStyleSheet(cssText, options = {}) {
|
|
|
2308
2615
|
return sheet;
|
|
2309
2616
|
}
|
|
2310
2617
|
//#endregion
|
|
2618
|
+
exports.CSS = CSS;
|
|
2619
|
+
exports.CSSApplyBlockRule = CSSApplyBlockRule;
|
|
2620
|
+
exports.CSSApplyStatementRule = CSSApplyStatementRule;
|
|
2311
2621
|
exports.CSSConditionRule = CSSConditionRule;
|
|
2312
2622
|
exports.CSSContainerRule = CSSContainerRule;
|
|
2623
|
+
exports.CSSContentsBlockRule = CSSContentsBlockRule;
|
|
2624
|
+
exports.CSSContentsStatementRule = CSSContentsStatementRule;
|
|
2313
2625
|
exports.CSSCounterStyleRule = CSSCounterStyleRule;
|
|
2314
2626
|
exports.CSSFontFaceRule = CSSFontFaceRule;
|
|
2315
2627
|
exports.CSSFontFeatureValuesMap = CSSFontFeatureValuesMap;
|
|
@@ -2326,9 +2638,11 @@ exports.CSSLayerBlockRule = CSSLayerBlockRule;
|
|
|
2326
2638
|
exports.CSSLayerStatementRule = CSSLayerStatementRule;
|
|
2327
2639
|
exports.CSSMarginRule = CSSMarginRule;
|
|
2328
2640
|
exports.CSSMediaRule = CSSMediaRule;
|
|
2641
|
+
exports.CSSMixinRule = CSSMixinRule;
|
|
2329
2642
|
exports.CSSNamespaceRule = CSSNamespaceRule;
|
|
2330
2643
|
exports.CSSNestedDeclarations = CSSNestedDeclarations;
|
|
2331
2644
|
exports.CSSPageRule = CSSPageRule;
|
|
2645
|
+
exports.CSSPositionTryDescriptors = CSSPositionTryDescriptors;
|
|
2332
2646
|
exports.CSSPositionTryRule = CSSPositionTryRule;
|
|
2333
2647
|
exports.CSSPropertyRule = CSSPropertyRule;
|
|
2334
2648
|
exports.CSSRule = CSSRule;
|
|
@@ -2342,6 +2656,7 @@ exports.CSSSupportsRule = CSSSupportsRule;
|
|
|
2342
2656
|
exports.CSSViewTransitionRule = CSSViewTransitionRule;
|
|
2343
2657
|
exports.MediaList = MediaList;
|
|
2344
2658
|
exports.SheetOMSerializationError = SheetOMSerializationError;
|
|
2659
|
+
exports.StyleSheet = StyleSheet;
|
|
2345
2660
|
exports.parseStyleSheet = parseStyleSheet;
|
|
2346
2661
|
|
|
2347
2662
|
//# sourceMappingURL=index.cjs.map
|