Cannot Frame.deinit in window.close() as that's happening inside JS runtime.
Instead, defer on Page.deinit. This is MUCH later than necessary, but I'd like
to address the timing separately. This commit, as-is, prevents real crashes.
Per maintainer review (PR #2310), Lightpanda has no caret/keyboard editing
pipeline, so honoring the spec-correct value risks routing downstream CDP
clients (notably Puppeteer's dispatchKeyEvent path) into an input pipeline
that silently no-ops. Switch to always returning false and emit
log.info(.not_implemented, "IsContentEditable", .{}) when the spec walk
would have produced true, so the unsupported case surfaces in telemetry
rather than masquerading as a working state.
The HTML §7.7.5.2 walk is preserved (nearest ancestor with `contenteditable`
wins, "false" disables) but only used to gate the log emission. The fixture
is reduced to assert the always-false return across the same shape of
inputs, with a comment pointing back at the rationale.
Extract module-loading plumbing into ScriptManagerBase so workers can
use it. Previously Context.script_manager was null for worker contexts,
which crashed on dynamic import() via the unwrap in dynamicModuleCallback.
ScriptManagerBase owns the HTTP fetch + V8 module resolution path
(preloadImport, waitForImport, getAsyncImport, resolveSpecifier, the
Script struct) and reaches per-owner fields through an Owner union.
ScriptManager wraps it for Frame and keeps the parser/DOM-bound surface
(addFromElement, parseImportmap, Frame-specific evaluate tail via
tail_hook). WorkerGlobalScope gets its own ScriptManagerBase directly.
This is similar to the work done in https://github.com/lightpanda-io/browser/pull/2093
which split EventManager into EventManager + EventManagerBase (for the same
reason).
add tests
`Frame.handleClick` had no `.label` arm, so clicking an `HTMLLabelElement`
fired the click event but never dispatched the synthetic click activation
on the labeled control. Per HTML §4.10.4 "The label element", a label's
activation behavior is to run the synthetic click activation steps on the
labeled control; without it `cb.checked` stays unchanged when the click
target is a `<label>`.
Resolve the labeled control via the existing `Label.getControl(frame)`
(handles both `for=` and the wrapping-descendant case) and call `.click()`
on it, mirroring Chrome's `HTMLLabelElement::DefaultEventHandler`.
Closes#2323
When a CDP client pre-arms `LP.handleJavaScriptDialog {accept: true}` with
no `promptText` and the page subsequently calls `window.prompt(message,
defaultText)`, Lightpanda discarded the dialog's `defaultText` argument
and returned `""`. Chrome's behavior is to surface `defaultText` as the
prompt's return value — that's the natural "user accepted without typing
anything" outcome per the HTML simple-dialog algorithm.
The fix is one line in `Window.zig`'s `prompt` JS binding: keep the
second argument named (`default_text` instead of `_`) and use it as the
fallback. Pre-armed `promptText` still wins when the client supplies it;
`accept = false` still returns null regardless. When neither
`promptText` nor `defaultText` is provided, the binding still returns
`""` per the CDP spec.
Adds four new assertions to the existing `cdp.lp` integration test
covering the matrix: defaultText fallback (no promptText), promptText
overrides defaultText, accept=false ignores defaultText, and the
existing no-defaultText case continues to return `""`.
Move FormData from using KeyValueList to using its own List(Entry), where
entry's value is a union over a String or File. Preparatory stuff for input
type=file support.