sheetom 0.1.0-rc.9 → 0.1.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/README.md +32 -0
- package/dist/index.cjs +214 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -12
- package/dist/index.d.ts +59 -12
- package/dist/index.js +214 -39
- package/dist/index.js.map +1 -1
- package/docs/api.md +42 -6
- package/engine-abi.json +3 -3
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -64,6 +64,31 @@ Constructed sheets strip `@import` during replacement. `parseStyleSheet()` is a
|
|
|
64
64
|
SheetOM extension for existing regular stylesheets and preserves valid imports
|
|
65
65
|
without fetching them.
|
|
66
66
|
|
|
67
|
+
Compilers can apply all known mutations for one rule with one engine crossing
|
|
68
|
+
and still receive one acceptance result per operation:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
function applyCompilerDeclarations(rule: CSSStyleRule, dynamicWidth: string) {
|
|
72
|
+
const results = rule.style.applyMutations([
|
|
73
|
+
{ kind: "set", property: "display", value: "grid" },
|
|
74
|
+
{ kind: "set", property: "width", value: dynamicWidth },
|
|
75
|
+
{ kind: "remove", property: "margin-left" },
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
for (const result of results) {
|
|
79
|
+
if (result.kind === "set" && !result.accepted) {
|
|
80
|
+
console.warn(result.diagnostic);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Operations run in order through the same validation and shorthand/longhand
|
|
87
|
+
state machine as individual calls. Group one batch per declaration block;
|
|
88
|
+
never combine values into declaration text. Batch results already include
|
|
89
|
+
rejection diagnostics, so high-volume callers can leave the sheet diagnostic
|
|
90
|
+
queue disabled unless they also need diagnostics from other APIs.
|
|
91
|
+
|
|
67
92
|
## Browser recovery, safe output
|
|
68
93
|
|
|
69
94
|
Browsers accept some CSS using end-of-input recovery and expose the incomplete
|
|
@@ -94,6 +119,13 @@ sheet.serialize();
|
|
|
94
119
|
| `style.cssText` | Browser-compatible declaration text, including measured recovery quirks. |
|
|
95
120
|
| `rule.cssText` | Browser-compatible text for the current rule. |
|
|
96
121
|
| `sheet.serialize()` | Deterministic, reparsable CSS for a complete stylesheet. |
|
|
122
|
+
| `sheet.serializeStrict()` | Exact-only output that rejects CSSOM states CSS text cannot represent faithfully. |
|
|
123
|
+
|
|
124
|
+
Pending-substitution shorthands survive later longhand edits in reparsable
|
|
125
|
+
output. If an imperative priority combination cannot be represented exactly,
|
|
126
|
+
`serialize()` emits a local best-effort result and an opt-in structured
|
|
127
|
+
diagnostic rather than blocking the whole stylesheet. Use `serializeStrict()`
|
|
128
|
+
when approximation is unacceptable.
|
|
97
129
|
|
|
98
130
|
Invalid property values and priorities are atomic no-ops: the previous state
|
|
99
131
|
survives unchanged. Static shorthands are stored as canonical longhands, so
|
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.1.0
|
|
33
|
-
syntaxEngineSetSha256: "
|
|
31
|
+
abiVersion: 3,
|
|
32
|
+
sheetomVersion: "0.1.0",
|
|
33
|
+
syntaxEngineSetSha256: "31990c26ede4e17c3a8941027f92b2be96a167984d0ab6529e724c3d6126be50"
|
|
34
34
|
});
|
|
35
35
|
var SheetOMEngineBindingError = class extends Error {
|
|
36
36
|
code;
|
|
@@ -114,16 +114,47 @@ function limitValue(value, name, fallback, maximum = maximumUnsignedLong) {
|
|
|
114
114
|
throw new RangeError(`${name} must be an integer between 0 and ${maximum}`);
|
|
115
115
|
}
|
|
116
116
|
//#endregion
|
|
117
|
+
//#region src/serialization-error.ts
|
|
118
|
+
/** A reparsable stylesheet cannot faithfully represent the current CSSOM state. */
|
|
119
|
+
var SheetOMSerializationError = class extends Error {
|
|
120
|
+
code;
|
|
121
|
+
shorthand;
|
|
122
|
+
conflictingLonghands;
|
|
123
|
+
constructor(shorthand, conflictingLonghands, options) {
|
|
124
|
+
super(`SheetOM cannot serialize the pending ${shorthand} shorthand without changing its semantics.`, options);
|
|
125
|
+
this.name = "SheetOMSerializationError";
|
|
126
|
+
this.code = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
127
|
+
this.shorthand = shorthand;
|
|
128
|
+
this.conflictingLonghands = Object.freeze([...conflictingLonghands]);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const unrepresentablePendingShorthandPattern = /^SHEETOM_UNREPRESENTABLE_PENDING_SHORTHAND: shorthand=([^;]+); conflicting=([a-z0-9,-]+)$/u;
|
|
132
|
+
function serializationErrorFrom(error) {
|
|
133
|
+
if (!(error instanceof Error)) return null;
|
|
134
|
+
const match = unrepresentablePendingShorthandPattern.exec(error.message);
|
|
135
|
+
if (!match) return null;
|
|
136
|
+
const shorthand = match[1];
|
|
137
|
+
const conflicts = match[2];
|
|
138
|
+
if (!shorthand || !conflicts) return null;
|
|
139
|
+
return new SheetOMSerializationError(shorthand, conflicts.split(","), { cause: error });
|
|
140
|
+
}
|
|
141
|
+
function rethrowSerializationError(error) {
|
|
142
|
+
const serializationError = serializationErrorFrom(error);
|
|
143
|
+
if (serializationError) throw serializationError;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
117
146
|
//#region src/internal/native-declaration-block.ts
|
|
118
147
|
/** Thin JS ownership boundary around the Rust declaration state machine. */
|
|
119
148
|
var NativeDeclarationBlock = class {
|
|
120
149
|
#state;
|
|
121
150
|
#reportDiagnostic;
|
|
151
|
+
#reportSerializationDiagnostic;
|
|
122
152
|
#reservedNestingDepth;
|
|
123
153
|
#observableCache;
|
|
124
154
|
#serializationCache = /* @__PURE__ */ new Map();
|
|
125
|
-
constructor(reportDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0) {
|
|
155
|
+
constructor(reportDiagnostic, reportSerializationDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0) {
|
|
126
156
|
this.#reportDiagnostic = reportDiagnostic;
|
|
157
|
+
this.#reportSerializationDiagnostic = reportSerializationDiagnostic;
|
|
127
158
|
this.#reservedNestingDepth = reservedNestingDepth;
|
|
128
159
|
this.#state = engineBinding.createDeclarationState(context, ...nativeBudgetArguments(resourceBudget));
|
|
129
160
|
}
|
|
@@ -155,9 +186,59 @@ var NativeDeclarationBlock = class {
|
|
|
155
186
|
this.#invalidateSerialization();
|
|
156
187
|
return;
|
|
157
188
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
189
|
+
this.#diagnosticForOutcome(outcome, name, value, priority);
|
|
190
|
+
}
|
|
191
|
+
applyMutations(mutations) {
|
|
192
|
+
const kinds = [];
|
|
193
|
+
const properties = [];
|
|
194
|
+
const values = [];
|
|
195
|
+
const priorities = [];
|
|
196
|
+
for (const mutation of mutations) {
|
|
197
|
+
kinds.push(mutation.kind === "set" ? 0 : 1);
|
|
198
|
+
properties.push(mutation.property);
|
|
199
|
+
values.push(mutation.kind === "set" ? mutation.value : "");
|
|
200
|
+
priorities.push(mutation.kind === "set" ? mutation.priority : "");
|
|
201
|
+
}
|
|
202
|
+
let outcomes;
|
|
203
|
+
try {
|
|
204
|
+
outcomes = this.#state.applyMutations(kinds, properties, values, priorities, this.#reservedNestingDepth());
|
|
205
|
+
} catch (error) {
|
|
206
|
+
rethrowResourceBudgetError(error);
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
if (outcomes.length !== mutations.length) throw new Error("SheetOM engine returned an incomplete declaration mutation result.");
|
|
210
|
+
const results = [];
|
|
211
|
+
let mutated = false;
|
|
212
|
+
for (let index = 0; index < outcomes.length; index += 1) {
|
|
213
|
+
const mutation = mutations[index];
|
|
214
|
+
const outcome = outcomes[index];
|
|
215
|
+
if (!mutation || outcome === void 0) throw new Error("SheetOM engine returned a mismatched declaration mutation result.");
|
|
216
|
+
if (mutation.kind === "remove") {
|
|
217
|
+
mutated = true;
|
|
218
|
+
results.push({
|
|
219
|
+
kind: "remove",
|
|
220
|
+
value: outcome
|
|
221
|
+
});
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (outcome === "applied") {
|
|
225
|
+
mutated = true;
|
|
226
|
+
results.push({
|
|
227
|
+
kind: "set",
|
|
228
|
+
accepted: true,
|
|
229
|
+
diagnostic: null
|
|
230
|
+
});
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (!isEngineMutationOutcome(outcome)) throw new Error("SheetOM engine returned an invalid declaration mutation outcome.");
|
|
234
|
+
results.push({
|
|
235
|
+
kind: "set",
|
|
236
|
+
accepted: false,
|
|
237
|
+
diagnostic: this.#diagnosticForOutcome(outcome, mutation.property, mutation.value, mutation.priority)
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (mutated) this.#invalidateSerialization();
|
|
241
|
+
return results;
|
|
161
242
|
}
|
|
162
243
|
removeProperty(name) {
|
|
163
244
|
const removed = this.#state.removeProperty(name);
|
|
@@ -173,19 +254,63 @@ var NativeDeclarationBlock = class {
|
|
|
173
254
|
}
|
|
174
255
|
this.#invalidateSerialization();
|
|
175
256
|
}
|
|
176
|
-
serialize(safe, indent, separator) {
|
|
177
|
-
const cacheKey = `${safe ? "1" : "0"}\0${indent}\0${separator}`;
|
|
257
|
+
serialize(safe, indent, separator, strict = false) {
|
|
258
|
+
const cacheKey = `${safe ? "1" : "0"}${strict ? "1" : "0"}\0${indent}\0${separator}`;
|
|
178
259
|
const cached = this.#serializationCache.get(cacheKey);
|
|
179
|
-
if (cached !== void 0)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
260
|
+
if (cached !== void 0) {
|
|
261
|
+
if (typeof cached === "string") return cached;
|
|
262
|
+
this.#reportSerializationIssues(cached.issues);
|
|
263
|
+
return cached.serialized;
|
|
264
|
+
}
|
|
265
|
+
let result;
|
|
266
|
+
try {
|
|
267
|
+
if (strict) result = this.#state.serializeFormatted(safe, indent, separator);
|
|
268
|
+
else result = parseResilientSerializationResult(this.#state.serializeFormattedResilient(safe, indent, separator));
|
|
269
|
+
} catch (error) {
|
|
270
|
+
rethrowResourceBudgetError(error);
|
|
271
|
+
rethrowSerializationError(error);
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
this.#serializationCache.set(cacheKey, result);
|
|
275
|
+
if (typeof result === "string") return result;
|
|
276
|
+
this.#reportSerializationIssues(result.issues);
|
|
277
|
+
return result.serialized;
|
|
183
278
|
}
|
|
184
279
|
#invalidateSerialization() {
|
|
185
280
|
this.#observableCache = void 0;
|
|
186
281
|
this.#serializationCache.clear();
|
|
187
282
|
}
|
|
283
|
+
#diagnosticForOutcome(outcome, name, value, priority) {
|
|
284
|
+
const normalizedName = name.startsWith("--") ? name : name.toLowerCase();
|
|
285
|
+
const [code, input] = outcome === "invalid-priority" ? ["INVALID_PRIORITY", priority] : outcome === "unsupported-shorthand" ? ["UNSUPPORTED_SHORTHAND_VALUE", value] : ["INVALID_PROPERTY_VALUE", value];
|
|
286
|
+
return this.#reportDiagnostic(code, normalizedName, input);
|
|
287
|
+
}
|
|
288
|
+
#reportSerializationIssues(issues) {
|
|
289
|
+
for (const issue of issues) this.#reportSerializationDiagnostic(issue.shorthand, issue.conflictingLonghands);
|
|
290
|
+
}
|
|
188
291
|
};
|
|
292
|
+
function parseResilientSerializationResult(output) {
|
|
293
|
+
const serialized = output[0];
|
|
294
|
+
if (serialized === void 0 || output.length % 2 === 0) throw new Error("SheetOM engine returned an invalid resilient serialization result.");
|
|
295
|
+
if (output.length === 1) return serialized;
|
|
296
|
+
const issues = [];
|
|
297
|
+
for (let index = 1; index < output.length; index += 2) {
|
|
298
|
+
const shorthand = output[index];
|
|
299
|
+
const conflicts = output[index + 1];
|
|
300
|
+
if (!shorthand || !conflicts) throw new Error("SheetOM engine returned an incomplete resilient serialization issue.");
|
|
301
|
+
issues.push({
|
|
302
|
+
shorthand,
|
|
303
|
+
conflictingLonghands: Object.freeze(conflicts.split(","))
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
serialized,
|
|
308
|
+
issues
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function isEngineMutationOutcome(value) {
|
|
312
|
+
return value === "invalid-name" || value === "invalid-priority" || value === "invalid-value" || value === "unsupported-shorthand";
|
|
313
|
+
}
|
|
189
314
|
function toUnsignedLong$1(value) {
|
|
190
315
|
const numeric = Number(value);
|
|
191
316
|
if (!Number.isFinite(numeric) || numeric === 0) return 0;
|
|
@@ -377,13 +502,20 @@ var Serializer = class {
|
|
|
377
502
|
this.#describe = describe;
|
|
378
503
|
}
|
|
379
504
|
serialize(node) {
|
|
505
|
+
return this.serializeMany([node]);
|
|
506
|
+
}
|
|
507
|
+
serializeMany(nodes) {
|
|
380
508
|
const chunks = [];
|
|
381
|
-
const pending = [
|
|
382
|
-
|
|
383
|
-
node
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
509
|
+
const pending = [];
|
|
510
|
+
for (let index = nodes.length - 1; index >= 0; index -= 1) {
|
|
511
|
+
const node = nodes[index];
|
|
512
|
+
if (node) pending.push({
|
|
513
|
+
kind: "node",
|
|
514
|
+
node,
|
|
515
|
+
depth: 0,
|
|
516
|
+
child: false
|
|
517
|
+
});
|
|
518
|
+
}
|
|
387
519
|
while (pending.length > 0) {
|
|
388
520
|
const frame = pending.pop();
|
|
389
521
|
if (!frame) continue;
|
|
@@ -497,7 +629,8 @@ const ruleTree = new RuleTree((rule, parentRule, parentStyleSheet) => {
|
|
|
497
629
|
parentStyleSheet
|
|
498
630
|
});
|
|
499
631
|
}, (rule) => rule.parentStyleSheet);
|
|
500
|
-
const safeSerializer = new Serializer(describeRuleSafe);
|
|
632
|
+
const safeSerializer = new Serializer((rule) => describeRuleSafe(rule, false));
|
|
633
|
+
const strictSerializer = new Serializer((rule) => describeRuleSafe(rule, true));
|
|
501
634
|
let activeConstructionResourceBudget = defaultResourceBudget;
|
|
502
635
|
function constructWithResourceBudget(factory, resourceBudget) {
|
|
503
636
|
const previous = activeConstructionResourceBudget;
|
|
@@ -1150,19 +1283,32 @@ var CSSStyleDeclaration = class {
|
|
|
1150
1283
|
this.parentRule = parentRule;
|
|
1151
1284
|
lockOwnProperties(this, "parentRule");
|
|
1152
1285
|
const reportDeclarationDiagnostic = (code, property, input) => {
|
|
1153
|
-
const
|
|
1154
|
-
const unsupportedShorthand = code === "UNSUPPORTED_SHORTHAND_VALUE";
|
|
1155
|
-
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)({
|
|
1286
|
+
const diagnostic = {
|
|
1156
1287
|
code,
|
|
1157
1288
|
severity: "warning",
|
|
1158
1289
|
operation: "setProperty",
|
|
1159
|
-
message:
|
|
1290
|
+
message: code === "INVALID_PRIORITY" ? `The mutation was ignored because ${input} is not a valid priority.` : code === "UNSUPPORTED_SHORTHAND_VALUE" ? `The value was ignored because the shorthand codec for ${property} cannot expand it.` : `The value was ignored because it is invalid for ${property}.`,
|
|
1160
1291
|
property,
|
|
1161
1292
|
input,
|
|
1162
1293
|
location: null
|
|
1163
|
-
}
|
|
1294
|
+
};
|
|
1295
|
+
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
|
|
1296
|
+
return diagnostic;
|
|
1297
|
+
};
|
|
1298
|
+
const reportSerializationDiagnostic = (shorthand, conflictingLonghands) => {
|
|
1299
|
+
const diagnostic = {
|
|
1300
|
+
code: "UNREPRESENTABLE_PENDING_SHORTHAND",
|
|
1301
|
+
severity: "warning",
|
|
1302
|
+
operation: "serialize",
|
|
1303
|
+
message: `The pending ${shorthand} shorthand required a best-effort recovery during serialization.`,
|
|
1304
|
+
property: shorthand,
|
|
1305
|
+
input: "",
|
|
1306
|
+
location: null,
|
|
1307
|
+
conflictingLonghands: Object.freeze([...conflictingLonghands])
|
|
1308
|
+
};
|
|
1309
|
+
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
|
|
1164
1310
|
};
|
|
1165
|
-
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule));
|
|
1311
|
+
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, reportSerializationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule));
|
|
1166
1312
|
return new Proxy(this, {
|
|
1167
1313
|
get(target, property) {
|
|
1168
1314
|
if (typeof property === "string" && arrayIndexPattern.test(property)) return target.item(Number(property)) || void 0;
|
|
@@ -1207,13 +1353,41 @@ var CSSStyleDeclaration = class {
|
|
|
1207
1353
|
const stringPriority = priority === null ? "" : `${priority}`;
|
|
1208
1354
|
this.#block.setProperty(stringName, stringValue, stringPriority);
|
|
1209
1355
|
}
|
|
1356
|
+
/** Apply ordered declaration mutations through one engine boundary crossing. */
|
|
1357
|
+
applyMutations(mutations) {
|
|
1358
|
+
requireArguments(arguments.length, 1, "CSSStyleDeclaration", "applyMutations");
|
|
1359
|
+
if (!Array.isArray(mutations)) throw new TypeError("CSSStyleDeclaration.applyMutations requires an array.");
|
|
1360
|
+
const normalized = [];
|
|
1361
|
+
for (let index = 0; index < mutations.length; index += 1) {
|
|
1362
|
+
const mutation = mutations[index];
|
|
1363
|
+
if (typeof mutation !== "object" || mutation === null) throw new TypeError(`Declaration mutation at index ${index} must be an object.`);
|
|
1364
|
+
if (mutation.kind !== "set" && mutation.kind !== "remove") throw new TypeError(`Declaration mutation at index ${index} has an invalid kind.`);
|
|
1365
|
+
if (typeof mutation.property !== "string") throw new TypeError(`Declaration mutation at index ${index} requires a string property.`);
|
|
1366
|
+
if (mutation.kind === "remove") {
|
|
1367
|
+
normalized.push({
|
|
1368
|
+
kind: "remove",
|
|
1369
|
+
property: mutation.property
|
|
1370
|
+
});
|
|
1371
|
+
continue;
|
|
1372
|
+
}
|
|
1373
|
+
if (typeof mutation.value !== "string" && mutation.value !== null) throw new TypeError(`Declaration mutation at index ${index} requires a string or null value.`);
|
|
1374
|
+
if (mutation.priority !== void 0 && mutation.priority !== null && typeof mutation.priority !== "string") throw new TypeError(`Declaration mutation at index ${index} requires a string priority.`);
|
|
1375
|
+
normalized.push({
|
|
1376
|
+
kind: "set",
|
|
1377
|
+
property: mutation.property,
|
|
1378
|
+
value: mutation.value ?? "",
|
|
1379
|
+
priority: mutation.priority ?? ""
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
return this.#block.applyMutations(normalized);
|
|
1383
|
+
}
|
|
1210
1384
|
removeProperty(name) {
|
|
1211
1385
|
requireArguments(arguments.length, 1, "CSSStyleDeclaration", "removeProperty");
|
|
1212
1386
|
return this.#block.removeProperty(`${name}`);
|
|
1213
1387
|
}
|
|
1214
1388
|
/** @internal */
|
|
1215
|
-
serializeSafe(indent) {
|
|
1216
|
-
return this.#block.serialize(true, indent, "\n");
|
|
1389
|
+
serializeSafe(indent, strict = false) {
|
|
1390
|
+
return this.#block.serialize(true, indent, "\n", strict);
|
|
1217
1391
|
}
|
|
1218
1392
|
};
|
|
1219
1393
|
/** A live `@font-face` descriptor rule. */
|
|
@@ -1702,26 +1876,23 @@ function replaceGroupingRules(group, rules) {
|
|
|
1702
1876
|
function attachRuleTree(rule, parentRule, parentStyleSheet) {
|
|
1703
1877
|
ruleTree.attach(rule, parentRule, parentStyleSheet);
|
|
1704
1878
|
}
|
|
1705
|
-
function
|
|
1706
|
-
return safeSerializer.serialize(rule);
|
|
1707
|
-
}
|
|
1708
|
-
function describeRuleSafe(rule) {
|
|
1879
|
+
function describeRuleSafe(rule, strict) {
|
|
1709
1880
|
if (rule instanceof CSSStyleRule) return {
|
|
1710
1881
|
kind: "block",
|
|
1711
1882
|
header: rule.selectorText,
|
|
1712
|
-
declarations: rule.style.serializeSafe(" "),
|
|
1883
|
+
declarations: rule.style.serializeSafe(" ", strict),
|
|
1713
1884
|
children: ruleTree.children(rule)
|
|
1714
1885
|
};
|
|
1715
1886
|
if (rule instanceof CSSNestedDeclarations || rule instanceof CSSFunctionDeclarations) return {
|
|
1716
1887
|
kind: "declarations",
|
|
1717
|
-
declarations: rule.style.serializeSafe("")
|
|
1888
|
+
declarations: rule.style.serializeSafe("", strict)
|
|
1718
1889
|
};
|
|
1719
1890
|
if (rule instanceof CSSFontFaceRule || rule instanceof CSSMarginRule || rule instanceof CSSPositionTryRule || rule instanceof CSSKeyframeRule) {
|
|
1720
1891
|
const blockIndex = rule.cssText.indexOf("{");
|
|
1721
1892
|
return {
|
|
1722
1893
|
kind: "block",
|
|
1723
1894
|
header: rule.cssText.slice(0, blockIndex).trimEnd(),
|
|
1724
|
-
declarations: rule.style.serializeSafe(" ")
|
|
1895
|
+
declarations: rule.style.serializeSafe(" ", strict)
|
|
1725
1896
|
};
|
|
1726
1897
|
}
|
|
1727
1898
|
if (rule instanceof CSSKeyframesRule) return {
|
|
@@ -1732,7 +1903,7 @@ function describeRuleSafe(rule) {
|
|
|
1732
1903
|
if (rule instanceof CSSPageRule) return {
|
|
1733
1904
|
kind: "block",
|
|
1734
1905
|
header: `@page${rule.selectorText === "" ? "" : ` ${rule.selectorText}`}`,
|
|
1735
|
-
declarations: rule.style.serializeSafe(" "),
|
|
1906
|
+
declarations: rule.style.serializeSafe(" ", strict),
|
|
1736
1907
|
children: ruleTree.children(rule)
|
|
1737
1908
|
};
|
|
1738
1909
|
if (!(rule instanceof CSSGroupingRule)) return {
|
|
@@ -2127,9 +2298,13 @@ var CSSStyleSheet = class {
|
|
|
2127
2298
|
}
|
|
2128
2299
|
/** Serialize current state as reparsable CSS without mutating live objects. */
|
|
2129
2300
|
serialize() {
|
|
2130
|
-
return this.#rules
|
|
2301
|
+
return safeSerializer.serializeMany(this.#rules);
|
|
2302
|
+
}
|
|
2303
|
+
/** Serialize current state only when its CSS semantics can be preserved exactly. */
|
|
2304
|
+
serializeStrict() {
|
|
2305
|
+
return strictSerializer.serializeMany(this.#rules);
|
|
2131
2306
|
}
|
|
2132
|
-
/** Drain opt-in mutation diagnostics without affecting CSSOM behavior. */
|
|
2307
|
+
/** Drain opt-in mutation and serialization diagnostics without affecting CSSOM behavior. */
|
|
2133
2308
|
takeDiagnostics() {
|
|
2134
2309
|
if (!this.#diagnostics) return [];
|
|
2135
2310
|
return this.#diagnostics.splice(0);
|
|
@@ -2180,6 +2355,7 @@ exports.CSSStyleSheet = CSSStyleSheet;
|
|
|
2180
2355
|
exports.CSSSupportsRule = CSSSupportsRule;
|
|
2181
2356
|
exports.CSSViewTransitionRule = CSSViewTransitionRule;
|
|
2182
2357
|
exports.MediaList = MediaList;
|
|
2358
|
+
exports.SheetOMSerializationError = SheetOMSerializationError;
|
|
2183
2359
|
exports.parseStyleSheet = parseStyleSheet;
|
|
2184
2360
|
|
|
2185
2361
|
//# sourceMappingURL=index.cjs.map
|