Skip to content

feat(M4-3): form controls + animation pipeline + content thread frame loop#22

Merged
send merged 12 commits intomainfrom
feat/m4-3-form-frame-loop
Mar 15, 2026
Merged

feat(M4-3): form controls + animation pipeline + content thread frame loop#22
send merged 12 commits intomainfrom
feat/m4-3-form-frame-loop

Conversation

@send
Copy link
Owner

@send send commented Mar 15, 2026

Summary

  • New crate: 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)
  • Animation pipeline completion — AnimationEngine tick connected to 16ms frame loop, keyframe interpolation, transition/animation DOM event dispatch (start/end/iteration/cancel)
  • Content thread refactorcontent.rs split into content/ module (mod, focus, event_handlers, ime, animation, navigation, form_input) with adaptive frame loop timeout
  • 6 rounds of review fixes (R11–R16) — 38 items covering CSS Selectors L4 spec compliance, NaN/Infinity safety guards, DRY helpers, step validation, IME DoS protection

Key changes

  • 15 input types with full validation (required/pattern/minlength/maxlength/min/max/step)
  • CSS pseudo-classes: :required/:optional/:valid/:invalid/:read-only/:read-write/:indeterminate
  • Password bullet masking, radio group exclusivity, select dropdown navigation
  • Form submit/reset with collect_form_data, encode_form_urlencoded, implicit Enter
  • Focus lifecycle with relatedTarget (focusout→focusin→blur→focus per UI Events §5.2)
  • ARIA role mapping for all form controls
  • elapsed_time f32→f64 propagation throughout animation event chain
  • has_running() prevents fill-mode:forwards infinite re-render loop

Stats

  • 76 files changed, +12,295 / −3,562 lines
  • 2,661 tests (up from 2,352), all passing
  • Clippy clean, no warnings

Test plan

  • cargo clippy --workspace -- -D warnings passes
  • cargo test --workspace — 2,661 tests pass
  • Form validation: required, pattern, minlength/maxlength, min/max, step, email/url type
  • Animation events: transitionend/start/run/cancel, animationend/start/iteration/cancel
  • CSS pseudo-class matching: :enabled/:disabled/:checked/:indeterminate scoping
  • NaN/Infinity guards: apply_dimension, keyframe interpolation, frame loop timing
  • IME composition text length cap (10k chars)
  • 6 review rounds (R11–R16): spec conformance, safety, refactoring, production readiness

🤖 Generated with Claude Code

send and others added 5 commits March 13, 2026 21:23
…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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-form crate 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, @keyframes extraction + 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.

send and others added 2 commits March 15, 2026 12:05
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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-form crate 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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-form crate 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, AnimStyle attachment, 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. relatedTarget payload 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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-form crate (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, attach AnimStyle from cascaded winners, tick AnimationEngine in a ~16ms loop, dispatch transition/animation events into JS.
  • Refactors content thread (content/ module split) and extends DOM/JS event payloads (focus relatedTarget, 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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-form and 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.

@send send merged commit f4ef3da into main Mar 15, 2026
13 checks passed
@send send deleted the feat/m4-3-form-frame-loop branch March 15, 2026 03:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants