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/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
//#region src/diagnostics.d.ts
|
|
2
2
|
/** Stable machine-readable codes emitted by opt-in mutation diagnostics. */
|
|
3
|
-
type
|
|
3
|
+
type SheetOMMutationDiagnosticCode = "INVALID_PRIORITY" | "INVALID_PROPERTY_VALUE" | "UNSUPPORTED_SHORTHAND_VALUE";
|
|
4
|
+
type SheetOMSerializationDiagnosticCode = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
5
|
+
type SheetOMDiagnosticCode = SheetOMMutationDiagnosticCode | SheetOMSerializationDiagnosticCode;
|
|
6
|
+
/** A structured explanation for an ignored mutation. */
|
|
7
|
+
interface SheetOMMutationDiagnostic {
|
|
8
|
+
code: SheetOMMutationDiagnosticCode;
|
|
9
|
+
severity: "warning";
|
|
10
|
+
operation: "setProperty";
|
|
11
|
+
message: string;
|
|
12
|
+
property: string;
|
|
13
|
+
input: string;
|
|
14
|
+
location: null;
|
|
15
|
+
}
|
|
16
|
+
/** A structured explanation for a best-effort serialization recovery. */
|
|
17
|
+
interface SheetOMSerializationDiagnostic {
|
|
18
|
+
code: SheetOMSerializationDiagnosticCode;
|
|
19
|
+
severity: "warning";
|
|
20
|
+
operation: "serialize";
|
|
21
|
+
message: string;
|
|
22
|
+
property: string;
|
|
23
|
+
input: "";
|
|
24
|
+
location: null;
|
|
25
|
+
conflictingLonghands: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
type SheetOMDiagnostic = SheetOMMutationDiagnostic | SheetOMSerializationDiagnostic;
|
|
4
28
|
//#endregion
|
|
5
29
|
//#region src/generated/css-style-declaration-properties.d.ts
|
|
6
30
|
/** Named CSS properties supported by the pinned Chromium compatibility baseline. */
|
|
@@ -728,17 +752,36 @@ interface SheetOMResourceBudget {
|
|
|
728
752
|
maxDeclarationsPerBlock?: number;
|
|
729
753
|
}
|
|
730
754
|
//#endregion
|
|
755
|
+
//#region src/serialization-error.d.ts
|
|
756
|
+
type SheetOMSerializationErrorCode = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
757
|
+
/** A reparsable stylesheet cannot faithfully represent the current CSSOM state. */
|
|
758
|
+
declare class SheetOMSerializationError extends Error {
|
|
759
|
+
readonly code: SheetOMSerializationErrorCode;
|
|
760
|
+
readonly shorthand: string;
|
|
761
|
+
readonly conflictingLonghands: readonly string[];
|
|
762
|
+
constructor(shorthand: string, conflictingLonghands: readonly string[], options?: ErrorOptions);
|
|
763
|
+
}
|
|
764
|
+
//#endregion
|
|
731
765
|
//#region src/index.d.ts
|
|
732
|
-
/**
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
severity: "warning";
|
|
736
|
-
operation: "setProperty";
|
|
737
|
-
message: string;
|
|
766
|
+
/** One ordered declaration mutation executed by SheetOM's engine extension. */
|
|
767
|
+
type CSSDeclarationMutation = {
|
|
768
|
+
kind: "set";
|
|
738
769
|
property: string;
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
}
|
|
770
|
+
value: string | null;
|
|
771
|
+
priority?: string | null;
|
|
772
|
+
} | {
|
|
773
|
+
kind: "remove";
|
|
774
|
+
property: string;
|
|
775
|
+
};
|
|
776
|
+
/** The result at the matching index of an ordered declaration mutation batch. */
|
|
777
|
+
type CSSDeclarationMutationResult = {
|
|
778
|
+
kind: "set";
|
|
779
|
+
accepted: boolean;
|
|
780
|
+
diagnostic: SheetOMDiagnostic | null;
|
|
781
|
+
} | {
|
|
782
|
+
kind: "remove";
|
|
783
|
+
value: string;
|
|
784
|
+
};
|
|
742
785
|
/** Options for a constructed SheetOM stylesheet. */
|
|
743
786
|
interface CSSStyleSheetOptions {
|
|
744
787
|
baseURL?: string;
|
|
@@ -954,6 +997,8 @@ declare class CSSStyleDeclaration {
|
|
|
954
997
|
getPropertyValue(name: string): string;
|
|
955
998
|
getPropertyPriority(name: string): string;
|
|
956
999
|
setProperty(name: string, value: string | null, priority?: string): void;
|
|
1000
|
+
/** Apply ordered declaration mutations through one engine boundary crossing. */
|
|
1001
|
+
applyMutations(mutations: readonly CSSDeclarationMutation[]): CSSDeclarationMutationResult[];
|
|
957
1002
|
removeProperty(name: string): string;
|
|
958
1003
|
}
|
|
959
1004
|
/** A live `@font-face` descriptor rule. */
|
|
@@ -1126,11 +1171,13 @@ declare class CSSStyleSheet {
|
|
|
1126
1171
|
replace(cssText: string): Promise<CSSStyleSheet>;
|
|
1127
1172
|
/** Serialize current state as reparsable CSS without mutating live objects. */
|
|
1128
1173
|
serialize(): string;
|
|
1129
|
-
/**
|
|
1174
|
+
/** Serialize current state only when its CSS semantics can be preserved exactly. */
|
|
1175
|
+
serializeStrict(): string;
|
|
1176
|
+
/** Drain opt-in mutation and serialization diagnostics without affecting CSSOM behavior. */
|
|
1130
1177
|
takeDiagnostics(): SheetOMDiagnostic[];
|
|
1131
1178
|
}
|
|
1132
1179
|
/** Forgivingly parse an existing regular stylesheet without loading imports. */
|
|
1133
1180
|
declare function parseStyleSheet(cssText: string, options?: ParseStyleSheetOptions): CSSStyleSheet;
|
|
1134
1181
|
//#endregion
|
|
1135
|
-
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSStyleSheetOptions, CSSSupportsRule, CSSViewTransitionRule, FunctionParameter, MediaList, ParseStyleSheetOptions, SheetOMDiagnostic, type SheetOMDiagnosticCode, type SheetOMResourceBudget, parseStyleSheet };
|
|
1182
|
+
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSDeclarationMutation, CSSDeclarationMutationResult, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSStyleSheetOptions, CSSSupportsRule, CSSViewTransitionRule, FunctionParameter, MediaList, ParseStyleSheetOptions, type SheetOMDiagnostic, type SheetOMDiagnosticCode, type SheetOMMutationDiagnostic, type SheetOMMutationDiagnosticCode, type SheetOMResourceBudget, type SheetOMSerializationDiagnostic, type SheetOMSerializationDiagnosticCode, SheetOMSerializationError, type SheetOMSerializationErrorCode, parseStyleSheet };
|
|
1136
1183
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
//#region src/diagnostics.d.ts
|
|
2
2
|
/** Stable machine-readable codes emitted by opt-in mutation diagnostics. */
|
|
3
|
-
type
|
|
3
|
+
type SheetOMMutationDiagnosticCode = "INVALID_PRIORITY" | "INVALID_PROPERTY_VALUE" | "UNSUPPORTED_SHORTHAND_VALUE";
|
|
4
|
+
type SheetOMSerializationDiagnosticCode = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
5
|
+
type SheetOMDiagnosticCode = SheetOMMutationDiagnosticCode | SheetOMSerializationDiagnosticCode;
|
|
6
|
+
/** A structured explanation for an ignored mutation. */
|
|
7
|
+
interface SheetOMMutationDiagnostic {
|
|
8
|
+
code: SheetOMMutationDiagnosticCode;
|
|
9
|
+
severity: "warning";
|
|
10
|
+
operation: "setProperty";
|
|
11
|
+
message: string;
|
|
12
|
+
property: string;
|
|
13
|
+
input: string;
|
|
14
|
+
location: null;
|
|
15
|
+
}
|
|
16
|
+
/** A structured explanation for a best-effort serialization recovery. */
|
|
17
|
+
interface SheetOMSerializationDiagnostic {
|
|
18
|
+
code: SheetOMSerializationDiagnosticCode;
|
|
19
|
+
severity: "warning";
|
|
20
|
+
operation: "serialize";
|
|
21
|
+
message: string;
|
|
22
|
+
property: string;
|
|
23
|
+
input: "";
|
|
24
|
+
location: null;
|
|
25
|
+
conflictingLonghands: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
type SheetOMDiagnostic = SheetOMMutationDiagnostic | SheetOMSerializationDiagnostic;
|
|
4
28
|
//#endregion
|
|
5
29
|
//#region src/generated/css-style-declaration-properties.d.ts
|
|
6
30
|
/** Named CSS properties supported by the pinned Chromium compatibility baseline. */
|
|
@@ -728,17 +752,36 @@ interface SheetOMResourceBudget {
|
|
|
728
752
|
maxDeclarationsPerBlock?: number;
|
|
729
753
|
}
|
|
730
754
|
//#endregion
|
|
755
|
+
//#region src/serialization-error.d.ts
|
|
756
|
+
type SheetOMSerializationErrorCode = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
757
|
+
/** A reparsable stylesheet cannot faithfully represent the current CSSOM state. */
|
|
758
|
+
declare class SheetOMSerializationError extends Error {
|
|
759
|
+
readonly code: SheetOMSerializationErrorCode;
|
|
760
|
+
readonly shorthand: string;
|
|
761
|
+
readonly conflictingLonghands: readonly string[];
|
|
762
|
+
constructor(shorthand: string, conflictingLonghands: readonly string[], options?: ErrorOptions);
|
|
763
|
+
}
|
|
764
|
+
//#endregion
|
|
731
765
|
//#region src/index.d.ts
|
|
732
|
-
/**
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
severity: "warning";
|
|
736
|
-
operation: "setProperty";
|
|
737
|
-
message: string;
|
|
766
|
+
/** One ordered declaration mutation executed by SheetOM's engine extension. */
|
|
767
|
+
type CSSDeclarationMutation = {
|
|
768
|
+
kind: "set";
|
|
738
769
|
property: string;
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
}
|
|
770
|
+
value: string | null;
|
|
771
|
+
priority?: string | null;
|
|
772
|
+
} | {
|
|
773
|
+
kind: "remove";
|
|
774
|
+
property: string;
|
|
775
|
+
};
|
|
776
|
+
/** The result at the matching index of an ordered declaration mutation batch. */
|
|
777
|
+
type CSSDeclarationMutationResult = {
|
|
778
|
+
kind: "set";
|
|
779
|
+
accepted: boolean;
|
|
780
|
+
diagnostic: SheetOMDiagnostic | null;
|
|
781
|
+
} | {
|
|
782
|
+
kind: "remove";
|
|
783
|
+
value: string;
|
|
784
|
+
};
|
|
742
785
|
/** Options for a constructed SheetOM stylesheet. */
|
|
743
786
|
interface CSSStyleSheetOptions {
|
|
744
787
|
baseURL?: string;
|
|
@@ -954,6 +997,8 @@ declare class CSSStyleDeclaration {
|
|
|
954
997
|
getPropertyValue(name: string): string;
|
|
955
998
|
getPropertyPriority(name: string): string;
|
|
956
999
|
setProperty(name: string, value: string | null, priority?: string): void;
|
|
1000
|
+
/** Apply ordered declaration mutations through one engine boundary crossing. */
|
|
1001
|
+
applyMutations(mutations: readonly CSSDeclarationMutation[]): CSSDeclarationMutationResult[];
|
|
957
1002
|
removeProperty(name: string): string;
|
|
958
1003
|
}
|
|
959
1004
|
/** A live `@font-face` descriptor rule. */
|
|
@@ -1126,11 +1171,13 @@ declare class CSSStyleSheet {
|
|
|
1126
1171
|
replace(cssText: string): Promise<CSSStyleSheet>;
|
|
1127
1172
|
/** Serialize current state as reparsable CSS without mutating live objects. */
|
|
1128
1173
|
serialize(): string;
|
|
1129
|
-
/**
|
|
1174
|
+
/** Serialize current state only when its CSS semantics can be preserved exactly. */
|
|
1175
|
+
serializeStrict(): string;
|
|
1176
|
+
/** Drain opt-in mutation and serialization diagnostics without affecting CSSOM behavior. */
|
|
1130
1177
|
takeDiagnostics(): SheetOMDiagnostic[];
|
|
1131
1178
|
}
|
|
1132
1179
|
/** Forgivingly parse an existing regular stylesheet without loading imports. */
|
|
1133
1180
|
declare function parseStyleSheet(cssText: string, options?: ParseStyleSheetOptions): CSSStyleSheet;
|
|
1134
1181
|
//#endregion
|
|
1135
|
-
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSStyleSheetOptions, CSSSupportsRule, CSSViewTransitionRule, FunctionParameter, MediaList, ParseStyleSheetOptions, SheetOMDiagnostic, type SheetOMDiagnosticCode, type SheetOMResourceBudget, parseStyleSheet };
|
|
1182
|
+
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSDeclarationMutation, CSSDeclarationMutationResult, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSStyleSheetOptions, CSSSupportsRule, CSSViewTransitionRule, FunctionParameter, MediaList, ParseStyleSheetOptions, type SheetOMDiagnostic, type SheetOMDiagnosticCode, type SheetOMMutationDiagnostic, type SheetOMMutationDiagnosticCode, type SheetOMResourceBudget, type SheetOMSerializationDiagnostic, type SheetOMSerializationDiagnosticCode, SheetOMSerializationError, type SheetOMSerializationErrorCode, parseStyleSheet };
|
|
1136
1183
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
//#endregion
|
|
5
5
|
//#region src/internal/engine-binding.ts
|
|
6
6
|
const expectedEngineAbiIdentity = Object.freeze({
|
|
7
|
-
abiVersion:
|
|
8
|
-
sheetomVersion: "0.1.0
|
|
9
|
-
syntaxEngineSetSha256: "
|
|
7
|
+
abiVersion: 3,
|
|
8
|
+
sheetomVersion: "0.1.0",
|
|
9
|
+
syntaxEngineSetSha256: "31990c26ede4e17c3a8941027f92b2be96a167984d0ab6529e724c3d6126be50"
|
|
10
10
|
});
|
|
11
11
|
var SheetOMEngineBindingError = class extends Error {
|
|
12
12
|
code;
|
|
@@ -90,16 +90,47 @@ function limitValue(value, name, fallback, maximum = maximumUnsignedLong) {
|
|
|
90
90
|
throw new RangeError(`${name} must be an integer between 0 and ${maximum}`);
|
|
91
91
|
}
|
|
92
92
|
//#endregion
|
|
93
|
+
//#region src/serialization-error.ts
|
|
94
|
+
/** A reparsable stylesheet cannot faithfully represent the current CSSOM state. */
|
|
95
|
+
var SheetOMSerializationError = class extends Error {
|
|
96
|
+
code;
|
|
97
|
+
shorthand;
|
|
98
|
+
conflictingLonghands;
|
|
99
|
+
constructor(shorthand, conflictingLonghands, options) {
|
|
100
|
+
super(`SheetOM cannot serialize the pending ${shorthand} shorthand without changing its semantics.`, options);
|
|
101
|
+
this.name = "SheetOMSerializationError";
|
|
102
|
+
this.code = "UNREPRESENTABLE_PENDING_SHORTHAND";
|
|
103
|
+
this.shorthand = shorthand;
|
|
104
|
+
this.conflictingLonghands = Object.freeze([...conflictingLonghands]);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const unrepresentablePendingShorthandPattern = /^SHEETOM_UNREPRESENTABLE_PENDING_SHORTHAND: shorthand=([^;]+); conflicting=([a-z0-9,-]+)$/u;
|
|
108
|
+
function serializationErrorFrom(error) {
|
|
109
|
+
if (!(error instanceof Error)) return null;
|
|
110
|
+
const match = unrepresentablePendingShorthandPattern.exec(error.message);
|
|
111
|
+
if (!match) return null;
|
|
112
|
+
const shorthand = match[1];
|
|
113
|
+
const conflicts = match[2];
|
|
114
|
+
if (!shorthand || !conflicts) return null;
|
|
115
|
+
return new SheetOMSerializationError(shorthand, conflicts.split(","), { cause: error });
|
|
116
|
+
}
|
|
117
|
+
function rethrowSerializationError(error) {
|
|
118
|
+
const serializationError = serializationErrorFrom(error);
|
|
119
|
+
if (serializationError) throw serializationError;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
93
122
|
//#region src/internal/native-declaration-block.ts
|
|
94
123
|
/** Thin JS ownership boundary around the Rust declaration state machine. */
|
|
95
124
|
var NativeDeclarationBlock = class {
|
|
96
125
|
#state;
|
|
97
126
|
#reportDiagnostic;
|
|
127
|
+
#reportSerializationDiagnostic;
|
|
98
128
|
#reservedNestingDepth;
|
|
99
129
|
#observableCache;
|
|
100
130
|
#serializationCache = /* @__PURE__ */ new Map();
|
|
101
|
-
constructor(reportDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0) {
|
|
131
|
+
constructor(reportDiagnostic, reportSerializationDiagnostic, context = "style", resourceBudget = defaultResourceBudget, reservedNestingDepth = () => 0) {
|
|
102
132
|
this.#reportDiagnostic = reportDiagnostic;
|
|
133
|
+
this.#reportSerializationDiagnostic = reportSerializationDiagnostic;
|
|
103
134
|
this.#reservedNestingDepth = reservedNestingDepth;
|
|
104
135
|
this.#state = engineBinding.createDeclarationState(context, ...nativeBudgetArguments(resourceBudget));
|
|
105
136
|
}
|
|
@@ -131,9 +162,59 @@ var NativeDeclarationBlock = class {
|
|
|
131
162
|
this.#invalidateSerialization();
|
|
132
163
|
return;
|
|
133
164
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
165
|
+
this.#diagnosticForOutcome(outcome, name, value, priority);
|
|
166
|
+
}
|
|
167
|
+
applyMutations(mutations) {
|
|
168
|
+
const kinds = [];
|
|
169
|
+
const properties = [];
|
|
170
|
+
const values = [];
|
|
171
|
+
const priorities = [];
|
|
172
|
+
for (const mutation of mutations) {
|
|
173
|
+
kinds.push(mutation.kind === "set" ? 0 : 1);
|
|
174
|
+
properties.push(mutation.property);
|
|
175
|
+
values.push(mutation.kind === "set" ? mutation.value : "");
|
|
176
|
+
priorities.push(mutation.kind === "set" ? mutation.priority : "");
|
|
177
|
+
}
|
|
178
|
+
let outcomes;
|
|
179
|
+
try {
|
|
180
|
+
outcomes = this.#state.applyMutations(kinds, properties, values, priorities, this.#reservedNestingDepth());
|
|
181
|
+
} catch (error) {
|
|
182
|
+
rethrowResourceBudgetError(error);
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
if (outcomes.length !== mutations.length) throw new Error("SheetOM engine returned an incomplete declaration mutation result.");
|
|
186
|
+
const results = [];
|
|
187
|
+
let mutated = false;
|
|
188
|
+
for (let index = 0; index < outcomes.length; index += 1) {
|
|
189
|
+
const mutation = mutations[index];
|
|
190
|
+
const outcome = outcomes[index];
|
|
191
|
+
if (!mutation || outcome === void 0) throw new Error("SheetOM engine returned a mismatched declaration mutation result.");
|
|
192
|
+
if (mutation.kind === "remove") {
|
|
193
|
+
mutated = true;
|
|
194
|
+
results.push({
|
|
195
|
+
kind: "remove",
|
|
196
|
+
value: outcome
|
|
197
|
+
});
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (outcome === "applied") {
|
|
201
|
+
mutated = true;
|
|
202
|
+
results.push({
|
|
203
|
+
kind: "set",
|
|
204
|
+
accepted: true,
|
|
205
|
+
diagnostic: null
|
|
206
|
+
});
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (!isEngineMutationOutcome(outcome)) throw new Error("SheetOM engine returned an invalid declaration mutation outcome.");
|
|
210
|
+
results.push({
|
|
211
|
+
kind: "set",
|
|
212
|
+
accepted: false,
|
|
213
|
+
diagnostic: this.#diagnosticForOutcome(outcome, mutation.property, mutation.value, mutation.priority)
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (mutated) this.#invalidateSerialization();
|
|
217
|
+
return results;
|
|
137
218
|
}
|
|
138
219
|
removeProperty(name) {
|
|
139
220
|
const removed = this.#state.removeProperty(name);
|
|
@@ -149,19 +230,63 @@ var NativeDeclarationBlock = class {
|
|
|
149
230
|
}
|
|
150
231
|
this.#invalidateSerialization();
|
|
151
232
|
}
|
|
152
|
-
serialize(safe, indent, separator) {
|
|
153
|
-
const cacheKey = `${safe ? "1" : "0"}\0${indent}\0${separator}`;
|
|
233
|
+
serialize(safe, indent, separator, strict = false) {
|
|
234
|
+
const cacheKey = `${safe ? "1" : "0"}${strict ? "1" : "0"}\0${indent}\0${separator}`;
|
|
154
235
|
const cached = this.#serializationCache.get(cacheKey);
|
|
155
|
-
if (cached !== void 0)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
236
|
+
if (cached !== void 0) {
|
|
237
|
+
if (typeof cached === "string") return cached;
|
|
238
|
+
this.#reportSerializationIssues(cached.issues);
|
|
239
|
+
return cached.serialized;
|
|
240
|
+
}
|
|
241
|
+
let result;
|
|
242
|
+
try {
|
|
243
|
+
if (strict) result = this.#state.serializeFormatted(safe, indent, separator);
|
|
244
|
+
else result = parseResilientSerializationResult(this.#state.serializeFormattedResilient(safe, indent, separator));
|
|
245
|
+
} catch (error) {
|
|
246
|
+
rethrowResourceBudgetError(error);
|
|
247
|
+
rethrowSerializationError(error);
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
this.#serializationCache.set(cacheKey, result);
|
|
251
|
+
if (typeof result === "string") return result;
|
|
252
|
+
this.#reportSerializationIssues(result.issues);
|
|
253
|
+
return result.serialized;
|
|
159
254
|
}
|
|
160
255
|
#invalidateSerialization() {
|
|
161
256
|
this.#observableCache = void 0;
|
|
162
257
|
this.#serializationCache.clear();
|
|
163
258
|
}
|
|
259
|
+
#diagnosticForOutcome(outcome, name, value, priority) {
|
|
260
|
+
const normalizedName = name.startsWith("--") ? name : name.toLowerCase();
|
|
261
|
+
const [code, input] = outcome === "invalid-priority" ? ["INVALID_PRIORITY", priority] : outcome === "unsupported-shorthand" ? ["UNSUPPORTED_SHORTHAND_VALUE", value] : ["INVALID_PROPERTY_VALUE", value];
|
|
262
|
+
return this.#reportDiagnostic(code, normalizedName, input);
|
|
263
|
+
}
|
|
264
|
+
#reportSerializationIssues(issues) {
|
|
265
|
+
for (const issue of issues) this.#reportSerializationDiagnostic(issue.shorthand, issue.conflictingLonghands);
|
|
266
|
+
}
|
|
164
267
|
};
|
|
268
|
+
function parseResilientSerializationResult(output) {
|
|
269
|
+
const serialized = output[0];
|
|
270
|
+
if (serialized === void 0 || output.length % 2 === 0) throw new Error("SheetOM engine returned an invalid resilient serialization result.");
|
|
271
|
+
if (output.length === 1) return serialized;
|
|
272
|
+
const issues = [];
|
|
273
|
+
for (let index = 1; index < output.length; index += 2) {
|
|
274
|
+
const shorthand = output[index];
|
|
275
|
+
const conflicts = output[index + 1];
|
|
276
|
+
if (!shorthand || !conflicts) throw new Error("SheetOM engine returned an incomplete resilient serialization issue.");
|
|
277
|
+
issues.push({
|
|
278
|
+
shorthand,
|
|
279
|
+
conflictingLonghands: Object.freeze(conflicts.split(","))
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
serialized,
|
|
284
|
+
issues
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function isEngineMutationOutcome(value) {
|
|
288
|
+
return value === "invalid-name" || value === "invalid-priority" || value === "invalid-value" || value === "unsupported-shorthand";
|
|
289
|
+
}
|
|
165
290
|
function toUnsignedLong$1(value) {
|
|
166
291
|
const numeric = Number(value);
|
|
167
292
|
if (!Number.isFinite(numeric) || numeric === 0) return 0;
|
|
@@ -353,13 +478,20 @@ var Serializer = class {
|
|
|
353
478
|
this.#describe = describe;
|
|
354
479
|
}
|
|
355
480
|
serialize(node) {
|
|
481
|
+
return this.serializeMany([node]);
|
|
482
|
+
}
|
|
483
|
+
serializeMany(nodes) {
|
|
356
484
|
const chunks = [];
|
|
357
|
-
const pending = [
|
|
358
|
-
|
|
359
|
-
node
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
485
|
+
const pending = [];
|
|
486
|
+
for (let index = nodes.length - 1; index >= 0; index -= 1) {
|
|
487
|
+
const node = nodes[index];
|
|
488
|
+
if (node) pending.push({
|
|
489
|
+
kind: "node",
|
|
490
|
+
node,
|
|
491
|
+
depth: 0,
|
|
492
|
+
child: false
|
|
493
|
+
});
|
|
494
|
+
}
|
|
363
495
|
while (pending.length > 0) {
|
|
364
496
|
const frame = pending.pop();
|
|
365
497
|
if (!frame) continue;
|
|
@@ -473,7 +605,8 @@ const ruleTree = new RuleTree((rule, parentRule, parentStyleSheet) => {
|
|
|
473
605
|
parentStyleSheet
|
|
474
606
|
});
|
|
475
607
|
}, (rule) => rule.parentStyleSheet);
|
|
476
|
-
const safeSerializer = new Serializer(describeRuleSafe);
|
|
608
|
+
const safeSerializer = new Serializer((rule) => describeRuleSafe(rule, false));
|
|
609
|
+
const strictSerializer = new Serializer((rule) => describeRuleSafe(rule, true));
|
|
477
610
|
let activeConstructionResourceBudget = defaultResourceBudget;
|
|
478
611
|
function constructWithResourceBudget(factory, resourceBudget) {
|
|
479
612
|
const previous = activeConstructionResourceBudget;
|
|
@@ -1126,19 +1259,32 @@ var CSSStyleDeclaration = class {
|
|
|
1126
1259
|
this.parentRule = parentRule;
|
|
1127
1260
|
lockOwnProperties(this, "parentRule");
|
|
1128
1261
|
const reportDeclarationDiagnostic = (code, property, input) => {
|
|
1129
|
-
const
|
|
1130
|
-
const unsupportedShorthand = code === "UNSUPPORTED_SHORTHAND_VALUE";
|
|
1131
|
-
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)({
|
|
1262
|
+
const diagnostic = {
|
|
1132
1263
|
code,
|
|
1133
1264
|
severity: "warning",
|
|
1134
1265
|
operation: "setProperty",
|
|
1135
|
-
message:
|
|
1266
|
+
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}.`,
|
|
1136
1267
|
property,
|
|
1137
1268
|
input,
|
|
1138
1269
|
location: null
|
|
1139
|
-
}
|
|
1270
|
+
};
|
|
1271
|
+
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
|
|
1272
|
+
return diagnostic;
|
|
1273
|
+
};
|
|
1274
|
+
const reportSerializationDiagnostic = (shorthand, conflictingLonghands) => {
|
|
1275
|
+
const diagnostic = {
|
|
1276
|
+
code: "UNREPRESENTABLE_PENDING_SHORTHAND",
|
|
1277
|
+
severity: "warning",
|
|
1278
|
+
operation: "serialize",
|
|
1279
|
+
message: `The pending ${shorthand} shorthand required a best-effort recovery during serialization.`,
|
|
1280
|
+
property: shorthand,
|
|
1281
|
+
input: "",
|
|
1282
|
+
location: null,
|
|
1283
|
+
conflictingLonghands: Object.freeze([...conflictingLonghands])
|
|
1284
|
+
};
|
|
1285
|
+
(ruleDiagnostics.get(this.parentRule) ?? ignoreDiagnostic)(diagnostic);
|
|
1140
1286
|
};
|
|
1141
|
-
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule));
|
|
1287
|
+
this.#block = new NativeDeclarationBlock(reportDeclarationDiagnostic, reportSerializationDiagnostic, parentRule instanceof CSSFontFaceRule ? "font-face" : parentRule instanceof CSSFunctionDeclarations ? "function" : "style", ruleResourceBudgets.get(parentRule) ?? defaultResourceBudget, () => declarationSerializationDepth(parentRule));
|
|
1142
1288
|
return new Proxy(this, {
|
|
1143
1289
|
get(target, property) {
|
|
1144
1290
|
if (typeof property === "string" && arrayIndexPattern.test(property)) return target.item(Number(property)) || void 0;
|
|
@@ -1183,13 +1329,41 @@ var CSSStyleDeclaration = class {
|
|
|
1183
1329
|
const stringPriority = priority === null ? "" : `${priority}`;
|
|
1184
1330
|
this.#block.setProperty(stringName, stringValue, stringPriority);
|
|
1185
1331
|
}
|
|
1332
|
+
/** Apply ordered declaration mutations through one engine boundary crossing. */
|
|
1333
|
+
applyMutations(mutations) {
|
|
1334
|
+
requireArguments(arguments.length, 1, "CSSStyleDeclaration", "applyMutations");
|
|
1335
|
+
if (!Array.isArray(mutations)) throw new TypeError("CSSStyleDeclaration.applyMutations requires an array.");
|
|
1336
|
+
const normalized = [];
|
|
1337
|
+
for (let index = 0; index < mutations.length; index += 1) {
|
|
1338
|
+
const mutation = mutations[index];
|
|
1339
|
+
if (typeof mutation !== "object" || mutation === null) throw new TypeError(`Declaration mutation at index ${index} must be an object.`);
|
|
1340
|
+
if (mutation.kind !== "set" && mutation.kind !== "remove") throw new TypeError(`Declaration mutation at index ${index} has an invalid kind.`);
|
|
1341
|
+
if (typeof mutation.property !== "string") throw new TypeError(`Declaration mutation at index ${index} requires a string property.`);
|
|
1342
|
+
if (mutation.kind === "remove") {
|
|
1343
|
+
normalized.push({
|
|
1344
|
+
kind: "remove",
|
|
1345
|
+
property: mutation.property
|
|
1346
|
+
});
|
|
1347
|
+
continue;
|
|
1348
|
+
}
|
|
1349
|
+
if (typeof mutation.value !== "string" && mutation.value !== null) throw new TypeError(`Declaration mutation at index ${index} requires a string or null value.`);
|
|
1350
|
+
if (mutation.priority !== void 0 && mutation.priority !== null && typeof mutation.priority !== "string") throw new TypeError(`Declaration mutation at index ${index} requires a string priority.`);
|
|
1351
|
+
normalized.push({
|
|
1352
|
+
kind: "set",
|
|
1353
|
+
property: mutation.property,
|
|
1354
|
+
value: mutation.value ?? "",
|
|
1355
|
+
priority: mutation.priority ?? ""
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
return this.#block.applyMutations(normalized);
|
|
1359
|
+
}
|
|
1186
1360
|
removeProperty(name) {
|
|
1187
1361
|
requireArguments(arguments.length, 1, "CSSStyleDeclaration", "removeProperty");
|
|
1188
1362
|
return this.#block.removeProperty(`${name}`);
|
|
1189
1363
|
}
|
|
1190
1364
|
/** @internal */
|
|
1191
|
-
serializeSafe(indent) {
|
|
1192
|
-
return this.#block.serialize(true, indent, "\n");
|
|
1365
|
+
serializeSafe(indent, strict = false) {
|
|
1366
|
+
return this.#block.serialize(true, indent, "\n", strict);
|
|
1193
1367
|
}
|
|
1194
1368
|
};
|
|
1195
1369
|
/** A live `@font-face` descriptor rule. */
|
|
@@ -1678,26 +1852,23 @@ function replaceGroupingRules(group, rules) {
|
|
|
1678
1852
|
function attachRuleTree(rule, parentRule, parentStyleSheet) {
|
|
1679
1853
|
ruleTree.attach(rule, parentRule, parentStyleSheet);
|
|
1680
1854
|
}
|
|
1681
|
-
function
|
|
1682
|
-
return safeSerializer.serialize(rule);
|
|
1683
|
-
}
|
|
1684
|
-
function describeRuleSafe(rule) {
|
|
1855
|
+
function describeRuleSafe(rule, strict) {
|
|
1685
1856
|
if (rule instanceof CSSStyleRule) return {
|
|
1686
1857
|
kind: "block",
|
|
1687
1858
|
header: rule.selectorText,
|
|
1688
|
-
declarations: rule.style.serializeSafe(" "),
|
|
1859
|
+
declarations: rule.style.serializeSafe(" ", strict),
|
|
1689
1860
|
children: ruleTree.children(rule)
|
|
1690
1861
|
};
|
|
1691
1862
|
if (rule instanceof CSSNestedDeclarations || rule instanceof CSSFunctionDeclarations) return {
|
|
1692
1863
|
kind: "declarations",
|
|
1693
|
-
declarations: rule.style.serializeSafe("")
|
|
1864
|
+
declarations: rule.style.serializeSafe("", strict)
|
|
1694
1865
|
};
|
|
1695
1866
|
if (rule instanceof CSSFontFaceRule || rule instanceof CSSMarginRule || rule instanceof CSSPositionTryRule || rule instanceof CSSKeyframeRule) {
|
|
1696
1867
|
const blockIndex = rule.cssText.indexOf("{");
|
|
1697
1868
|
return {
|
|
1698
1869
|
kind: "block",
|
|
1699
1870
|
header: rule.cssText.slice(0, blockIndex).trimEnd(),
|
|
1700
|
-
declarations: rule.style.serializeSafe(" ")
|
|
1871
|
+
declarations: rule.style.serializeSafe(" ", strict)
|
|
1701
1872
|
};
|
|
1702
1873
|
}
|
|
1703
1874
|
if (rule instanceof CSSKeyframesRule) return {
|
|
@@ -1708,7 +1879,7 @@ function describeRuleSafe(rule) {
|
|
|
1708
1879
|
if (rule instanceof CSSPageRule) return {
|
|
1709
1880
|
kind: "block",
|
|
1710
1881
|
header: `@page${rule.selectorText === "" ? "" : ` ${rule.selectorText}`}`,
|
|
1711
|
-
declarations: rule.style.serializeSafe(" "),
|
|
1882
|
+
declarations: rule.style.serializeSafe(" ", strict),
|
|
1712
1883
|
children: ruleTree.children(rule)
|
|
1713
1884
|
};
|
|
1714
1885
|
if (!(rule instanceof CSSGroupingRule)) return {
|
|
@@ -2103,9 +2274,13 @@ var CSSStyleSheet = class {
|
|
|
2103
2274
|
}
|
|
2104
2275
|
/** Serialize current state as reparsable CSS without mutating live objects. */
|
|
2105
2276
|
serialize() {
|
|
2106
|
-
return this.#rules
|
|
2277
|
+
return safeSerializer.serializeMany(this.#rules);
|
|
2278
|
+
}
|
|
2279
|
+
/** Serialize current state only when its CSS semantics can be preserved exactly. */
|
|
2280
|
+
serializeStrict() {
|
|
2281
|
+
return strictSerializer.serializeMany(this.#rules);
|
|
2107
2282
|
}
|
|
2108
|
-
/** Drain opt-in mutation diagnostics without affecting CSSOM behavior. */
|
|
2283
|
+
/** Drain opt-in mutation and serialization diagnostics without affecting CSSOM behavior. */
|
|
2109
2284
|
takeDiagnostics() {
|
|
2110
2285
|
if (!this.#diagnostics) return [];
|
|
2111
2286
|
return this.#diagnostics.splice(0);
|
|
@@ -2123,6 +2298,6 @@ function parseStyleSheet(cssText, options = {}) {
|
|
|
2123
2298
|
return sheet;
|
|
2124
2299
|
}
|
|
2125
2300
|
//#endregion
|
|
2126
|
-
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSSupportsRule, CSSViewTransitionRule, MediaList, parseStyleSheet };
|
|
2301
|
+
export { CSSConditionRule, CSSContainerRule, CSSCounterStyleRule, CSSFontFaceRule, CSSFontFeatureValuesMap, CSSFontFeatureValuesRule, CSSFontPaletteValuesRule, CSSFunctionDeclarations, CSSFunctionDescriptors, CSSFunctionRule, CSSGroupingRule, CSSImportRule, CSSKeyframeRule, CSSKeyframesRule, CSSLayerBlockRule, CSSLayerStatementRule, CSSMarginRule, CSSMediaRule, CSSNamespaceRule, CSSNestedDeclarations, CSSPageRule, CSSPositionTryRule, CSSPropertyRule, CSSRule, CSSRuleList, CSSScopeRule, CSSStartingStyleRule, CSSStyleDeclaration, CSSStyleRule, CSSStyleSheet, CSSSupportsRule, CSSViewTransitionRule, MediaList, SheetOMSerializationError, parseStyleSheet };
|
|
2127
2302
|
|
|
2128
2303
|
//# sourceMappingURL=index.js.map
|