Conversation
WASM bindings around Servo's `selectors` crate, intended to eventually replace Alfa's TypeScript selector parsing and matching in alfa-cascade. Motivated by a nesting bug where desugared `:is()` selectors from `&` rules don't match correctly in the current engine. Milestone 2: ingests a real Alfa DOM via a binary serialization bridge, parses selectors (including :is(), :where(), :has(), & nesting), and matches type/class/id/attribute/descendant/child/ sibling/:root/:nth-child() selectors against real Alfa elements, plus specificity. Cascade integration (Milestone 3) and & nesting resolution (Milestone 4) are not yet started. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wires the WASM selector engine into alfa-cascade's SelectorMap: candidate matching is delegated to it wherever it can parse the selector, falling back to the existing TypeScript Selector#matches otherwise (currently anything using a Context-dependent pseudo-class, e.g. :hover/:focus-within, since those need Context-state support the engine doesn't have yet). :host/::slotted selectors are unaffected, they already matched through their own matchHost/matchSlotted paths. Also includes the prerequisite work this surfaced: - Fixed :has() matching in the Rust engine: ElementRef::opaque() derived its identity token from a transient stack address rather than the arena index, so the selectors crate's relative-selector anchor check always failed. selector-wasm is now wired into the standard TS project-reference build (packages/tsconfig.json, ts/tsconfig.json, test/tsconfig.json) so alfa-cascade can depend on it normally. - Made SelectorEngine a process-wide singleton with idempotent loadDom(): the compiled WASM module's DOM arena is process-global, but Cascade keeps many documents' cascades alive concurrently, so matching now always (re)asserts the right tree is loaded first. - Fixed alfa-selector's Selector#toString() leaking a literal "of None" into serialized bare :nth-child()/:nth-last-child() selectors, which would otherwise force every such selector to fall back to TS matching unnecessarily. Note: the original motivating nesting bug isn't fixed end-to-end yet. alfa-dom's real-world CSSOM ingestion (native.ts) doesn't capture nested style rules, so a raw `&` selector never reaches the cascade today; only already-desugared selectors do. That's separate alfa-dom work. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 1975a02 The changes in this PR will be included in the next version bump. This PR includes changesets to release 77 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| }); | ||
|
|
||
| test("matches descendant and child combinators across the real tree", (t) => { | ||
| const { document, div, table, span } = fixture(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continues the
alfa-selector-wasmeffort (a Rust/WASM selector engine built on Servo'sselectorscrate, originally motivated by a nesting bug where desugared:is()-wrapped selectors from&rules didn't match correctly).alfa-cascade'sSelectorMap. Candidate matching is delegated to WASM wherever it can parse the selector, falling back to the existing TypeScript matcher otherwise (currently: selectors using a Context-dependent pseudo-class like:hover/:focus-within, since those need Context-state support the engine doesn't have yet).:host/::slottedselectors are untouched.Also includes prerequisite fixes this surfaced:
:has()matching was silently broken in the Rust engine (ElementRef::opaque()derived its identity token from a transient stack address rather than the arena index, so theselectorscrate's relative-selector anchor check always failed).alfa-selector-wasmis now wired into the standard TS project-reference build soalfa-cascadecan depend on it normally.SelectorEngineis now a process-wide singleton with idempotentloadDom(), since the compiled WASM module's DOM arena is process-global butCascadekeeps many documents' cascades alive concurrently.alfa-selector'sSelector#toString()leaked a literal"of None"into serialized bare:nth-child()/:nth-last-child()selectors, which would've forced every such selector to fall back to TS matching unnecessarily.Known gap carried forward: the original motivating nesting bug isn't fixed end-to-end yet.
alfa-dom's real-world CSSOM ingestion (native.ts) doesn't capture nested style rules at all, so a raw&selector never reaches the cascade today — only already-desugared selectors do. That's separatealfa-domwork, tracked outside this PR.Test plan
:has()matching (direct child, deep descendant, sibling combinator, absence, composition with:is())alfa-selector-wasm's Alfa-integrated vitest suite (bridge.spec.tsx)alfa-cascadetest suite, including a new end-to-end test matching a WASM-backed:is()+:has()selector through the fullCascadealfa-selector,alfa-selector-wasm,alfa-cascade,alfa-style,alfa-rules— 2041 tests passing, no type errorsalfa-selectorpatch,alfa-cascadepatch)🤖 Generated with Claude Code