From 0aaed08c1ea9127b310136e499a45da3f15b2f3d Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 15 Oct 2025 13:52:21 +0200 Subject: [PATCH 1/3] cdp: add input.insertText --- src/browser/page.zig | 25 +++++++++++++++++++++++++ src/cdp/domains/input.zig | 16 ++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/browser/page.zig b/src/browser/page.zig index d668b67c..833c683f 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -1013,6 +1013,31 @@ pub const Page = struct { } } + // insertText is a shortcut to insert text into the active element. + pub fn insertText(self: *Page, v: []const u8) !void { + const Document = @import("dom/document.zig").Document; + const element = (try Document.getActiveElement(@ptrCast(self.window.document), self)) orelse return; + const node = parser.elementToNode(element); + + const tag = (try parser.nodeHTMLGetTagType(node)) orelse return; + switch (tag) { + .input => { + const input_type = try parser.inputGetType(@ptrCast(element)); + if (std.mem.eql(u8, input_type, "text")) { + const value = try parser.inputGetValue(@ptrCast(element)); + const new_value = try std.mem.concat(self.arena, u8, &.{ value, v }); + try parser.inputSetValue(@ptrCast(element), new_value); + } + }, + .textarea => { + const value = try parser.textareaGetValue(@ptrCast(node)); + const new_value = try std.mem.concat(self.arena, u8, &.{ value, v }); + try parser.textareaSetValue(@ptrCast(node), new_value); + }, + else => {}, + } + } + // We cannot navigate immediately as navigating will delete the DOM tree, // which holds this event's node. // As such we schedule the function to be called as soon as possible. diff --git a/src/cdp/domains/input.zig b/src/cdp/domains/input.zig index d81fb1c8..94986a27 100644 --- a/src/cdp/domains/input.zig +++ b/src/cdp/domains/input.zig @@ -23,11 +23,13 @@ pub fn processMessage(cmd: anytype) !void { const action = std.meta.stringToEnum(enum { dispatchKeyEvent, dispatchMouseEvent, + insertText, }, cmd.input.action) orelse return error.UnknownMethod; switch (action) { .dispatchKeyEvent => return dispatchKeyEvent(cmd), .dispatchMouseEvent => return dispatchMouseEvent(cmd), + .insertText => return insertText(cmd), } } @@ -115,6 +117,20 @@ fn dispatchMouseEvent(cmd: anytype) !void { // result already sent } +// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-insertText +fn insertText(cmd: anytype) !void { + const params = (try cmd.params(struct { + text: []const u8, // The text to insert + })) orelse return error.InvalidParams; + + const bc = cmd.browser_context orelse return; + const page = bc.session.currentPage() orelse return; + + try page.insertText(params.text); + + try cmd.sendResult(null, .{}); +} + fn clickNavigate(cmd: anytype, uri: std.Uri) !void { const bc = cmd.browser_context.?; From 09be5e23f12126d1ad815caae6c428dd8f3eddc1 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 15 Oct 2025 15:32:27 +0200 Subject: [PATCH 2/3] add input.select placeholder --- src/browser/html/elements.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/browser/html/elements.zig b/src/browser/html/elements.zig index a3104fa3..9673db69 100644 --- a/src/browser/html/elements.zig +++ b/src/browser/html/elements.zig @@ -732,6 +732,9 @@ pub const HTMLInputElement = struct { pub fn set_value(self: *parser.Input, value: []const u8) !void { try parser.inputSetValue(self, value); } + pub fn _select(_: *parser.Input) void { + log.debug(.web_api, "not implemented", .{ .feature = "HTMLInputElement select" }); + } }; pub const HTMLLIElement = struct { From 14a23123c01254dba0fb79cebb607d5b94f60bc4 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 15 Oct 2025 15:34:06 +0200 Subject: [PATCH 3/3] add Document.hasFocus placeholder --- src/browser/dom/document.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/browser/dom/document.zig b/src/browser/dom/document.zig index fc65ad0a..db675aea 100644 --- a/src/browser/dom/document.zig +++ b/src/browser/dom/document.zig @@ -17,6 +17,7 @@ // along with this program. If not, see . const std = @import("std"); +const log = @import("../../log.zig"); const js = @import("../js/js.zig"); const parser = @import("../netsurf.zig"); @@ -313,6 +314,11 @@ pub const Document = struct { const state = try page.getOrCreateNodeState(@ptrCast(@alignCast(self))); state.adopted_style_sheets = try sheets.persist(); } + + pub fn _hasFocus(_: *parser.Document) bool { + log.debug(.web_api, "not implemented", .{ .feature = "Document hasFocus" }); + return true; + } }; const testing = @import("../../testing.zig");