To reflect the current style attribute, CSSStyleDeclaration now parses
it on init.
Moreover, this PR synchronizes the element's style attribute with the
dynamic changes.
- number: validate against spec grammar (reject "+1", "1.", "Infinity",
"NaN", overflow values like "2e308")
- date: validate YYYY-MM-DD with day-of-month and leap year checks
- time: validate HH:MM[:SS[.sss]]
- month: validate YYYY-MM
- week: validate YYYY-Www with ISO 8601 week count
- datetime-local: validate and normalize (T separator, shortest time)
- color: normalize hex to lowercase per spec
- checkbox/radio: return "on" as default value
- sanitize initial value from HTML attributes in created()
- checkbox/radio getValue() returns "on" when no value attribute set
- color input sanitization normalizes hex to lowercase per spec
- initial input value is sanitized per input type during element creation
- initEvent resets both stop_propagation and stop_immediate_propagation
- dispatchNode resets propagation flags after dispatch per DOM spec step 12
Our BrowsingContext currently supports 1 target. So we have a per-BC target_id.
Previously, our target had 1 "frame" - our page. So we often treated the
targetId as the frameId. But to work with frames, we need page-specific
frameIds and loaderIds.
This tries to clean up our ids (a little). frameIds are now ids derived from
a new incrementing page.id. This page.id has to be passed around (via http
Requests and through notifications) in order to properly generate messages with
a frameId.
Added a get-only `getStyle` which doesn't lazily create a new style if none
exists. This can be used in the (frequently used) `checkVisibility` to avoid
an allocation. Added a specialized getBoundingClientRectForVisible which
skips the checkVisibility check, since a few callers have already done their
own visibility check.
DOMRect is now off the heap. This avoids _a lot_ of allocation when a DOMRect
is only needed for internal calculation, e.g. in Document.elementFromPoint.
implement proper tree-walking in writeTextContent to handle all cases:
same-element containers, cross-container ranges, and comment exclusion.
uncomment ~800 lines of Range tests and add 5 new toString tests.
handleClick() was setting _active_element directly, bypassing
Element.focus() — so no blur/focus events fired on click.
Now calls focus() for input, button, select, textarea, anchor.
focus() and blur() now dispatch all four spec-required FocusEvents:
blur (no bubble) → focusout (bubbles) → focus (no bubble) → focusin (bubbles)
Each event carries the correct relatedTarget: the element gaining focus
for blur/focusout, and the element losing focus for focus/focusin.
All four events are composed per W3C spec.
Relates to #1161
Both insertText() and handleKeydown() were manually concatenating text
to the textarea value, ignoring the current selection range. This uses
the existing innerInsert() method which correctly handles full, partial,
and no-selection states — matching the Input element behavior.