feat(M4-3): form controls + animation pipeline + content thread frame loop#22
feat(M4-3): form controls + animation pipeline + content thread frame loop#22
Conversation
…ing + registry dispatch - Add AnimationEngine to PipelineResult, initialized in both build_pipeline functions - Parse @Keyframes at-rules in CSS parser (Stylesheet.keyframes_raw), register with engine - Add parse_stylesheet_with_registry() for handler-based property dispatch - Transition/animation properties now parsed from stylesheets via CssPropertyRegistry fallback - Add parse_compat_stylesheet_with_registry() to elidex-dom-compat - 5 new tests (3 @Keyframes parser + 2 shell integration) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Content thread event loop now uses 16ms (~60fps) polling when AnimationEngine has active animations/transitions. Falls back to 100ms idle polling when inactive. Each frame ticks the animation engine with elapsed dt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire AnimStyle ECS component population into the style walk phase, implement transition detection by comparing old vs new computed styles, and apply animated values from active transitions to ComputedStyle before layout. Changes: - walk.rs: build_anim_style_from_winners() populates AnimStyle ECS component during style resolution (sequential + parallel paths) - lib.rs: re_render() now saves old styles, detects transitions after re-resolution, and applies animated values before layout - apply.rs: new module mapping animated CssValues to ComputedStyle fields (~35 animatable properties) - interpolate.rs: ANIMATABLE_PROPERTIES public constant - engine.rs: active_entity_ids() iterator method - 13 new tests (apply: 10, shell: 3), total: 2396 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dispatch transitionrun/start/end/cancel and animationstart/end/iteration events from the AnimationEngine to JS listeners via DispatchEvent. - Add TransitionEventInit and AnimationEventInit to elidex-plugin EventPayload - Expose propertyName/elapsedTime/pseudoElement (transition) and animationName/elapsedTime/pseudoElement (animation) on JS event objects - Convert AnimationEvent from engine tick into DispatchEvent with correct event type and payload in content thread - Events bubble but are not cancelable (per CSS Transitions/Animations spec) - 6 new tests (2402 total) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… loop Form Controls (elidex-form crate): - Input types: text/password/email/url/tel/search/number/range/color/date/file/hidden - Select element with dropdown, option navigation, intrinsic sizing - Textarea with multiline rendering, scroll tracking - Checkbox/radio with group exclusivity, arrow key navigation - Button (submit/reset/button), fieldset/legend with disabled propagation - Form submission (collect_form_data, encode_form_urlencoded, implicit Enter) - Constraint validation (ValidityState: required/pattern/minlength/maxlength/ min/max/step/type mismatch/bad input), :valid/:invalid pseudo-class sync - Text selection (Shift+Arrow, select_all, replace_selection) - Clipboard (Ctrl+C/X/V via arboard), caret blink (500ms), IME composition - InputEvent/ClipboardEvent/CompositionEvent interfaces - Focus lifecycle (focusout→focusin→blur→focus with relatedTarget) - dirty-value flag, defaultValue, password bullet masking - ARIA role mapping for form controls - 117 tests Animation Pipeline Completion: - AnimationEngine tick connected to 16ms frame loop - keyframe_values() with O(n) HashMap lookup, surrounding keyframe interpolation - apply_active_animations() applies both transitions and @Keyframes animations - Transition detection with CSS property list filtering - transitionend/animationend/animationstart/animationiteration DOM event dispatch - animationcancel/transitioncancel on style removal - elapsed_time f32→f64 propagation throughout event chain Content Thread Architecture: - content.rs split into content/ module (mod, focus, event_handlers, ime, animation, navigation, form_input) - Frame loop: animation tick + caret blink + timer drain with adaptive timeout - has_running() prevents fill-mode:forwards infinite re-render loop - SetViewport uses PipelineResult viewport fields + re_render() Review Fixes (R5-R16, 38 items): - CSS Selectors L4: :enabled/:disabled restricted to actually disableable elements, :checked to checkbox/radio/option, :indeterminate to checkbox/radio/progress - NaN/Infinity guards: apply_dimension, apply_optional_px, keyframe local_t, safe_scroll_offset, frame loop 1ms minimum sleep - DRY: push_transition_event, safe_scroll_offset, apply_optional_px, apply_non_negative_number, set_elapsed_and_pseudo, create_animation_engine, ANIM_LONGHAND_NAMES shared constant, match_form_pseudo_class extraction - @Keyframes: quoted name support, CSS-wide keyword/none rejection, find_matching_brace string literal skip - Step validation (HTML §4.10.5.1.12) for Number/Range inputs - IME composition text 10k char cap, redirect header stripping - is_form_element includes progress/meter/output - find_surrounding_keyframes assert→debug_assert Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR significantly expands the engine’s interactive capabilities by introducing a full form-controls subsystem, wiring CSS transitions/animations through parsing → style resolution → ticking → event dispatch, and refactoring the content thread into focused submodules with an adaptive frame loop.
Changes:
- Added new
elidex-formcrate and integrated form control state init + rendering + basic interaction (focus, label click, checkbox/radio behavior, selection, clipboard, IME). - Completed CSS animation/transition pipeline: registry-backed parsing for animation/transition properties,
@keyframesextraction + registration, transition detection + engine ticking + DOM event dispatch. - Refactored content thread loop and navigation to support POST submissions, IME events, and frame-loop ticking.
Reviewed changes
Copilot reviewed 81 out of 82 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/shell/elidex-shell/src/tests.rs | Adds integration tests for keyframes registration, AnimStyle attachment, and JS transition/animation event payloads. |
| crates/shell/elidex-shell/src/lib.rs | Integrates AnimationEngine, keyframes registration, viewport sizing, and transition detection into re-render. |
| crates/shell/elidex-shell/src/ipc.rs | Adds IME IPC message + ImeKind enum. |
| crates/shell/elidex-shell/src/content_tests.rs | Adjusts keyboard test HTML to be focusable (tabindex=0). |
| crates/shell/elidex-shell/src/content/navigation.rs | New content-thread navigation module; supports POST requests for form submission. |
| crates/shell/elidex-shell/src/content/mod.rs | New content-thread module + adaptive frame loop (animations/timers/caret blink) + IME handling. |
| crates/shell/elidex-shell/src/content/ime.rs | New IME composition/commit handling integrated with form state + DOM events. |
| crates/shell/elidex-shell/src/content/form_input.rs | New helpers for label activation, checkbox toggling, input/change dispatch, and form submit/reset. |
| crates/shell/elidex-shell/src/content/focus.rs | New focus management and focus/blur/focusin/focusout dispatch; change-on-blur for text controls. |
| crates/shell/elidex-shell/src/content/animation.rs | Dispatches transition/animation events from animation engine into DOM dispatch. |
| crates/shell/elidex-shell/src/app/navigation.rs | Updates navigation loader call signature to include request option. |
| crates/shell/elidex-shell/Cargo.toml | Adds dependencies for forms, animation, clipboard, logging, and request bodies. |
| crates/shell/elidex-navigation/src/loader.rs | Extends loader API to accept optional custom request (enables POST form submit). |
| crates/script/elidex-js/src/parser/expr_tests_special.rs | Adds parser coverage for special expressions (super, import.meta, new.target, regexp ambiguity, etc.). |
| crates/script/elidex-js/src/parser/expr_tests_operators.rs | Adds expression operator precedence/validation tests. |
| crates/script/elidex-js/src/parser/expr_tests_core.rs | New shared test helpers and core expression tests. |
| crates/script/elidex-js/src/parser/expr.rs | Splits expr tests into multiple modules. |
| crates/script/elidex-js-boa/src/globals/mod.rs | Registers new form-related element globals module. |
| crates/script/elidex-js-boa/src/globals/events.rs | Adds event payload property mapping for animation/transition/input/clipboard/composition/focus. |
| crates/script/elidex-js-boa/src/globals/element.rs | Registers form accessors on Element objects. |
| crates/script/elidex-js-boa/Cargo.toml | Adds dependency on elidex-form. |
| crates/net/elidex-net/src/redirect.rs | Refines redirect method/body/header handling; adds test for HEAD preservation. |
| crates/layout/elidex-layout-block/src/block/mod.rs | Treats form controls as replaced elements with intrinsic sizing fallback. |
| crates/layout/elidex-layout-block/Cargo.toml | Adds dependency on elidex-form. |
| crates/dom/elidex-form/src/util.rs | Adds UTF-8 boundary + UTF-16 offset conversion utilities with tests. |
| crates/dom/elidex-form/src/sizing.rs | Implements intrinsic sizing for form controls with tests. |
| crates/dom/elidex-form/src/selection.rs | Implements text selection operations with tests. |
| crates/dom/elidex-form/src/radio.rs | Implements form-scoped radio groups, toggling, and navigation with tests. |
| crates/dom/elidex-form/src/label.rs | Implements label→control association and descendant lookup with tests. |
| crates/dom/elidex-form/src/init.rs | Adds bulk form-control initialization + single-entity attach for dynamic creation. |
| crates/dom/elidex-form/src/fieldset.rs | Implements disabled fieldset propagation with legend exemption and tests. |
| crates/dom/elidex-form/src/clipboard.rs | Implements copy/cut/paste semantics with safety limits and tests. |
| crates/dom/elidex-form/Cargo.toml | New crate manifest for form control subsystem. |
| crates/dom/elidex-dom-compat/src/vendor_prefix.rs | Adds registry-aware compat stylesheet parsing. |
| crates/dom/elidex-dom-compat/src/lib.rs | Re-exports registry-aware compat stylesheet parser. |
| crates/dom/elidex-dom-compat/src/legacy_ua.rs | Adds UA default styling for form controls. |
| crates/dom/elidex-a11y/src/tree.rs | Uses FormControlState to map to more precise accessibility roles. |
| crates/dom/elidex-a11y/src/roles.rs | Adds FormControlKind→AccessKit role mapping + tests. |
| crates/dom/elidex-a11y/Cargo.toml | Adds dependency on elidex-form. |
| crates/css/elidex-style/src/walk.rs | Attaches AnimStyle during style resolution based on cascade winners. |
| crates/css/elidex-css/src/selector/tests/matching.rs | Expands selector tests for form pseudo-classes; updates ElementState width. |
| crates/css/elidex-css/src/parser.rs | Adds registry-backed parsing + raw @keyframes extraction. |
| crates/css/elidex-css/src/lib.rs | Re-exports parse_stylesheet_with_registry. |
| crates/css/elidex-css/src/declaration.rs | Adds optional registry dispatch for unknown properties. |
| crates/css/elidex-css-anim/src/resolve.rs | Exposes ANIM_LONGHAND_NAMES for shared resolution. |
| crates/css/elidex-css-anim/src/parse_tests.rs | Adds tests for brace matching in strings and keyframes parsing edge cases. |
| crates/css/elidex-css-anim/src/parse.rs | Improves brace matching to skip braces inside string literals. |
| crates/css/elidex-css-anim/src/lib.rs | Exposes apply module publicly. |
| crates/css/elidex-css-anim/src/interpolate.rs | Centralizes animatable properties list; updates is_animatable accordingly. |
| crates/css/elidex-css-anim/src/engine_tests.rs | Adds comprehensive AnimationEngine behavioral tests. |
| crates/css/elidex-css-anim/src/detection.rs | Fixes transition list indexing for duplicates; adds regression test. |
| crates/core/elidex-render/src/builder/walk.rs | Emits form controls during display list build. |
| crates/core/elidex-render/src/builder/mod.rs | Adds form builder module. |
| crates/core/elidex-render/Cargo.toml | Adds dependencies for form rendering and fontdb. |
| crates/core/elidex-plugin/src/lib.rs | Re-exports new event init payload types. |
| crates/core/elidex-plugin/src/event_types.rs | Adds payload init structs and payload variants for animation/transition/input/clipboard/composition/focus. |
| crates/core/elidex-ecs/src/dom/tests/mod.rs | Adds DOM test module organization. |
| crates/core/elidex-ecs/src/dom/tests/creation.rs | Adds DOM creation tests. |
| crates/core/elidex-ecs/src/dom/tests/destroy.rs | Adds DOM destroy semantics tests (incl. shadow DOM interactions). |
| crates/core/elidex-ecs/src/dom/tests/shadow_dom.rs | Adds extensive shadow DOM behavior tests. |
| crates/core/elidex-ecs/src/dom/tests/tree_ops.rs | Adds tree operation tests (append/insert/replace/cycle rejection). |
| crates/core/elidex-ecs/src/dom.rs | Adds is_contenteditable() and get_tag_name() helpers. |
| crates/core/elidex-ecs/src/components.rs | Expands ElementState bitflags to u16 and adds form-related state bits. |
| Cargo.toml | Adds elidex-form, regex, arboard to workspace members/deps. |
| Cargo.lock | Updates lockfile for new crates and dependencies. |
| CLAUDE.md | Updates repo docs describing registry parsing and animation engine wiring. |
Comments suppressed due to low confidence (1)
crates/script/elidex-js-boa/src/globals/events.rs:333
- FocusEventInit carries related_target entity bits, but the JS event object currently hard-codes relatedTarget to null. This means JS listeners can’t observe relatedTarget despite the new focus event ordering logic. Consider plumbing HostBridge into event construction so relatedTarget can be resolved to an Element (or adjust the PR description/expectations if this is intentionally deferred).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
CI fixes: - Rename sel_rw/sel_ro to read_write/read_only (similar_names lint) - Allow field_reassign_with_default in apply.rs tests - Use struct init in lib_tests.rs (field_reassign_with_default) Copilot review fixes: - Use after-change AnimStyle for transition params (CSS Transitions §3) - Cap animation dt to 2×FRAME_INTERVAL to prevent idle→active spike - Remove stale AnimStyle when properties disappear (both sequential and parallel resolve paths) - Collapse delete_selection to cursor_pos instead of (0,0) Copilot review TODOs (architectural, deferred to M4-3.7): - Thread caret_visible into display list builder - Fieldset disabled propagation for dynamically created controls - Radio group sorting by document tree order Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cap IME composition text once and reuse for both FormControlState storage and compositionupdate event payload, preventing JS from seeing the uncapped string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR substantially expands the browser engine’s interactivity by adding a full form-controls subsystem, completing the CSS animation/transition pipeline (including event dispatch), and refactoring the content-thread loop into a modular frame/timer-driven architecture.
Changes:
- Introduces new
elidex-formcrate and integrates form control state, selection/clipboard/IME behaviors, intrinsic sizing, and label/radio/fieldset logic across shell/layout/render/a11y. - Adds CSS animation/transition support end-to-end: stylesheet parsing of
@keyframes, animation/transition property resolution into ECS (AnimStyle), engine ticking + event dispatch, and animated value application during re-render. - Refactors content thread into
content/modules with an adaptive frame loop (animations/timers/caret blink) and navigation support with optional POST requests.
Reviewed changes
Copilot reviewed 81 out of 82 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/shell/elidex-shell/src/lib.rs | Adds AnimationEngine to pipeline, keyframes registration, transition detection, and animated style application during re_render. |
| crates/shell/elidex-shell/src/content/mod.rs | New modular content-thread loop with animation ticking, timer draining, caret blink timing, and message handling. |
| crates/css/elidex-css/src/parser.rs | Extracts @keyframes blocks and adds stylesheet parsing with an optional CssPropertyRegistry. |
| crates/css/elidex-style/src/walk.rs | Attaches/removes AnimStyle during style resolution based on animation/transition cascade winners. |
| crates/script/elidex-js-boa/src/globals/events.rs | Exposes transition/animation/input/clipboard/composition/focus payload properties to JS events. |
| crates/core/elidex-render/src/builder/walk.rs | Emits form control rendering during display-list build and wires focus detection into rendering. |
| crates/dom/elidex-form/* | New form-control crate: state initialization, sizing, selection, clipboard, label/radio/fieldset helpers, and tests. |
| crates/net/elidex-net/src/redirect.rs | Refines redirect method/header handling and adds an async regression test for method preservation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Avoid per-element HashMap allocation in parallel walk path by using build_anim_style_from_owned() that queries OwnedPropertyMap directly - Resolve FocusEventInit.related_target to JS element object instead of always setting null (UI Events §5.2) - Gate caret blink on editable text controls only, preventing unnecessary 500ms re-render loops when non-text elements are focused Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR substantially expands the engine’s interactive capabilities by introducing a full form-controls subsystem, completing the CSS animation/transition pipeline (including @keyframes extraction + runtime event payloads), and refactoring the shell content thread into a modular event loop with frame ticking, IME support, and navigation handling.
Changes:
- Add new
elidex-formcrate and integrate form control state/initialization, sizing, selection, clipboard, IME composition, and radio/label/fieldset behaviors. - Complete CSS animation/transition plumbing end-to-end: stylesheet parsing + handler registry dispatch,
AnimStyleattachment, transition detection + engine ticking, and JS event payload exposure. - Refactor shell content thread into modules (
content/) with adaptive poll timeout, navigation/history actions, viewport updates, and focus lifecycle updates (incl.relatedTargetpayload bits).
Reviewed changes
Copilot reviewed 82 out of 83 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/shell/elidex-shell/src/tests.rs | Adds integration tests around keyframes registration, AnimStyle attachment, and JS transition/animation event payloads. |
| crates/shell/elidex-shell/src/lib.rs | Integrates elidex-form, introduces AnimationEngine in pipeline state, adds transition detection + animated value application in re_render. |
| crates/shell/elidex-shell/src/ipc.rs | Adds browser→content IME message and ImeKind variants. |
| crates/shell/elidex-shell/src/content_tests.rs | Adjusts keyboard test element to be focusable (tabindex=0). |
| crates/shell/elidex-shell/src/content/navigation.rs | New navigation/history action handler module for the content thread. |
| crates/shell/elidex-shell/src/content/mod.rs | New modular content-thread main loop with adaptive timeouts, animation ticking, timers, caret blink, and message dispatch. |
| crates/shell/elidex-shell/src/content/ime.rs | New IME preedit/commit handling with composition events and maxlength enforcement. |
| crates/shell/elidex-shell/src/content/form_input.rs | New form interaction helpers (label activation, checkbox toggle, input/change dispatch, submit/reset). |
| crates/shell/elidex-shell/src/content/focus.rs | New focus management with UI Events ordering and change-on-blur for text controls. |
| crates/shell/elidex-shell/src/content/animation.rs | Dispatches animation/transition engine events into DOM events + payloads. |
| crates/shell/elidex-shell/src/app/navigation.rs | Updates navigation loading to new load_document(..., request) signature. |
| crates/shell/elidex-shell/Cargo.toml | Adds dependencies needed for forms/anim/clipboard and tracing. |
| crates/shell/elidex-navigation/src/loader.rs | Extends load_document to accept an optional custom request (enables POST form submissions). |
| crates/script/elidex-js/src/parser/expr_tests_core.rs | New expression parser test suite split (core). |
| crates/script/elidex-js/src/parser/expr_tests_operators.rs | New operator-focused expression parser tests. |
| crates/script/elidex-js/src/parser/expr_tests_special.rs | New special-syntax expression parser tests (super/import.meta/new.target/dynamic import/regexp ambiguity/etc.). |
| crates/script/elidex-js/src/parser/expr.rs | Wires the new split test modules. |
| crates/script/elidex-js-boa/src/runtime/mod.rs | Attempts to populate relatedTarget for focus events during JS dispatch. |
| crates/script/elidex-js-boa/src/globals/mod.rs | Registers new element_form module. |
| crates/script/elidex-js-boa/src/globals/events.rs | Adds event payload property wiring for transition/animation/input/clipboard/composition/focus events. |
| crates/script/elidex-js-boa/src/globals/element.rs | Registers form-related element accessors. |
| crates/script/elidex-js-boa/Cargo.toml | Adds elidex-form dependency for JS bindings. |
| crates/net/elidex-net/src/redirect.rs | Refines redirect method/body/header handling and adds test for HEAD 301 method preservation. |
| crates/layout/elidex-layout-block/src/block/mod.rs | Treats form controls as replaced elements with intrinsic sizing fallback. |
| crates/layout/elidex-layout-block/Cargo.toml | Adds elidex-form dependency. |
| crates/dom/elidex-form/src/util.rs | Adds UTF-8/UTF-16 and char-boundary utilities with tests. |
| crates/dom/elidex-form/src/sizing.rs | Adds intrinsic sizing for form controls with tests. |
| crates/dom/elidex-form/src/selection.rs | Adds selection operations (extend/select-all/collapse/delete/replace) with tests. |
| crates/dom/elidex-form/src/radio.rs | Adds form-scoped radio grouping + navigation with tests. |
| crates/dom/elidex-form/src/label.rs | Adds <label> target resolution (for= and wrapped controls) with tests. |
| crates/dom/elidex-form/src/init.rs | Adds DOM walk + single-entity attachment for FormControlState and ElementState flag setup. |
| crates/dom/elidex-form/src/fieldset.rs | Adds fieldset disabled propagation with legend exemption + tests. |
| crates/dom/elidex-form/src/clipboard.rs | Adds copy/cut/paste behavior with password safeguards + paste limits + tests. |
| crates/dom/elidex-form/Cargo.toml | Introduces new crate manifest. |
| crates/dom/elidex-dom-compat/src/vendor_prefix.rs | Adds stylesheet parsing variant that passes a property-handler registry through. |
| crates/dom/elidex-dom-compat/src/lib.rs | Re-exports registry-aware compat stylesheet parser. |
| crates/dom/elidex-dom-compat/src/legacy_ua.rs | Adds UA default styles for form controls/fieldset/legend. |
| crates/dom/elidex-a11y/src/tree.rs | Uses FormControlState to derive more accurate accessibility roles. |
| crates/dom/elidex-a11y/src/roles.rs | Adds FormControlKind→AccessKit Role mapping + tests. |
| crates/dom/elidex-a11y/Cargo.toml | Adds elidex-form dependency. |
| crates/css/elidex-style/src/walk.rs | Builds/attaches/removes AnimStyle during style resolution (serial + parallel paths). |
| crates/css/elidex-css/src/selector/tests/matching.rs | Extends selector matching tests for form-related pseudo-classes and updates ElementState width. |
| crates/css/elidex-css/src/parser.rs | Extracts raw @keyframes blocks and adds registry-aware stylesheet parsing. |
| crates/css/elidex-css/src/lib.rs | Re-exports registry-aware stylesheet parsing API. |
| crates/css/elidex-css/src/declaration.rs | Adds registry-based fallback parsing for plugin-handled properties. |
| crates/css/elidex-css-anim/src/resolve.rs | Exports shared animation/transition longhand property name list. |
| crates/css/elidex-css-anim/src/parse_tests.rs | Adds tests for brace matching inside strings in keyframe parsing. |
| crates/css/elidex-css-anim/src/parse.rs | Updates brace matcher to skip braces inside string literals. |
| crates/css/elidex-css-anim/src/lib.rs | Exposes apply module. |
| crates/css/elidex-css-anim/src/interpolate.rs | Centralizes animatable property list and updates is_animatable implementation + tests. |
| crates/css/elidex-css-anim/src/engine_tests.rs | Adds comprehensive engine behavior tests (running/active, delays, cancel, NaN dt, caps). |
| crates/css/elidex-css-anim/src/detection.rs | Fixes duplicate transition-property indexing (use last occurrence) + test. |
| crates/core/elidex-render/src/builder/walk.rs | Emits form control display items during display-list building. |
| crates/core/elidex-render/src/builder/mod.rs | Registers new form builder module. |
| crates/core/elidex-render/src/builder/form.rs | Implements actual form control rendering (caret, selection, masking, etc.). |
| crates/core/elidex-render/Cargo.toml | Adds elidex-form and fontdb dependencies. |
| crates/core/elidex-plugin/src/lib.rs | Re-exports expanded event payload init types. |
| crates/core/elidex-plugin/src/event_types.rs | Adds init structs + payload variants for transition/animation/input/clipboard/composition/focus events. |
| crates/core/elidex-ecs/src/dom/tests/mod.rs | Adds new DOM test module structure. |
| crates/core/elidex-ecs/src/dom/tests/creation.rs | Adds DOM creation tests. |
| crates/core/elidex-ecs/src/dom/tests/destroy.rs | Adds DOM destroy tests incl. shadow DOM interactions. |
| crates/core/elidex-ecs/src/dom/tests/shadow_dom.rs | Adds shadow DOM behavior tests (host validation, composed children, etc.). |
| crates/core/elidex-ecs/src/dom/tests/tree_ops.rs | Adds tree operation tests (append/insert/replace/cycle rejection). |
| crates/core/elidex-ecs/src/dom.rs | Adds is_contenteditable (inherited) and a tag-name getter helper. |
| crates/core/elidex-ecs/src/components.rs | Expands ElementState to a u16 bitfield with form-related flags. |
| Cargo.toml | Adds elidex-form, regex, and arboard workspace entries. |
| Cargo.lock | Locks new dependencies and crate additions. |
| CLAUDE.md | Updates docs for registry-aware stylesheet parsing and AnimationEngine pipeline integration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Make relatedTarget writable+configurable so dispatch_event can overwrite the initial null with the resolved JS element wrapper - Loosen f32 assertion tolerance from EPSILON to 1e-6 for parsed time values (0.3s may not round-trip exactly through f32) - Add TODO for snapshotting ComputedStyle of entities that gain AnimStyle in the current render (newly added transition-*) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR substantially expands the engine toward interactive web-app behavior by adding a full HTML form-controls subsystem, completing the CSS animation/transition pipeline (including event dispatch), and refactoring the shell content thread into clearer submodules with an adaptive frame loop.
Changes:
- Introduces new
elidex-formcrate (form control state, validation, selection/clipboard, radio/label/fieldset logic, intrinsic sizing) and wires it into shell/layout/render/a11y/JS. - Completes animation/transition pipeline: parse
@keyframes, attachAnimStylefrom cascaded winners, tickAnimationEnginein a ~16ms loop, dispatch transition/animation events into JS. - Refactors content thread (
content/module split) and extends DOM/JS event payloads (focusrelatedTarget, Input/Composition/Clipboard/Transition/Animation event init data).
Reviewed changes
Copilot reviewed 82 out of 83 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/shell/elidex-shell/src/tests.rs | Adds pipeline/registry/AnimStyle and JS event dispatch tests for transitions/animations. |
| crates/shell/elidex-shell/src/lib.rs | Adds AnimationEngine + viewport to pipeline, registers @keyframes, runs transition detection + animation application during re-render, initializes form controls. |
| crates/shell/elidex-shell/src/ipc.rs | Adds IME message variant and ImeKind enum to browser↔content IPC. |
| crates/shell/elidex-shell/src/content_tests.rs | Adjusts keyboard test to focus a tabindex element. |
| crates/shell/elidex-shell/src/content/navigation.rs | New navigation/history action handling (including request override for POST submissions). |
| crates/shell/elidex-shell/src/content/mod.rs | New content-thread main loop with adaptive timeout, animation tick, timers, caret blink, and message dispatch. |
| crates/shell/elidex-shell/src/content/ime.rs | New IME preedit/commit handling with composition event dispatch and maxlength enforcement. |
| crates/shell/elidex-shell/src/content/form_input.rs | New form interaction helpers: checkbox toggle, label click targeting, input/change events, submit/reset navigation. |
| crates/shell/elidex-shell/src/content/focus.rs | New focus lifecycle implementation (focusin/out + blur/focus) and change-on-blur for text controls. |
| crates/shell/elidex-shell/src/content/animation.rs | Dispatches animation/transition lifecycle events produced by the engine into DOM/JS. |
| crates/shell/elidex-shell/src/app/navigation.rs | Updates loader call site to new load_document(..., request) signature. |
| crates/shell/elidex-shell/Cargo.toml | Adds dependencies needed for forms, animation pipeline, and logging (elidex-form, elidex-css-anim, tracing, etc.). |
| crates/shell/elidex-navigation/src/loader.rs | Extends document loader to accept an explicit request (enables POST form submissions). |
| crates/script/elidex-js/src/parser/expr_tests_special.rs | Adds parser tests for special expressions/features (import.meta, new.target, dynamic import, etc.). |
| crates/script/elidex-js/src/parser/expr_tests_operators.rs | Adds parser tests focused on operator precedence/associativity and regressions. |
| crates/script/elidex-js/src/parser/expr_tests_core.rs | Adds shared parser test helpers and core expression parsing tests. |
| crates/script/elidex-js/src/parser/expr.rs | Splits expression tests into multiple modules. |
| crates/script/elidex-js-boa/src/runtime/mod.rs | Adds FocusEvent relatedTarget resolution into JS event objects at dispatch time. |
| crates/script/elidex-js-boa/src/globals/mod.rs | Registers new element form globals module. |
| crates/script/elidex-js-boa/src/globals/events.rs | Adds payload property mapping for transition/animation/input/clipboard/composition/focus events. |
| crates/script/elidex-js-boa/src/globals/element.rs | Registers form-related accessors on Element wrappers. |
| crates/script/elidex-js-boa/Cargo.toml | Adds elidex-form dependency for JS↔form integration. |
| crates/net/elidex-net/src/redirect.rs | Improves redirect method/body/header handling per RFC 9110; adds async test coverage. |
| crates/layout/elidex-layout-block/src/block/mod.rs | Uses elidex-form intrinsic sizing as a replaced-element fallback for form controls. |
| crates/layout/elidex-layout-block/Cargo.toml | Adds elidex-form dependency. |
| crates/dom/elidex-form/src/util.rs | Adds UTF-8/UTF-16 boundary utilities with tests. |
| crates/dom/elidex-form/src/sizing.rs | Adds intrinsic sizing heuristics for common controls with tests. |
| crates/dom/elidex-form/src/selection.rs | Adds selection operations for text controls with tests. |
| crates/dom/elidex-form/src/radio.rs | Adds form-scoped radio group logic, arrow navigation, and tests. |
| crates/dom/elidex-form/src/label.rs | Adds <label> association logic and tests. |
| crates/dom/elidex-form/src/init.rs | Adds bulk/single-entity form control state initialization and fieldset disabled propagation. |
| crates/dom/elidex-form/src/fieldset.rs | Implements disabled fieldset propagation with legend exemption and tests. |
| crates/dom/elidex-form/src/clipboard.rs | Adds copy/cut/paste logic with password safety + maxlength/DoS limits and tests. |
| crates/dom/elidex-form/Cargo.toml | New crate manifest for elidex-form. |
| crates/dom/elidex-dom-compat/src/vendor_prefix.rs | Adds registry-aware compat stylesheet parsing for handler-based property parsing. |
| crates/dom/elidex-dom-compat/src/lib.rs | Re-exports parse_compat_stylesheet_with_registry. |
| crates/dom/elidex-dom-compat/src/legacy_ua.rs | Expands legacy UA stylesheet with baseline form control styles. |
| crates/dom/elidex-a11y/src/tree.rs | Prefers role mapping derived from FormControlState for more accurate a11y roles. |
| crates/dom/elidex-a11y/src/roles.rs | Adds FormControlKind → AccessKit role mapping + tests. |
| crates/dom/elidex-a11y/Cargo.toml | Adds elidex-form dependency. |
| crates/css/elidex-style/src/walk.rs | Attaches/removes AnimStyle during style resolution based on cascaded animation/transition properties. |
| crates/css/elidex-css/src/selector/tests/matching.rs | Adds extensive form pseudo-class matching tests; updates ElementState type to u16 in tests. |
| crates/css/elidex-css/src/parser.rs | Adds registry-aware parsing and @keyframes extraction into Stylesheet::keyframes_raw. |
| crates/css/elidex-css/src/lib.rs | Re-exports parse_stylesheet_with_registry. |
| crates/css/elidex-css/src/declaration.rs | Dispatches unknown properties to plugin registry handler parsing when provided. |
| crates/css/elidex-css-anim/src/resolve.rs | Exposes shared list of animation/transition longhand names for reuse in style walker. |
| crates/css/elidex-css-anim/src/parse_tests.rs | Adds tests for brace matching robustness in keyframes parsing. |
| crates/css/elidex-css-anim/src/parse.rs | Improves brace matching to ignore braces inside string literals/escapes. |
| crates/css/elidex-css-anim/src/lib.rs | Exposes apply module for applying animated values to computed style. |
| crates/css/elidex-css-anim/src/interpolate.rs | Centralizes animatable property list constant and aligns is_animatable with it. |
| crates/css/elidex-css-anim/src/engine_tests.rs | Adds engine tests including has_running semantics and guard cases (NaN/negative dt). |
| crates/css/elidex-css-anim/src/detection.rs | Uses last occurrence for duplicate transition-property entries (spec-correct list cycling); adds test. |
| crates/core/elidex-render/src/builder/walk.rs | Emits form control rendering during display list build. |
| crates/core/elidex-render/src/builder/mod.rs | Registers new form builder module. |
| crates/core/elidex-render/Cargo.toml | Adds elidex-form (and fontdb) dependency for form rendering/font selection. |
| crates/core/elidex-plugin/src/lib.rs | Re-exports new event init types and expands EventPayload variants. |
| crates/core/elidex-plugin/src/event_types.rs | Adds transition/animation/input/clipboard/composition/focus event init structs and payload variants + tests. |
| crates/core/elidex-ecs/src/dom/tests/tree_ops.rs | Adds/expands DOM tree operation tests. |
| crates/core/elidex-ecs/src/dom/tests/shadow_dom.rs | Adds/expands Shadow DOM behavior tests and custom element validation tests. |
| crates/core/elidex-ecs/src/dom/tests/mod.rs | New DOM tests module wiring. |
| crates/core/elidex-ecs/src/dom/tests/destroy.rs | Adds destroy-entity tests including Shadow DOM interactions. |
| crates/core/elidex-ecs/src/dom/tests/creation.rs | Adds creation/attribute/document-root tests. |
| crates/core/elidex-ecs/src/dom.rs | Adds is_contenteditable (inherited) and get_tag_name helper. |
| crates/core/elidex-ecs/src/components.rs | Expands ElementState to u16 and adds form-related flags + set() helper. |
| Cargo.toml | Adds elidex-form workspace member and dependencies (arboard, regex, etc.). |
| Cargo.lock | Locks new crates and dependency graph updates. |
| CLAUDE.md | Updates internal documentation for registry parsing + animation engine pipeline notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Update char_count after setting textarea value from text content, fixing maxlength enforcement for textarea initialization - Add contenteditable to is_focusable() check (HTML §6.6.3) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR significantly expands Elidex’s browser-engine capabilities by adding a new form-controls crate, completing the CSS animation/transition pipeline, and refactoring the shell content thread into a modular event loop with IME + navigation support.
Changes:
- Introduces
elidex-formand wires form control state + interactions into shell, layout, render, and a11y. - Completes CSS animation/transition plumbing: keyframes extraction, AnimStyle attachment, AnimationEngine ticking, and JS event payload support.
- Refactors the shell content thread into
content/modules (navigation, focus, IME, animation dispatch, form input) with an adaptive frame/timer loop.
Reviewed changes
Copilot reviewed 82 out of 83 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/shell/elidex-shell/src/tests.rs | Adds pipeline tests for keyframes registration, AnimStyle attachment, and JS transition/animation event payloads. |
| crates/shell/elidex-shell/src/lib.rs | Adds AnimationEngine + viewport state to PipelineResult; registers keyframes; adds transition detection/apply steps in re-render. |
| crates/shell/elidex-shell/src/ipc.rs | Extends IPC with IME messages and IME event kinds. |
| crates/shell/elidex-shell/src/content_tests.rs | Updates keyboard test HTML to be focusable via tabindex. |
| crates/shell/elidex-shell/src/content/navigation.rs | New navigation/history handler for the content thread (including POST requests). |
| crates/shell/elidex-shell/src/content/mod.rs | New modular content thread event loop with frame ticking, timers, caret blink, viewport updates, and message dispatch. |
| crates/shell/elidex-shell/src/content/ime.rs | New IME composition/commit handling and composition event dispatch. |
| crates/shell/elidex-shell/src/content/form_input.rs | New form interaction helpers: label activation, checkbox toggling, input/change/submit/reset dispatch, GET/POST submission. |
| crates/shell/elidex-shell/src/content/focus.rs | New focus lifecycle implementation with relatedTarget and change-on-blur behavior. |
| crates/shell/elidex-shell/src/content/animation.rs | Dispatches engine animation/transition events into DOM events with payloads. |
| crates/shell/elidex-shell/src/app/navigation.rs | Updates loader call signature to include optional request. |
| crates/shell/elidex-shell/Cargo.toml | Adds dependencies for form controls, animation, clipboard, request bodies, and tracing. |
| crates/shell/elidex-navigation/src/loader.rs | Adds optional request support to enable POST form submissions. |
| crates/script/elidex-js/src/parser/expr_tests_core.rs | New expression parsing test suite split-out (core). |
| crates/script/elidex-js/src/parser/expr_tests_operators.rs | New operator-focused expression parsing tests. |
| crates/script/elidex-js/src/parser/expr_tests_special.rs | New special-case expression parsing tests (import.meta, new.target, yield, regexp ambiguities, etc.). |
| crates/script/elidex-js/src/parser/expr.rs | Splits expression tests into multiple modules. |
| crates/script/elidex-js-boa/src/runtime/mod.rs | Resolves FocusEvent.relatedTarget to an Element wrapper during dispatch. |
| crates/script/elidex-js-boa/src/globals/mod.rs | Adds element_form module for form accessors. |
| crates/script/elidex-js-boa/src/globals/events.rs | Adds payload property mapping for transition/animation/input/clipboard/composition/focus events. |
| crates/script/elidex-js-boa/src/globals/element.rs | Registers form accessors on Element wrappers. |
| crates/script/elidex-js-boa/Cargo.toml | Adds elidex-form dependency. |
| crates/net/elidex-net/src/redirect.rs | Refines redirect method/body behavior and adds a HEAD 301 preservation async test. |
| crates/layout/elidex-layout-block/src/block/mod.rs | Adds intrinsic sizing fallback for form controls when treating them like replaced elements. |
| crates/layout/elidex-layout-block/Cargo.toml | Adds elidex-form dependency. |
| crates/dom/elidex-form/src/util.rs | New UTF-8 boundary + UTF-16 offset utilities (with tests). |
| crates/dom/elidex-form/src/sizing.rs | New intrinsic sizing logic for various form control kinds (with tests). |
| crates/dom/elidex-form/src/selection.rs | New text selection operations for controls (with tests). |
| crates/dom/elidex-form/src/radio.rs | New radio-group toggling + navigation + satisfaction helpers (with tests). |
| crates/dom/elidex-form/src/label.rs | New label-to-control association (for/descendant) logic (with tests). |
| crates/dom/elidex-form/src/init.rs | New DOM-wide and single-entity form control state initialization (with tests). |
| crates/dom/elidex-form/src/fieldset.rs | New fieldset disabled propagation + first-legend exemption (with tests). |
| crates/dom/elidex-form/src/clipboard.rs | New copy/cut/paste helpers with password/maxlength safety (with tests). |
| crates/dom/elidex-form/Cargo.toml | Introduces new elidex-form crate and dependencies. |
| crates/dom/elidex-dom-compat/src/vendor_prefix.rs | Adds parse_compat_stylesheet_with_registry to support handler registry parsing. |
| crates/dom/elidex-dom-compat/src/lib.rs | Re-exports new compat stylesheet parsing entrypoint. |
| crates/dom/elidex-dom-compat/src/legacy_ua.rs | Adds UA styling defaults for form controls and related elements. |
| crates/dom/elidex-a11y/src/tree.rs | Maps FormControlState to more precise AccessKit roles. |
| crates/dom/elidex-a11y/src/roles.rs | Adds form_control_role(FormControlKind) mapping + tests. |
| crates/dom/elidex-a11y/Cargo.toml | Adds elidex-form dependency. |
| crates/css/elidex-style/src/walk.rs | Attaches/removes AnimStyle during style resolution based on resolved animation/transition properties. |
| crates/css/elidex-css/src/selector/tests/matching.rs | Adds pseudo-class matching tests for form-related selectors; updates ElementState width. |
| crates/css/elidex-css/src/parser.rs | Extracts @keyframes blocks and adds parse_stylesheet_with_registry. |
| crates/css/elidex-css/src/lib.rs | Exposes parse_stylesheet_with_registry. |
| crates/css/elidex-css/src/declaration.rs | Adds registry-based fallback dispatch for unknown properties to plugin handlers. |
| crates/css/elidex-css-anim/src/resolve.rs | Exposes shared list of animation/transition longhand property names. |
| crates/css/elidex-css-anim/src/parse_tests.rs | Adds parsing tests for brace-matching inside strings. |
| crates/css/elidex-css-anim/src/parse.rs | Improves brace matching by skipping braces inside string literals. |
| crates/css/elidex-css-anim/src/lib.rs | Exposes new apply module. |
| crates/css/elidex-css-anim/src/interpolate.rs | Consolidates animatable property list into a constant used by detection and tests. |
| crates/css/elidex-css-anim/src/engine_tests.rs | Adds engine-level tests for tick semantics, events, limits, and dt guards. |
| crates/css/elidex-css-anim/src/detection.rs | Uses last-match semantics for duplicate transition-property entries; adds regression test. |
| crates/core/elidex-render/src/builder/walk.rs | Adds form control rendering emission in display list building (caret visibility currently stubbed). |
| crates/core/elidex-render/src/builder/mod.rs | Registers new form rendering module. |
| crates/core/elidex-render/Cargo.toml | Adds form-related dependencies. |
| crates/core/elidex-plugin/src/lib.rs | Re-exports new event init types and payload variants. |
| crates/core/elidex-plugin/src/event_types.rs | Adds init structs and payload variants for transition/animation/input/clipboard/composition/focus events (with tests). |
| crates/core/elidex-ecs/src/dom/tests/* | Adds comprehensive DOM + shadow DOM + tree ops + destroy behavior tests. |
| crates/core/elidex-ecs/src/dom.rs | Adds is_contenteditable() (inherited) and get_tag_name() helper. |
| crates/core/elidex-ecs/src/components.rs | Expands ElementState to u16 with form-related flags and adds set() helper. |
| Cargo.toml | Adds elidex-form, arboard, and regex to the workspace. |
| Cargo.lock | Updates lockfile for new crates/dependencies. |
| CLAUDE.md | Documents registry parsing and AnimationEngine initialization details. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
elidex-form— Full HTML form controls implementation (input types, select, textarea, checkbox/radio, button, fieldset/legend, form submission, constraint validation, text selection, clipboard, IME, caret blink)content.rssplit intocontent/module (mod, focus, event_handlers, ime, animation, navigation, form_input) with adaptive frame loop timeoutKey changes
:required/:optional/:valid/:invalid/:read-only/:read-write/:indeterminatecollect_form_data,encode_form_urlencoded, implicit EnterrelatedTarget(focusout→focusin→blur→focus per UI Events §5.2)elapsed_timef32→f64 propagation throughout animation event chainhas_running()prevents fill-mode:forwards infinite re-render loopStats
Test plan
cargo clippy --workspace -- -D warningspassescargo test --workspace— 2,661 tests pass🤖 Generated with Claude Code