sheetom 0.1.0-rc.0 → 0.1.0-rc.2
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 +28 -8
- package/compatibility/baselines/0.1.0-rc.1.json +108 -0
- package/compatibility/baselines/0.1.0-rc.2.json +142 -0
- package/compatibility/schemas/compatibility-report.schema.json +62 -4
- package/dist/index.cjs +313 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +313 -38
- package/dist/index.js.map +1 -1
- package/docs/api.md +15 -1
- package/docs/releasing.md +44 -54
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -9,9 +9,7 @@ not implement the DOM, cascade, selector matching, layout, or computed styles.
|
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
`0.1.0-rc.0` under the `next` dist-tag after the complete conformance gate
|
|
14
|
-
passes. Once published:
|
|
12
|
+
Install the current release candidate from the `next` dist-tag:
|
|
15
13
|
|
|
16
14
|
```sh
|
|
17
15
|
npm install sheetom@next
|
|
@@ -59,9 +57,10 @@ Constructed sheets follow browser replacement behavior and strip `@import`.
|
|
|
59
57
|
`parseStyleSheet` creates a regular authoring sheet and preserves valid imports
|
|
60
58
|
without loading them.
|
|
61
59
|
|
|
62
|
-
## Recovered values and
|
|
60
|
+
## Recovered values and reparsable serialization
|
|
63
61
|
|
|
64
|
-
SheetOM distinguishes
|
|
62
|
+
SheetOM distinguishes browser-facing CSSOM text from reparsable stylesheet
|
|
63
|
+
output. Chromium
|
|
65
64
|
accepts some values using CSS Syntax end-of-input recovery while preserving the
|
|
66
65
|
unclosed input in `getPropertyValue()` and `cssText`:
|
|
67
66
|
|
|
@@ -82,9 +81,25 @@ sheet.serialize();
|
|
|
82
81
|
// reparsable CSS with the missing syntax repaired
|
|
83
82
|
```
|
|
84
83
|
|
|
84
|
+
The three text surfaces have distinct contracts:
|
|
85
|
+
|
|
86
|
+
| Surface | Contract |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `rule.style.cssText` | Browser-compatible observable declaration text, including accepted recovery quirks. |
|
|
89
|
+
| `rule.cssText` | Browser-compatible observable text for one rule and its current descendants. |
|
|
90
|
+
| `sheet.serialize()` | Deterministic, reparsable stylesheet output with recoverable syntax confined to its declaration or rule. |
|
|
91
|
+
|
|
92
|
+
Reparsable serialization means that the output can be parsed again without one
|
|
93
|
+
declaration leaking into the next declaration or rule, while preserving the
|
|
94
|
+
valid semantic state owned by SheetOM. It does not sanitize URLs, enforce CSP,
|
|
95
|
+
block remote resources, or make valid hostile CSS safe to render.
|
|
96
|
+
|
|
85
97
|
Invalid `setProperty` values and priorities are atomic no-ops, matching browser
|
|
86
98
|
behavior. Opt into mutation diagnostics with `{ diagnostics: true }` and drain
|
|
87
|
-
them using `takeDiagnostics()`.
|
|
99
|
+
them using `takeDiagnostics()`. `SheetOMDiagnostic.code` is a stable string
|
|
100
|
+
union. Diagnostics retain the complete rejected input until drained; when
|
|
101
|
+
processing untrusted or very large input, callers should leave diagnostics off
|
|
102
|
+
or drain them promptly to bound memory use.
|
|
88
103
|
|
|
89
104
|
## API scope
|
|
90
105
|
|
|
@@ -141,8 +156,13 @@ npm run pack:test
|
|
|
141
156
|
|
|
142
157
|
`npm test` runs unit, deterministic fuzz, and local Chromium projects. Use
|
|
143
158
|
`npm run test:browser:matrix` on a machine with all Playwright dependencies to
|
|
144
|
-
run Chromium, Firefox, and WebKit.
|
|
145
|
-
|
|
159
|
+
run Chromium, Firefox, and WebKit. The browser matrix also runs a deterministic,
|
|
160
|
+
grammar-oriented declaration differential; any minimized mismatch must become
|
|
161
|
+
an immutable Operation Fixture with an explicit Compatibility Resolution.
|
|
162
|
+
`npm run docs:build` generates the TypeDoc reference under `site/api`. The benchmark gates both a 10,000-rule stress case
|
|
163
|
+
and a publisher-shaped reference workload with one shared stylesheet, 20 page
|
|
164
|
+
stylesheets, nested layers/media, distributed mutations, and two idempotent
|
|
165
|
+
serialization passes.
|
|
146
166
|
|
|
147
167
|
Only the latest published `0.x` minor and its active prereleases receive fixes
|
|
148
168
|
before 1.0. During `0.x`, observable compatibility corrections and interface
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../schemas/compatibility-report.schema.json",
|
|
3
|
+
"schemaVersion": 1,
|
|
4
|
+
"packageVersion": "0.1.0-rc.1",
|
|
5
|
+
"baseline": {
|
|
6
|
+
"wptCommit": "54f8f933629e7c010ae98a246729af01f8abcda5",
|
|
7
|
+
"lightningcss": "1.33.0",
|
|
8
|
+
"cssTree": "3.2.1",
|
|
9
|
+
"runtimes": {
|
|
10
|
+
"node": "v24.18.0",
|
|
11
|
+
"bun": "1.3.1",
|
|
12
|
+
"deno": "2.9.5"
|
|
13
|
+
},
|
|
14
|
+
"browsers": {
|
|
15
|
+
"chromium": "151.0.7922.34 (revision 1234)",
|
|
16
|
+
"firefox": "153.0 (revision 1538)",
|
|
17
|
+
"webkit": "26.5 (revision 2336)"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"summary": {
|
|
21
|
+
"passed": 5,
|
|
22
|
+
"divergences": 2,
|
|
23
|
+
"excluded": 0,
|
|
24
|
+
"unexplained": 0
|
|
25
|
+
},
|
|
26
|
+
"evidence": {
|
|
27
|
+
"operationFixtures": {
|
|
28
|
+
"passed": 7,
|
|
29
|
+
"total": 7,
|
|
30
|
+
"sha256": "b4ec45fce8ad92393966d1b538748f6b3256d7d51af2fb0f76b4539a3300c349",
|
|
31
|
+
"adapters": [
|
|
32
|
+
{
|
|
33
|
+
"adapter": "sheetom",
|
|
34
|
+
"passed": 7,
|
|
35
|
+
"total": 7
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"adapter": "chromium",
|
|
39
|
+
"passed": 7,
|
|
40
|
+
"total": 7
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"adapter": "firefox",
|
|
44
|
+
"passed": 7,
|
|
45
|
+
"total": 7
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"adapter": "webkit",
|
|
49
|
+
"passed": 7,
|
|
50
|
+
"total": 7
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"nativeWpt": [
|
|
55
|
+
{
|
|
56
|
+
"engine": "chrome",
|
|
57
|
+
"version": "150.0.7871.128",
|
|
58
|
+
"sha256": "33aaf2418507bb1d335cd5350b21a86cee86cbe3059e9eb1b2001c9e2693c1f1",
|
|
59
|
+
"passed": 4,
|
|
60
|
+
"total": 4
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"engine": "firefox",
|
|
64
|
+
"version": "153.0.3",
|
|
65
|
+
"sha256": "20ee01df1d83cc67a50e7949ff6a62c87c572c2fb0159ee5c2b15bc8e9a13a1f",
|
|
66
|
+
"passed": 4,
|
|
67
|
+
"total": 4
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"resolutions": [
|
|
72
|
+
{
|
|
73
|
+
"fixtureId": "declarations.basic-set-property",
|
|
74
|
+
"decision": "shared",
|
|
75
|
+
"rationale": "The observable declaration state is shared by the pinned browser engines."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"fixtureId": "declarations.malformed-padding",
|
|
79
|
+
"decision": "chromium-fallback",
|
|
80
|
+
"rationale": "CSS Syntax accepts the EOF-recovered value; Chromium preserves the unclosed observable spelling while Firefox materializes closing parentheses."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"fixtureId": "declarations.setproperty-null-undefined",
|
|
84
|
+
"decision": "shared",
|
|
85
|
+
"rationale": "The four adapted WPT subtests define the shared null and undefined conversion behavior."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"fixtureId": "declarations.required-arguments",
|
|
89
|
+
"decision": "shared",
|
|
90
|
+
"rationale": "Required WebIDL arguments throw TypeError before string conversion in the pinned browser engines."
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"fixtureId": "declarations.set-property-multiple-declarations",
|
|
94
|
+
"decision": "shared",
|
|
95
|
+
"rationale": "A setProperty value is parsed independently and cannot escape into another declaration; invalid input leaves the previous declaration unchanged."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"fixtureId": "declarations.escaped-custom-property-name",
|
|
99
|
+
"decision": "shared",
|
|
100
|
+
"rationale": "Custom-property method arguments retain their logical names and cssText escapes those names only when serializing CSS syntax."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"fixtureId": "integration.weweb-authoring-tree",
|
|
104
|
+
"decision": "chromium-fallback",
|
|
105
|
+
"rationale": "The standard rule-tree operations and detachment identity are shared; the recovered padding spelling follows the existing Chromium fallback resolution."
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../schemas/compatibility-report.schema.json",
|
|
3
|
+
"schemaVersion": 2,
|
|
4
|
+
"packageVersion": "0.1.0-rc.2",
|
|
5
|
+
"baseline": {
|
|
6
|
+
"wptCommit": "54f8f933629e7c010ae98a246729af01f8abcda5",
|
|
7
|
+
"syntaxEngineSet": {
|
|
8
|
+
"lightningcss": "1.33.0",
|
|
9
|
+
"cssTree": "3.2.1",
|
|
10
|
+
"cssstyle": "6.2.0",
|
|
11
|
+
"cssTokenizer": "4.0.0"
|
|
12
|
+
},
|
|
13
|
+
"runtimes": {
|
|
14
|
+
"node": "v24.18.0",
|
|
15
|
+
"bun": "1.3.1",
|
|
16
|
+
"deno": "2.9.5"
|
|
17
|
+
},
|
|
18
|
+
"browsers": {
|
|
19
|
+
"chromium": "151.0.7922.34 (revision 1234)",
|
|
20
|
+
"firefox": "153.0 (revision 1538)",
|
|
21
|
+
"webkit": "26.5 (revision 2336)"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"summary": {
|
|
25
|
+
"passed": 6,
|
|
26
|
+
"divergences": 7,
|
|
27
|
+
"excluded": 0,
|
|
28
|
+
"unexplained": 0
|
|
29
|
+
},
|
|
30
|
+
"evidence": {
|
|
31
|
+
"operationFixtures": {
|
|
32
|
+
"passed": 13,
|
|
33
|
+
"total": 13,
|
|
34
|
+
"sha256": "7909f90571b8d6595d18b006bb4f2c5337cca9d413084558e913e760be45a3aa",
|
|
35
|
+
"adapters": [
|
|
36
|
+
{
|
|
37
|
+
"adapter": "sheetom",
|
|
38
|
+
"passed": 13,
|
|
39
|
+
"total": 13
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"adapter": "chromium",
|
|
43
|
+
"passed": 13,
|
|
44
|
+
"total": 13
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"adapter": "firefox",
|
|
48
|
+
"passed": 13,
|
|
49
|
+
"total": 13
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"adapter": "webkit",
|
|
53
|
+
"passed": 13,
|
|
54
|
+
"total": 13
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"nativeWpt": [
|
|
59
|
+
{
|
|
60
|
+
"engine": "chrome",
|
|
61
|
+
"version": "150.0.7871.128",
|
|
62
|
+
"sha256": "3f66a5f324bb9023cdd4b168e780640700449f22f28ca378eca91504b7d68e3f",
|
|
63
|
+
"passed": 4,
|
|
64
|
+
"total": 4
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"engine": "firefox",
|
|
68
|
+
"version": "153.0.3",
|
|
69
|
+
"sha256": "e5f88e3431f602dc29fd8dbd79667bef33930ee7f87ee6d2069f17126421a230",
|
|
70
|
+
"passed": 4,
|
|
71
|
+
"total": 4
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"resolutions": [
|
|
76
|
+
{
|
|
77
|
+
"fixtureId": "declarations.basic-set-property",
|
|
78
|
+
"decision": "shared",
|
|
79
|
+
"rationale": "The observable declaration state is shared by the pinned browser engines."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"fixtureId": "declarations.malformed-padding",
|
|
83
|
+
"decision": "chromium-fallback",
|
|
84
|
+
"rationale": "CSS Syntax accepts the EOF-recovered value; Chromium preserves the unclosed observable spelling while Firefox materializes closing parentheses."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"fixtureId": "declarations.modern-color-canonicalization",
|
|
88
|
+
"decision": "shared",
|
|
89
|
+
"rationale": "The pinned browser engines expose modern rgb syntax through the shared legacy rgba serialization in CSSStyleDeclaration."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"fixtureId": "declarations.typed-eof-recovery",
|
|
93
|
+
"decision": "chromium-fallback",
|
|
94
|
+
"rationale": "Typed property values expose the Chromium/WebKit canonical serialization after CSS Syntax EOF recovery; Firefox retains quotes around the recovered font-family string."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"fixtureId": "declarations.quoted-font-family",
|
|
98
|
+
"decision": "chromium-fallback",
|
|
99
|
+
"rationale": "Chromium and WebKit remove unnecessary quotes around a simple font-family while Firefox retains them; SheetOM follows the measured Chromium fallback."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"fixtureId": "declarations.custom-property-eof-recovery",
|
|
103
|
+
"decision": "chromium-fallback",
|
|
104
|
+
"rationale": "Chromium retains unclosed custom-property token structures, removes EOF comments, and replaces an escaped EOF with U+FFFD."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"fixtureId": "declarations.custom-property-priority-replacement",
|
|
108
|
+
"decision": "chromium-fallback",
|
|
109
|
+
"rationale": "Chromium and Firefox replace the existing custom-property priority when setProperty is called without a priority, while WebKit retains !important; SheetOM follows the measured Chromium fallback."
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"fixtureId": "declarations.pending-substitution-eof-recovery",
|
|
113
|
+
"decision": "chromium-fallback",
|
|
114
|
+
"rationale": "Chromium retains the unclosed pending-substitution spelling while applying lexical EOF recovery such as comment removal."
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"fixtureId": "declarations.setproperty-null-undefined",
|
|
118
|
+
"decision": "shared",
|
|
119
|
+
"rationale": "The four adapted WPT subtests define the shared null and undefined conversion behavior."
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"fixtureId": "declarations.required-arguments",
|
|
123
|
+
"decision": "shared",
|
|
124
|
+
"rationale": "Required WebIDL arguments throw TypeError before string conversion in the pinned browser engines."
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"fixtureId": "declarations.set-property-multiple-declarations",
|
|
128
|
+
"decision": "shared",
|
|
129
|
+
"rationale": "A setProperty value is parsed independently and cannot escape into another declaration; invalid input leaves the previous declaration unchanged."
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"fixtureId": "declarations.escaped-custom-property-name",
|
|
133
|
+
"decision": "shared",
|
|
134
|
+
"rationale": "Custom-property method arguments retain their logical names and cssText escapes those names only when serializing CSS syntax."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"fixtureId": "integration.weweb-authoring-tree",
|
|
138
|
+
"decision": "chromium-fallback",
|
|
139
|
+
"rationale": "The standard rule-tree operations and detachment identity are shared; the recovered padding spelling follows the existing Chromium fallback resolution."
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
@@ -7,16 +7,27 @@
|
|
|
7
7
|
"required": ["schemaVersion", "packageVersion", "baseline", "summary", "evidence", "resolutions"],
|
|
8
8
|
"properties": {
|
|
9
9
|
"$schema": { "type": "string" },
|
|
10
|
-
"schemaVersion": { "
|
|
10
|
+
"schemaVersion": { "enum": [1, 2] },
|
|
11
11
|
"packageVersion": { "type": "string" },
|
|
12
12
|
"baseline": {
|
|
13
13
|
"type": "object",
|
|
14
14
|
"additionalProperties": false,
|
|
15
|
-
"required": ["wptCommit", "
|
|
15
|
+
"required": ["wptCommit", "runtimes", "browsers"],
|
|
16
16
|
"properties": {
|
|
17
17
|
"wptCommit": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
|
|
18
18
|
"lightningcss": { "type": "string" },
|
|
19
19
|
"cssTree": { "type": "string" },
|
|
20
|
+
"syntaxEngineSet": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"required": ["lightningcss", "cssTree", "cssstyle", "cssTokenizer"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"lightningcss": { "type": "string" },
|
|
26
|
+
"cssTree": { "type": "string" },
|
|
27
|
+
"cssstyle": { "type": "string" },
|
|
28
|
+
"cssTokenizer": { "type": "string" }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
20
31
|
"runtimes": { "type": "object" },
|
|
21
32
|
"browsers": { "type": "object" }
|
|
22
33
|
}
|
|
@@ -43,7 +54,23 @@
|
|
|
43
54
|
"required": ["passed", "total"],
|
|
44
55
|
"properties": {
|
|
45
56
|
"passed": { "type": "integer", "minimum": 0 },
|
|
46
|
-
"total": { "type": "integer", "minimum": 0 }
|
|
57
|
+
"total": { "type": "integer", "minimum": 0 },
|
|
58
|
+
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
59
|
+
"adapters": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"additionalProperties": false,
|
|
64
|
+
"required": ["adapter", "passed", "total"],
|
|
65
|
+
"properties": {
|
|
66
|
+
"adapter": {
|
|
67
|
+
"enum": ["sheetom", "chromium", "firefox", "webkit"]
|
|
68
|
+
},
|
|
69
|
+
"passed": { "type": "integer", "minimum": 0 },
|
|
70
|
+
"total": { "type": "integer", "minimum": 0 }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
47
74
|
}
|
|
48
75
|
},
|
|
49
76
|
"nativeWpt": {
|
|
@@ -64,5 +91,36 @@
|
|
|
64
91
|
}
|
|
65
92
|
},
|
|
66
93
|
"resolutions": { "type": "array" }
|
|
67
|
-
}
|
|
94
|
+
},
|
|
95
|
+
"allOf": [
|
|
96
|
+
{
|
|
97
|
+
"if": { "properties": { "schemaVersion": { "const": 1 } } },
|
|
98
|
+
"then": {
|
|
99
|
+
"properties": {
|
|
100
|
+
"baseline": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"required": ["lightningcss", "cssTree"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"lightningcss": { "type": "string" },
|
|
105
|
+
"cssTree": { "type": "string" }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"if": { "properties": { "schemaVersion": { "const": 2 } } },
|
|
113
|
+
"then": {
|
|
114
|
+
"properties": {
|
|
115
|
+
"baseline": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"required": ["syntaxEngineSet"],
|
|
118
|
+
"properties": {
|
|
119
|
+
"syntaxEngineSet": { "type": "object" }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
]
|
|
68
126
|
}
|