Previously, our window.isSecureContext was hard-coded to false. This commit
(a) reports the correct value and (b) disables [some] secure-context-only APIs
in a non-secure context. This change is somewhat related to the ongoing Service
Worker work and will need to be adjusted accordingly, e.g. when #3562 lands,
the Cache will need to be disabled when isSecureContext == false.
DOM.getFrameOwner answered with the child frame's document instead of the
element hosting it. Clients that map an <iframe> to its frame compare the
backendNodeId it returns with the one they resolved in the parent
(Stagehand's frameLocator/deepLocator, Playwright's contentFrame), so the
lookup never matched and they could not descend into frames.
Return the owner element, as Chrome does, and error for the main frame.
The node writer now emits frameId on frame-owner elements and on document
nodes, which is the other half of that pairing.
Directly improve a couple slow tests (crash_handler actually generating crash
dumps on some systems, e.g. mine). The runWebApiTest prefers to poll for work
when possible rather than a blind sleep -> check loop. (e.g. if we have
websocket connections, prefer an http tick).
For me, it's 22s -> 17s.
Continuation of cleaning up frame ownership (#3549, #3536, #3520, ...).
Element.blur/focus are noop on a frameless element.
AXNode.Writer rejects frameless nodes. DOM.resolveNodes keeps its fallback
bacause it's stateless - just needs the context.
This adds the Cache and CacheStore APIs when ServiceWorker is enabled. Purely
in-memory, tied to the Session's lifetime. These generally don't do unbounded
growth, but simply load a fixed set of resources.
In firefox, when ServiceWorker is disabled, the cache is still available on the
Window. I tied it to the existing --experimental-features serviceworker flag
(at least for now).
- `available_providers` holds the static enum tag names; drop the dupe
loop, its errdefer and the per-string frees.
- `reconcileModel` returns `error.ModelNotAvailable` directly instead of
a `use`/`abort` union the caller only mapped to that same error.
- `runCommand`/`printCommandResult` take `Command.ToolCall`; the caller
already has it, so the unreachable "no tool mapping" branches go.
- `handleSave` reuses `rememberSavePath`, which now propagates its
allocation failure so a first save under OOM warns instead of
unwrapping a null `save_path`.
- `SlashCommand.all_names` is a comptime `++` of the three name lists.
- `buildUserMessageParts` reads the attachment once for both text and
image, and prepends the text part instead of copying the list.
- `printSeverity`/`formatBulletLine` use `allocPrint` and the shared
`emitStderr`; drop an unreachable `ends_ws` check in `renderMetaHint`.
In a REPL whose stderr isn't a tty the spinner is disabled, so
`agentToolDone`'s `emitAbove` returned false and the `● [tool: …]` line
was discarded. `printToolOutcome` already fell back to a raw stderr write
in that case; share that fallback through `emitStderr`.
The non-REPL result line sliced `text` at a byte offset, which could
split a multi-byte codepoint and emit garbage. Truncate on a UTF-8
boundary instead.
Each optional block after the pass count (slowest list, metrics JSON,
failed-test summary) now prints its own leading separator instead of the
previous block printing a trailing one, so the output never ends with an
empty line. Printer.status places the color reset before a trailing
newline so the escape sequence no longer opens the next line.
The Zig 0.16 port of SlowTracker.endTiming dropped the early return for
unnamed tests and discarded the flag, so the refAllDecls blocks were
timed and queued like real tests. With a filter that matches nothing they
were the only candidates and filled the "Slowest 5 tests" output.
Every key path resolves its target through user_input.focusedElement,
which is document.activeElement with the <body> fallback. WebDriver and
the MCP press action used to fall back to the document node instead, a
target no default action or char step handles.
The Enter and Space activation rules share isButton, and the text-entry
rule (no text goes into a checkbox or radio) lives on the TextEntry
mixin as acceptsTextEntry rather than as a type test inside the shared
insertion helper. pressKey takes its extra ref only when a keypress will
be built from the keydown.
Chrome clicks a button on the keypress Enter produces, after the keypress
fires; only links follow Enter on the keydown. Clicking on the keydown put
the click before the keypress and, with the char step also submitting for
button-type inputs, submitted the form twice.
The MCP press action relied on the same char step for Enter, so its own
implicit submission is gone with the double submit it caused on buttons.
The #3549 test only covered LP.getSemanticTree's text format. Cover
the JSON format with interactiveOnly on the same fixture, and drive the
MCP tree and nodeDetails tools through call() with a child-frame
backendNodeId. Passing the main frame in either tool now fails the
suite instead of only tripping a debug assert.
Every caller resolved node.ownerFrame(frame) before building a
SemanticTree or calling getNodeDetails, and every one made the same
decision on a frameless node. Move that into SemanticTree.init, which
returns error.FramelessNode, and turn getNodeDetails into a method so
it goes through the same constructor.
With init as the only entry point the per-method assertOwns is
redundant, so drop it along with its copy of StyleManager's helper.
A nodeId root inside a child frame was walked with the main frame. The
style checks already resolve the owner frame per element, but the
listener map was built from the main frame's event manager, so
listener-only elements in the iframe were reported non-interactive, and
relative hrefs resolved against the parent's base URL.
Resolve the root's owner frame before the walk, as getSemanticTree and
getNodeDetails do.
Follow Chrome's model. A keydown only runs its own default action (Tab,
caret moves, Backspace, Enter activation). Text is typed by the char half
of the press, which fires keypress and then beforeinput/textInput, so
either can veto the edit.
A keyDown carrying `text` runs the char step inline (Puppeteer,
Playwright). A text-less keyDown followed by a `char` message runs it on
the char (chromedp), so each character is typed once. A cancelled
text-less keyDown drops the char that follows it, as Chrome does.
BiDi, WebDriver and the MCP press action go through the same pressKey,
deriving the text from the key. pressKey holds a ref on the keydown for
the keypress it builds, so nothing reads the event after dispatch.
Input.insertText fires beforeinput like a key press does.
Applies the frame-ownership pass to SemanticTree, copying what we did for
StyleManager (1). SemanticTree doesn't visit iframes, so the frame of the root
is the frame/frame._style_manager we need to target for all visited nodes.
Like #3536, it's up to the callers to (a) get the correct frame and (b) decide
what to do on a frameless-node.
(1) https://github.com/lightpanda-io/browser/pull/3536