sheetom 0.1.0 → 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 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: 3,
32
- sheetomVersion: "0.1.0",
33
- syntaxEngineSetSha256: "31990c26ede4e17c3a8941027f92b2be96a167984d0ab6529e724c3d6126be50"
31
+ abiVersion: 5,
32
+ sheetomVersion: "0.2.0",
33
+ syntaxEngineSetSha256: "954d76058dc35ad2a5c85e41fd66e35d308856e554c93563e7eee8a4704d4b70"
34
34
  });
35
35
  var SheetOMEngineBindingError = class extends Error {
36
36
  code;
@@ -65,7 +65,7 @@ function loadBinding() {
65
65
  validateEngineBindingIdentity(addon);
66
66
  return {
67
67
  ...addon,
68
- createDeclarationState: (context, ...budget) => new addon.NativeDeclarationState(context, ...budget)
68
+ createDeclarationState: (context, ...arguments_) => new addon.NativeDeclarationState(context, ...arguments_)
69
69
  };
70
70
  }
71
71
  //#endregion
@@ -152,11 +152,16 @@ var NativeDeclarationBlock = class {
152
152
  #reservedNestingDepth;
153
153
  #observableCache;
154
154
  #serializationCache = /* @__PURE__ */ new Map();
155
- constructor(reportDiagnostic, reportSerializationDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0) {
155
+ constructor(reportDiagnostic, reportSerializationDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0, initialCssText) {
156
156
  this.#reportDiagnostic = reportDiagnostic;
157
157
  this.#reportSerializationDiagnostic = reportSerializationDiagnostic;
158
158
  this.#reservedNestingDepth = reservedNestingDepth;
159
- this.#state = engineBinding.createDeclarationState(context, ...nativeBudgetArguments(resourceBudget));
159
+ try {
160
+ this.#state = engineBinding.createDeclarationState(context, ...nativeBudgetArguments(resourceBudget), initialCssText);
161
+ } catch (error) {
162
+ rethrowResourceBudgetError(error);
163
+ throw error;
164
+ }
160
165
  }
161
166
  get cssText() {
162
167
  this.#observableCache ??= this.#state.cssText;
@@ -375,8 +380,8 @@ function isNativeRuleDescription(value) {
375
380
  }
376
381
  //#endregion
377
382
  //#region src/internal/native-rule-syntax.ts
378
- function normalizeNativeSelector(source, resourceBudget = defaultResourceBudget) {
379
- return callNative(() => engineBinding.normalizeSelector(source, ...nativeBudgetArguments(resourceBudget)));
383
+ function normalizeNativeSelector(source, resourceBudget = defaultResourceBudget, namespaces = "") {
384
+ return callNative(() => engineBinding.normalizeSelector(source, namespaces, ...nativeBudgetArguments(resourceBudget)));
380
385
  }
381
386
  function normalizeNativeMedia(source, resourceBudget = defaultResourceBudget) {
382
387
  return callNative(() => engineBinding.normalizeMedia(source, ...nativeBudgetArguments(resourceBudget)));
@@ -415,6 +420,9 @@ function callNative(operation) {
415
420
  return null;
416
421
  }
417
422
  }
423
+ function supportsNativeCss(source, value) {
424
+ return engineBinding.supportsCss(source, value);
425
+ }
418
426
  //#endregion
419
427
  //#region src/internal/rule-tree.ts
420
428
  /** Owns child-list identity and parent propagation for every live rule node. */
@@ -594,6 +602,39 @@ function assertInternalConstructor(name) {
594
602
  }
595
603
  //#endregion
596
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
+ });
597
638
  const arrayIndexPattern = /^(0|[1-9]\d*)$/;
598
639
  const regularSheetMetadata = /* @__PURE__ */ new WeakMap();
599
640
  const ruleParentage = /* @__PURE__ */ new WeakMap();
@@ -601,7 +642,19 @@ const ruleResourceBudgets = /* @__PURE__ */ new WeakMap();
601
642
  const sheetResourceBudgets = /* @__PURE__ */ new WeakMap();
602
643
  const sheetRuleArrays = /* @__PURE__ */ new WeakMap();
603
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
+ }
604
656
  const functionRuleHeaders = /* @__PURE__ */ new WeakMap();
657
+ const mixinRuleHeaders = /* @__PURE__ */ new WeakMap();
605
658
  const unsignedLongRange = 2 ** 32;
606
659
  const pageMarginRuleNames = /* @__PURE__ */ new Set([
607
660
  "top-left-corner",
@@ -622,6 +675,7 @@ const pageMarginRuleNames = /* @__PURE__ */ new Set([
622
675
  "left-top"
623
676
  ]);
624
677
  const ignoreDiagnostic = () => {};
678
+ const normalizedSelectorText = Symbol("normalizedSelectorText");
625
679
  const ruleDiagnostics = /* @__PURE__ */ new WeakMap();
626
680
  const ruleTree = new RuleTree((rule, parentRule, parentStyleSheet) => {
627
681
  ruleParentage.set(rule, {
@@ -653,8 +707,8 @@ function namedPropertyToCSS(property) {
653
707
  if (/^(webkit|moz|ms|o)-/.test(cssName)) cssName = `-${cssName}`;
654
708
  return cssName;
655
709
  }
656
- function normalizeSelectorText(value, resourceBudget = defaultResourceBudget) {
657
- return normalizeNativeSelector(value, resourceBudget);
710
+ function normalizeSelectorText(value, resourceBudget = defaultResourceBudget, namespaces = "") {
711
+ return normalizeNativeSelector(value, resourceBudget, namespaces);
658
712
  }
659
713
  function toUnsignedLong(value) {
660
714
  const number = Number(value);
@@ -1046,6 +1100,112 @@ var CSSFunctionRule = class extends CSSGroupingRule {
1046
1100
  }
1047
1101
  set cssText(_value) {}
1048
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
+ }
1049
1209
  function serializeFunctionHeader(name, parameters, returnType) {
1050
1210
  const serializedParameters = parameters.map((parameter) => {
1051
1211
  const type = serializeFunctionType(parameter.type);
@@ -1278,7 +1438,7 @@ var CSSViewTransitionRule = class extends CSSRule {
1278
1438
  var CSSStyleDeclaration = class {
1279
1439
  parentRule;
1280
1440
  #block;
1281
- constructor(parentRule) {
1441
+ constructor(parentRule, initialCssText) {
1282
1442
  assertInternalConstructor("CSSStyleDeclaration");
1283
1443
  this.parentRule = parentRule;
1284
1444
  lockOwnProperties(this, "parentRule");
@@ -1308,7 +1468,7 @@ var CSSStyleDeclaration = class {
1308
1468
  };
1309
1469
  (ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
1310
1470
  };
1311
- this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, reportSerializationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule));
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);
1312
1472
  return new Proxy(this, {
1313
1473
  get(target, property) {
1314
1474
  if (typeof property === "string" && arrayIndexPattern.test(property)) return target.item(Number(property)) || void 0;
@@ -1393,9 +1553,9 @@ var CSSStyleDeclaration = class {
1393
1553
  /** A live `@font-face` descriptor rule. */
1394
1554
  var CSSFontFaceRule = class extends CSSRule {
1395
1555
  style;
1396
- constructor() {
1556
+ constructor(initialCssText) {
1397
1557
  super(CSSRule.FONT_FACE_RULE);
1398
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
1558
+ this.style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1399
1559
  lockOwnProperties(this, "style");
1400
1560
  }
1401
1561
  get cssText() {
@@ -1406,9 +1566,9 @@ var CSSFontFaceRule = class extends CSSRule {
1406
1566
  /** Declarations ordered after a nested style rule. */
1407
1567
  var CSSNestedDeclarations = class extends CSSRule {
1408
1568
  #style;
1409
- constructor() {
1569
+ constructor(initialCssText) {
1410
1570
  super(0);
1411
- this.#style = constructWebIDL(CSSStyleDeclaration, [this]);
1571
+ this.#style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1412
1572
  }
1413
1573
  get style() {
1414
1574
  return this.#style;
@@ -1424,9 +1584,9 @@ var CSSNestedDeclarations = class extends CSSRule {
1424
1584
  /** A run of live descriptors inside a custom function. */
1425
1585
  var CSSFunctionDeclarations = class extends CSSRule {
1426
1586
  #style;
1427
- constructor() {
1587
+ constructor(initialCssText) {
1428
1588
  super(0);
1429
- this.#style = constructWebIDL(CSSFunctionDescriptors, [this]);
1589
+ this.#style = constructWebIDL(CSSFunctionDescriptors, [this, initialCssText]);
1430
1590
  }
1431
1591
  get style() {
1432
1592
  return this.#style;
@@ -1450,10 +1610,10 @@ var CSSFunctionDescriptors = class extends CSSStyleDeclaration {
1450
1610
  var CSSMarginRule = class extends CSSRule {
1451
1611
  name;
1452
1612
  style;
1453
- constructor(name) {
1613
+ constructor(name, initialCssText) {
1454
1614
  super(CSSRule.MARGIN_RULE);
1455
1615
  this.name = name;
1456
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
1616
+ this.style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1457
1617
  lockOwnProperties(this, "name", "style");
1458
1618
  }
1459
1619
  get cssText() {
@@ -1465,10 +1625,10 @@ var CSSMarginRule = class extends CSSRule {
1465
1625
  var CSSPageRule = class extends CSSGroupingRule {
1466
1626
  style;
1467
1627
  #selectorText;
1468
- constructor(selectorText) {
1628
+ constructor(selectorText, initialCssText) {
1469
1629
  super(CSSRule.PAGE_RULE);
1470
1630
  this.#selectorText = selectorText;
1471
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
1631
+ this.style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1472
1632
  lockOwnProperties(this, "style");
1473
1633
  }
1474
1634
  get selectorText() {
@@ -1485,15 +1645,76 @@ var CSSPageRule = class extends CSSGroupingRule {
1485
1645
  }
1486
1646
  set cssText(_value) {}
1487
1647
  };
1488
- /** A live `@position-try` declaration rule. */
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. */
1489
1704
  var CSSPositionTryRule = class extends CSSRule {
1490
1705
  name;
1491
- style;
1492
- constructor(name) {
1706
+ #style;
1707
+ constructor(name, initialCssText) {
1493
1708
  super(0);
1494
1709
  this.name = name;
1495
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
1496
- lockOwnProperties(this, "name", "style");
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}`;
1497
1718
  }
1498
1719
  get cssText() {
1499
1720
  return `@position-try ${this.name} {${this.style.cssText === "" ? "" : ` ${this.style.cssText}`} }`;
@@ -1526,10 +1747,10 @@ function normalizeKeyText(value) {
1526
1747
  var CSSKeyframeRule = class extends CSSRule {
1527
1748
  style;
1528
1749
  #keyText;
1529
- constructor(keyText) {
1750
+ constructor(keyText, initialCssText) {
1530
1751
  super(CSSRule.KEYFRAME_RULE);
1531
1752
  this.#keyText = normalizeKeyText(keyText) ?? keyText;
1532
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
1753
+ this.style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1533
1754
  lockOwnProperties(this, "style");
1534
1755
  }
1535
1756
  get keyText() {
@@ -1840,17 +2061,20 @@ var CSSFontFeatureValuesRule = class extends CSSRule {
1840
2061
  var CSSStyleRule = class extends CSSGroupingRule {
1841
2062
  style;
1842
2063
  #selectorText;
1843
- constructor(selectorText) {
2064
+ #namespaces() {
2065
+ return namespaceText(this.parentStyleSheet);
2066
+ }
2067
+ constructor(selectorText, normalized, initialCssText) {
1844
2068
  super(CSSRule.STYLE_RULE);
1845
- this.#selectorText = normalizeSelectorText(`${selectorText}`, currentConstructionResourceBudget()) ?? `${selectorText}`;
1846
- this.style = constructWebIDL(CSSStyleDeclaration, [this]);
2069
+ this.#selectorText = normalized === normalizedSelectorText ? selectorText : normalizeSelectorText(`${selectorText}`, currentConstructionResourceBudget()) ?? `${selectorText}`;
2070
+ this.style = constructWebIDL(CSSStyleDeclaration, [this, initialCssText]);
1847
2071
  lockOwnProperties(this, "style");
1848
2072
  }
1849
2073
  get selectorText() {
1850
2074
  return this.#selectorText;
1851
2075
  }
1852
2076
  set selectorText(value) {
1853
- const normalized = normalizeSelectorText(`${value}`, ruleResourceBudgets.get(this) ?? defaultResourceBudget);
2077
+ const normalized = normalizeSelectorText(`${value}`, ruleResourceBudgets.get(this) ?? defaultResourceBudget, this.#namespaces());
1854
2078
  if (normalized === null) return;
1855
2079
  this.#selectorText = normalized;
1856
2080
  }
@@ -1906,17 +2130,24 @@ function describeRuleSafe(rule, strict) {
1906
2130
  declarations: rule.style.serializeSafe(" ", strict),
1907
2131
  children: ruleTree.children(rule)
1908
2132
  };
2133
+ if (rule instanceof CSSApplyStatementRule && rule.getArguments().length === 1 && rule.getArguments()[0] === "") return {
2134
+ kind: "raw",
2135
+ cssText: `@apply ${rule.name}({ });`
2136
+ };
1909
2137
  if (!(rule instanceof CSSGroupingRule)) return {
1910
2138
  kind: "raw",
1911
2139
  cssText: rule.cssText
1912
2140
  };
1913
2141
  return {
1914
2142
  kind: "block",
1915
- header: groupingRuleHeader(rule),
2143
+ header: rule instanceof CSSApplyBlockRule && rule.getArguments().length === 1 && rule.getArguments()[0] === "" ? `@apply ${rule.name}({ })` : groupingRuleHeader(rule),
1916
2144
  children: ruleTree.children(rule)
1917
2145
  };
1918
2146
  }
1919
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;
1920
2151
  if (rule instanceof CSSFunctionRule) return functionRuleHeaders.get(rule) ?? "@function";
1921
2152
  if (rule instanceof CSSMediaRule) return `@media ${rule.media.mediaText}`;
1922
2153
  if (rule instanceof CSSSupportsRule) return `@supports ${rule.conditionText}`;
@@ -1968,12 +2199,13 @@ function parseImportPrelude(prelude) {
1968
2199
  supports
1969
2200
  };
1970
2201
  }
1971
- function createRuleFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
1972
- 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);
1973
2204
  }
1974
- function createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
2205
+ function createRuleTreeFromNative(description, reportDiagnostic, preserveImports, resourceBudget, parentRule) {
1975
2206
  const root = createRuleShellFromNative(description, reportDiagnostic, preserveImports, resourceBudget);
1976
2207
  if (!root) return null;
2208
+ attachRuleTree(root, parentRule, parentRule?.parentStyleSheet ?? null);
1977
2209
  const pending = [{
1978
2210
  description,
1979
2211
  rule: root
@@ -1985,9 +2217,10 @@ function createRuleTreeFromNative(description, reportDiagnostic, preserveImports
1985
2217
  const childFrames = [];
1986
2218
  for (const childDescription of current.description.children) {
1987
2219
  if (isNativeMetadataRule(childDescription)) continue;
2220
+ if (!isMixinContextAllowed(childDescription.kind, current.rule)) continue;
1988
2221
  const child = createRuleShellFromNative(childDescription, reportDiagnostic, preserveImports, resourceBudget);
1989
2222
  if (!child) continue;
1990
- if (child instanceof CSSFunctionDeclarations && child.style.length === 0) continue;
2223
+ if ((child instanceof CSSFunctionDeclarations || child instanceof CSSNestedDeclarations) && child.style.length === 0) continue;
1991
2224
  if (current.rule instanceof CSSKeyframesRule && !(child instanceof CSSKeyframeRule)) continue;
1992
2225
  children.push(child);
1993
2226
  childFrames.push({
@@ -2005,29 +2238,24 @@ function createRuleTreeFromNative(description, reportDiagnostic, preserveImports
2005
2238
  return root;
2006
2239
  }
2007
2240
  function isNativeMetadataRule(description) {
2008
- 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";
2009
2242
  }
2010
2243
  function createRuleShellFromNative(description, reportDiagnostic, preserveImports, resourceBudget) {
2011
2244
  let rule;
2012
2245
  switch (description.kind) {
2013
- case "style": {
2014
- const style = constructWebIDL(CSSStyleRule, [description.prelude]);
2015
- style.style.cssText = description.declarations;
2016
- rule = style;
2246
+ case "style":
2247
+ rule = constructWebIDL(CSSStyleRule, [
2248
+ description.prelude,
2249
+ normalizedSelectorText,
2250
+ description.declarations
2251
+ ]);
2017
2252
  break;
2018
- }
2019
- case "nested-declarations": {
2020
- const nested = constructWebIDL(CSSNestedDeclarations);
2021
- nested.style.cssText = description.declarations;
2022
- rule = nested;
2253
+ case "nested-declarations":
2254
+ rule = constructWebIDL(CSSNestedDeclarations, [description.declarations]);
2023
2255
  break;
2024
- }
2025
- case "function-declarations": {
2026
- const declarations = constructWebIDL(CSSFunctionDeclarations);
2027
- declarations.style.cssText = description.declarations;
2028
- rule = declarations;
2256
+ case "function-declarations":
2257
+ rule = constructWebIDL(CSSFunctionDeclarations, [description.declarations]);
2029
2258
  break;
2030
- }
2031
2259
  case "import": {
2032
2260
  if (!preserveImports) return null;
2033
2261
  const parsed = parseImportPrelude(description.cssText.replace(/^@import\s+/iu, "").replace(/;\s*$/u, ""));
@@ -2040,39 +2268,24 @@ function createRuleShellFromNative(description, reportDiagnostic, preserveImport
2040
2268
  ]);
2041
2269
  break;
2042
2270
  }
2043
- case "font-face": {
2044
- const fontFace = constructWebIDL(CSSFontFaceRule);
2045
- fontFace.style.cssText = description.declarations;
2046
- rule = fontFace;
2271
+ case "font-face":
2272
+ rule = constructWebIDL(CSSFontFaceRule, [description.declarations]);
2047
2273
  break;
2048
- }
2049
- case "page": {
2050
- const page = constructWebIDL(CSSPageRule, [description.prelude]);
2051
- page.style.cssText = description.declarations;
2052
- rule = page;
2274
+ case "page":
2275
+ rule = constructWebIDL(CSSPageRule, [description.prelude, description.declarations]);
2053
2276
  break;
2054
- }
2055
- case "margin": {
2056
- const margin = constructWebIDL(CSSMarginRule, [description.prelude]);
2057
- margin.style.cssText = description.declarations;
2058
- rule = margin;
2277
+ case "margin":
2278
+ rule = constructWebIDL(CSSMarginRule, [description.prelude, description.declarations]);
2059
2279
  break;
2060
- }
2061
- case "position-try": {
2062
- const positionTry = constructWebIDL(CSSPositionTryRule, [description.prelude]);
2063
- positionTry.style.cssText = description.declarations;
2064
- rule = positionTry;
2280
+ case "position-try":
2281
+ rule = constructWebIDL(CSSPositionTryRule, [description.prelude, description.declarations]);
2065
2282
  break;
2066
- }
2067
2283
  case "keyframes":
2068
2284
  rule = constructWebIDL(CSSKeyframesRule, [description.prelude]);
2069
2285
  break;
2070
- case "keyframe": {
2071
- const keyframe = constructWebIDL(CSSKeyframeRule, [description.prelude]);
2072
- keyframe.style.cssText = description.declarations;
2073
- rule = keyframe;
2286
+ case "keyframe":
2287
+ rule = constructWebIDL(CSSKeyframeRule, [description.prelude, description.declarations]);
2074
2288
  break;
2075
- }
2076
2289
  case "counter-style": {
2077
2290
  const counterStyle = constructWebIDL(CSSCounterStyleRule, [description.prelude]);
2078
2291
  hydrateCounterStyleDescriptors(counterStyle, description.declarations, resourceBudget);
@@ -2113,7 +2326,8 @@ function createRuleShellFromNative(description, reportDiagnostic, preserveImport
2113
2326
  description.children.filter((candidate) => candidate.kind === "view-transition-type").map((candidate) => candidate.prelude),
2114
2327
  description.cssText
2115
2328
  ]);
2116
- case "function": {
2329
+ case "function":
2330
+ case "mixin": {
2117
2331
  const parameters = description.children.filter((candidate) => candidate.kind === "function-parameter").map((candidate) => {
2118
2332
  const defaultValue = candidate.children.find((child) => child.kind === "property-descriptor" && child.prelude === "default-value");
2119
2333
  return defaultValue ? {
@@ -2125,13 +2339,35 @@ function createRuleShellFromNative(description, reportDiagnostic, preserveImport
2125
2339
  type: candidate.declarations
2126
2340
  };
2127
2341
  });
2128
- rule = constructWebIDL(CSSFunctionRule, [
2342
+ rule = description.kind === "mixin" ? constructWebIDL(CSSMixinRule, [description.prelude, parameters]) : constructWebIDL(CSSFunctionRule, [
2129
2343
  description.prelude,
2130
2344
  parameters,
2131
2345
  description.declarations
2132
2346
  ]);
2133
2347
  break;
2134
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;
2135
2371
  case "namespace": return constructWebIDL(CSSNamespaceRule, [
2136
2372
  nativeRuleDescriptor(description, "namespace-uri"),
2137
2373
  nativeRuleDescriptor(description, "prefix"),
@@ -2169,7 +2405,7 @@ function nativeRuleDescriptor(description, name) {
2169
2405
  function hydrateCounterStyleDescriptors(rule, declarations, resourceBudget) {
2170
2406
  for (const descriptor of parseNativeCounterStyleDescriptors(declarations, resourceBudget)) rule.setParsedDescriptor(descriptor.name, descriptor.value);
2171
2407
  }
2172
- 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)) {
2173
2409
  if (parentRule instanceof CSSPageRule) {
2174
2410
  const page = parseNativeRule(`@page { ${ruleText} }`, resourceBudget);
2175
2411
  if (page?.kind !== "page" || page.children.length !== 1) return null;
@@ -2179,7 +2415,41 @@ function parseStrictRule(ruleText, reportDiagnostic, preserveImports = false, pa
2179
2415
  }
2180
2416
  const description = parseNativeRule(ruleText, resourceBudget) ?? (parentRule && hasFunctionAncestor(parentRule) ? parseNativeRuleWithErrorRecovery(ruleText, resourceBudget) : null);
2181
2417
  if (!description || description.kind === "import" && !preserveImports) return null;
2182
- return createRuleFromNative(description, reportDiagnostic, preserveImports, resourceBudget);
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;
2183
2453
  }
2184
2454
  function hasFunctionAncestor(rule) {
2185
2455
  let current = rule;
@@ -2203,11 +2473,17 @@ function genericRuleType(name) {
2203
2473
  }
2204
2474
  }
2205
2475
  function parseStyleSheetRules(cssText, reportDiagnostic, preserveImports, resourceBudget) {
2476
+ let namespaces = "";
2477
+ let namespaceRulesAllowed = true;
2206
2478
  const rules = [];
2207
2479
  let parsedRuleCount = 0;
2208
2480
  for (const rawRule of scanTopLevelRules(cssText, resourceBudget)) {
2209
- const rule = parseStrictRule(rawRule, reportDiagnostic, preserveImports, null, resourceBudget);
2481
+ const rule = parseStrictRule(rawRule, reportDiagnostic, preserveImports, null, resourceBudget, namespaces);
2210
2482
  if (rule) {
2483
+ if (rule instanceof CSSNamespaceRule) {
2484
+ if (!namespaceRulesAllowed) continue;
2485
+ namespaces += rule.cssText;
2486
+ } else if (!(rule instanceof CSSImportRule)) namespaceRulesAllowed = false;
2211
2487
  parsedRuleCount += ruleForestSize([rule]);
2212
2488
  assertRuleCountBudget(parsedRuleCount, resourceBudget);
2213
2489
  rules.push(rule);
@@ -2219,38 +2495,50 @@ function parseStyleSheetRules(cssText, reportDiagnostic, preserveImports, resour
2219
2495
  assertRuleCountBudget(parsedRuleCount, resourceBudget);
2220
2496
  rules.push(opaque);
2221
2497
  }
2222
- return rules;
2498
+ return {
2499
+ rules,
2500
+ namespaces
2501
+ };
2223
2502
  }
2224
- /** A mutable, browser-shaped authoring stylesheet. */
2225
- var CSSStyleSheet = class {
2226
- cssRules;
2503
+ const stylesheetConstructionKey = Symbol("StyleSheet construction");
2504
+ /** Shared stylesheet metadata. Instances are created through CSSStyleSheet. */
2505
+ var StyleSheet = class {
2227
2506
  media;
2228
2507
  ownerNode = null;
2229
2508
  parentStyleSheet = null;
2230
- ownerRule = null;
2231
2509
  title = null;
2232
2510
  type = "text/css";
2233
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;
2234
2526
  #rules = [];
2235
2527
  #diagnostics;
2236
2528
  #constructedBaseURL;
2237
2529
  constructor(options = {}) {
2238
2530
  const normalizedOptions = options ?? {};
2239
2531
  const resourceBudget = normalizeResourceBudget(normalizedOptions.resourceBudget);
2532
+ super(normalizedOptions, resourceBudget, stylesheetConstructionKey);
2240
2533
  sheetResourceBudgets.set(this, resourceBudget);
2241
2534
  sheetRuleArrays.set(this, this.#rules);
2242
2535
  sheetRuleCounts.set(this, 0);
2536
+ sheetNamespaces.set(this, "");
2243
2537
  this.#diagnostics = Boolean(normalizedOptions.diagnostics) ? [] : null;
2244
2538
  this.#constructedBaseURL = normalizedOptions.baseURL === void 0 ? "about:blank" : `${normalizedOptions.baseURL}`;
2245
- const media = normalizedOptions.media === void 0 ? "" : `${normalizedOptions.media}`;
2246
- this.media = constructWithResourceBudget(() => constructWebIDL(MediaList, [media]), resourceBudget);
2247
- this.disabled = Boolean(normalizedOptions.disabled);
2248
2539
  this.cssRules = constructInternally(() => constructWebIDL(CSSRuleList, [this.#rules]));
2249
2540
  lockOwnProperties(this, "cssRules", "media", "ownerNode", "parentStyleSheet", "ownerRule", "title", "type");
2250
2541
  }
2251
- get href() {
2252
- return regularSheetMetadata.get(this)?.href ?? null;
2253
- }
2254
2542
  get baseURL() {
2255
2543
  return regularSheetMetadata.get(this)?.baseURL ?? this.#constructedBaseURL;
2256
2544
  }
@@ -2263,14 +2551,16 @@ var CSSStyleSheet = class {
2263
2551
  if (normalizedIndex > this.#rules.length) throw new DOMException("The index is outside the allowed range.", "IndexSizeError");
2264
2552
  const regular = regularSheetMetadata.has(this);
2265
2553
  const resourceBudget = sheetResourceBudgets.get(this) ?? defaultResourceBudget;
2266
- const rule = parseStrictRule(`${ruleText}`, this.#reportDiagnostic, regular, null, resourceBudget);
2554
+ const rule = parseStrictRule(`${ruleText}`, this.#reportDiagnostic, regular, null, resourceBudget, namespaceText(this));
2267
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");
2268
2557
  const precedingRules = this.#rules.slice(0, normalizedIndex);
2269
2558
  const followingRules = this.#rules.slice(normalizedIndex);
2270
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");
2271
2560
  const insertedCount = assertRuleInsertionBudget(this, rule, resourceBudget);
2272
2561
  attachRuleTree(rule, null, this);
2273
2562
  this.#rules.splice(normalizedIndex, 0, rule);
2563
+ if (rule instanceof CSSNamespaceRule) sheetNamespaces.set(this, namespaceRulesText(this.#rules));
2274
2564
  adjustSheetRuleCount(this, insertedCount);
2275
2565
  return normalizedIndex;
2276
2566
  }
@@ -2278,15 +2568,18 @@ var CSSStyleSheet = class {
2278
2568
  requireArguments(arguments.length, 1, "CSSStyleSheet", "deleteRule");
2279
2569
  const normalizedIndex = toUnsignedLong(index);
2280
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");
2281
2572
  const [removed] = this.#rules.splice(normalizedIndex, 1);
2282
2573
  if (!removed) return;
2574
+ if (removed instanceof CSSNamespaceRule) sheetNamespaces.set(this, namespaceRulesText(this.#rules));
2283
2575
  adjustSheetRuleCount(this, -ruleForestSize([removed]));
2284
2576
  attachRuleTree(removed, null, null);
2285
2577
  }
2286
2578
  replaceSync(cssText) {
2287
2579
  requireArguments(arguments.length, 1, "CSSStyleSheet", "replaceSync");
2288
- 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);
2289
2581
  for (const rule of this.#rules) attachRuleTree(rule, null, null);
2582
+ sheetNamespaces.set(this, namespaces);
2290
2583
  for (const rule of replacement) attachRuleTree(rule, null, this);
2291
2584
  this.#rules.splice(0, this.#rules.length, ...replacement);
2292
2585
  sheetRuleCounts.set(this, ruleForestSize(replacement));
@@ -2322,8 +2615,13 @@ function parseStyleSheet(cssText, options = {}) {
2322
2615
  return sheet;
2323
2616
  }
2324
2617
  //#endregion
2618
+ exports.CSS = CSS;
2619
+ exports.CSSApplyBlockRule = CSSApplyBlockRule;
2620
+ exports.CSSApplyStatementRule = CSSApplyStatementRule;
2325
2621
  exports.CSSConditionRule = CSSConditionRule;
2326
2622
  exports.CSSContainerRule = CSSContainerRule;
2623
+ exports.CSSContentsBlockRule = CSSContentsBlockRule;
2624
+ exports.CSSContentsStatementRule = CSSContentsStatementRule;
2327
2625
  exports.CSSCounterStyleRule = CSSCounterStyleRule;
2328
2626
  exports.CSSFontFaceRule = CSSFontFaceRule;
2329
2627
  exports.CSSFontFeatureValuesMap = CSSFontFeatureValuesMap;
@@ -2340,9 +2638,11 @@ exports.CSSLayerBlockRule = CSSLayerBlockRule;
2340
2638
  exports.CSSLayerStatementRule = CSSLayerStatementRule;
2341
2639
  exports.CSSMarginRule = CSSMarginRule;
2342
2640
  exports.CSSMediaRule = CSSMediaRule;
2641
+ exports.CSSMixinRule = CSSMixinRule;
2343
2642
  exports.CSSNamespaceRule = CSSNamespaceRule;
2344
2643
  exports.CSSNestedDeclarations = CSSNestedDeclarations;
2345
2644
  exports.CSSPageRule = CSSPageRule;
2645
+ exports.CSSPositionTryDescriptors = CSSPositionTryDescriptors;
2346
2646
  exports.CSSPositionTryRule = CSSPositionTryRule;
2347
2647
  exports.CSSPropertyRule = CSSPropertyRule;
2348
2648
  exports.CSSRule = CSSRule;
@@ -2356,6 +2656,7 @@ exports.CSSSupportsRule = CSSSupportsRule;
2356
2656
  exports.CSSViewTransitionRule = CSSViewTransitionRule;
2357
2657
  exports.MediaList = MediaList;
2358
2658
  exports.SheetOMSerializationError = SheetOMSerializationError;
2659
+ exports.StyleSheet = StyleSheet;
2359
2660
  exports.parseStyleSheet = parseStyleSheet;
2360
2661
 
2361
2662
  //# sourceMappingURL=index.cjs.map