Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ __pycache__/
# Cake - Uncomment if you are using it
tools/**
# !tools/packages.config
!tools/generate_css_property_metadata.py
!tools/webidl-v8-bindings/
!tools/webidl-v8-bindings/dom-exposure.json
!tools/webidl-v8-bindings/generate.mjs
Expand Down
82 changes: 82 additions & 0 deletions docs/validation/css-property-identity-20260917.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Generated CSS property identity validation (2026-09-17)

This stage of #235 removes the remaining independent managed and native
CSSStyleDeclaration property lists. It builds on the effective-property registry
merged in #309; it does not alter the selector timing, containment, or stylesheet
finalization work owned by #238 and #297.

## Structural result

`experiments/WebScene.NativeEngine.Probe/native/css_property_metadata.json` is now
the checked-in source for three related property views:

- 105 stable managed storage properties, in ID order;
- 95 additional CSSOM-supported names; and
- 61 effective box-property entries used by native cascade masks and expansion.

The generator validates and emits:

- the existing 61-entry native effective-property table;
- a 214-entry native CSSOM table containing canonical CSS names and precomputed IDL
names; and
- managed arrays for stable storage IDs and the same 214 supported CSSOM names,
plus the direct name-to-ID switch.

The native V8 template previously maintained 152 handwritten IDL names separately
from the managed catalog. It now consumes the generated CSS/IDL pairs. The pairs
are compile-time string views, so template setup does not allocate strings to
convert 214 property names at runtime. Six compatibility names that existed only
in the native list (`animation`, `box-shadow`, `contain`, `grid-row-gap`,
`grid-column-gap`, and `webkit-font-smoothing`) were retained in the shared catalog.

Managed direct-storage IDs remain byte-for-byte ordered as before. The generator
test pins all 105 names with a SHA-256 sequence fingerprint in addition to checking
the generated outputs. Case-insensitive access still uses the existing frozen-map
fallback, while exact lower-case access retains the direct switch.

The shared union also closes an observed CSSOM drift: 14 logical effective names,
including `inset-block-end`, `border-block-width`, `border-inline-color`,
`padding-block-start`, and `margin-block-end`, were understood by native style
application but absent from one or both named-property exposure lists.

The generator itself is now explicitly tracked. The repository's broad `tools/**`
ignore rule had excluded the script introduced with #309 even though CI invoked it;
the new `.gitignore` exception prevents clean checkouts from losing that build input.

## Browser-shaped regression

`tests/WebPlatformSubset/contracts/cssom-inline-declaration-validity.html` now has a
fifth subtest covering named exposure and assignment for logical inset, border,
padding, and margin properties. Results:

- Google Chrome 153.0.8010.48: 5/5;
- native current CSSParser: 5/5; and
- native legacy parser: 5/5.

The native engine initially failed the new subtest because `inset-block-end` was
missing from its handwritten V8 template list. Replacing that list with generated
metadata is the regression fix; adding only managed tests would not have caught it.

An adjacent native `cssom-` sweep passes all nine CSS-specific documents. The filter
also selects `dom-document-cssom-hosted-page-primitives.html`; its unrelated
`document.cookie` assertion failed both with default and fresh storage, leaving the
combined sweep at 9/10 documents and 60/61 subtests. No property-exposure assertion
failed.

## Build and test evidence

- metadata generator tests: 6/6, followed by a clean `--check`;
- WebScene.Css tests: 383/383 on .NET 8 and 383/383 on .NET 10;
- full `WebScene.sln` Release build: success with 16 pre-existing nullable warnings
and zero errors;
- full managed solution tests: 1,774 passed, 30 platform-dependent tests skipped;
- current-parser native CSS parser CTest: 1/1;
- NativeWeb CSS service/shared-style/compiler CTests: 3/3; and
- both current- and legacy-parser native engine libraries rebuilt successfully.

This stage centralizes identity and exposure, not all CSS semantics. Property initial
values, inheritance, serialization, grammar selection, complex shorthand expansion,
origins, and CSS-wide keyword behavior remain later metadata slices in #235.

Machine-readable evidence is in
`docs/validation/evidence/css-property-identity-20260917.json`.
76 changes: 76 additions & 0 deletions docs/validation/evidence/css-property-identity-20260917.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"date": "2026-09-17",
"issue": 235,
"catalog": {
"managedKnownProperties": 105,
"managedKnownPropertyOrderSha256": "fc4d77c515998b6df1f119ff7e09b0b82cc812744c34f1c44c6fd142067b1fb2",
"supportedPropertyExtras": 95,
"effectiveProperties": 61,
"unifiedSupportedProperties": 214,
"previousNativeHandwrittenIdlNames": 152
},
"generatedOutputs": {
"nativeEffectivePropertyTable": 61,
"nativeCssomCssIdlPairs": 214,
"managedKnownNames": 105,
"managedSupportedNames": 214,
"managedDirectIdSwitchEntries": 105
},
"contracts": {
"chrome": {
"version": "153.0.8010.48",
"passed": 5,
"total": 5
},
"nativeCurrentParser": {
"passed": 5,
"total": 5
},
"nativeLegacyParser": {
"passed": 5,
"total": 5
}
},
"tests": {
"managedSolutionBuild": {
"result": "pass",
"warnings": 16,
"newWarnings": 0,
"errors": 0
},
"generator": {
"passed": 6,
"total": 6,
"generatedCheck": "pass"
},
"managedCssNet8": {
"passed": 383,
"total": 383
},
"managedCssNet10": {
"passed": 383,
"total": 383
},
"managedSolution": {
"passed": 1774,
"skipped": 30,
"failed": 0
},
"nativeCurrentCssParser": {
"passed": 1,
"total": 1
},
"nativeWebCss": {
"passed": 3,
"total": 3
}
},
"adjacentCssomSweep": {
"documentsPassed": 9,
"documentsTotal": 10,
"subtestsPassed": 60,
"subtestsTotal": 61,
"propertyExposureFailures": 0,
"unrelatedFailure": "dom-document-cssom-hosted-page-primitives document.cookie"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
{
"version": 1,
"managedKnownProperties": [
"align-content", "align-items", "align-self", "all", "background", "background-color",
"background-image", "border", "border-bottom-color", "border-bottom-left-radius",
"border-bottom-right-radius", "border-bottom-style", "border-bottom-width", "border-color",
"border-left-color", "border-left-style", "border-left-width", "border-radius",
"border-right-color", "border-right-style", "border-right-width", "border-style",
"border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-sizing", "clip-rule", "color",
"column-gap", "content", "cursor", "direction", "display", "fill", "fill-rule", "flex",
"flex-basis", "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", "font",
"font-family", "font-size", "font-style", "font-variant", "font-weight", "gap",
"grid", "grid-template-columns", "grid-template-rows", "height", "inset", "justify-content",
"left", "letter-spacing", "line-height", "margin", "margin-bottom", "margin-left",
"margin-right", "margin-top", "max-height", "max-width", "min-height", "min-width", "opacity",
"order", "overflow", "overflow-x", "overflow-y", "padding", "padding-bottom", "padding-left",
"padding-right", "padding-top", "pointer-events", "position", "right", "row-gap", "stroke",
"stroke-linecap", "stroke-linejoin", "stroke-width", "text-align", "text-indent", "text-transform",
"top", "transform", "visibility", "white-space", "width", "word-spacing", "z-index",
"outline", "outline-color", "outline-offset", "outline-style", "outline-width",
"grid-template-areas"
],
"supportedPropertyExtras": [
"animation", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function",
"accent-color", "appearance", "backdrop-filter", "background-attachment", "background-clip",
"background-origin", "background-position", "background-position-x", "background-position-y",
"background-repeat", "background-size", "border-bottom", "border-collapse", "border-left",
"border-right", "border-spacing", "border-top", "clear", "column-count", "columns", "css-float",
"box-shadow", "clip-path", "color-scheme", "contain", "empty-cells", "fill-opacity", "filter", "float", "font-stretch",
"grid-area", "grid-column", "grid-column-end", "grid-column-start", "grid-row", "grid-row-end",
"grid-row-start", "grid-gap", "grid-row-gap", "grid-column-gap", "inset-block", "inset-inline", "inset-inline-start",
"inset-inline-end", "margin-block", "margin-inline", "margin-inline-start", "margin-inline-end",
"mask-composite", "mask-image", "mask-position", "mask-repeat", "mask-size", "padding-block",
"padding-inline", "padding-inline-start", "padding-inline-end", "border-inline-start",
"border-inline-end", "border-inline-start-width", "border-inline-end-width",
"border-inline-start-color", "border-inline-end-color", "border-start-start-radius",
"border-start-end-radius", "border-end-start-radius", "border-end-end-radius", "-moz-transform",
"moz-transform", "-webkit-transform", "webkit-transform", "webkit-font-smoothing", "orphans", "resize", "table-layout",
"text-decoration", "text-overflow", "vertical-align", "transition", "transition-delay",
"transition-duration", "transition-property", "transition-timing-function", "transform-origin",
"widows", "zoom"
],
"properties": [
{"name": "border-block-color", "mask": ["inline_border"], "expansion": ["border-top-color", "border-bottom-color"], "applyExpansion": true},
{"name": "border-block-end-color", "mask": ["inline_border"], "alias": "border-bottom-color"},
Expand Down
Loading
Loading