Merge pull request #1299 from lightpanda-io/cdp-inserttext

backport cdp Input.insertText
This commit is contained in:
Karl Seguin
2025-12-29 19:11:46 +08:00
committed by GitHub
5 changed files with 67 additions and 1 deletions

View File

@@ -2500,6 +2500,13 @@ pub fn handleKeydown(self: *Page, target: *Node, event: *Event) !void {
// Handle printable characters
if (key.isPrintable()) {
// if the input is selected, replace the content.
if (input._selected) {
const new_value = try self.arena.dupe(u8, key.asString());
try input.setValue(new_value, self);
input._selected = false;
return;
}
const current_value = input.getValue();
const new_value = try std.mem.concat(self.arena, u8, &.{ current_value, key.asString() });
try input.setValue(new_value, self);
@@ -2561,6 +2568,37 @@ pub fn submitForm(self: *Page, submitter_: ?*Element, form_: ?*Element.Html.Form
return self.scheduleNavigation(action, opts, .form);
}
// insertText is a shortcut to insert text into the active element.
pub fn insertText(self: *Page, v: []const u8) !void {
const html_element = self.document._active_element orelse return;
if (html_element.is(Element.Html.Input)) |input| {
const input_type = input._input_type;
if (input_type == .radio or input_type == .checkbox) {
return;
}
// If the input is selected, replace the existing value
if (input._selected) {
const new_value = try self.arena.dupe(u8, v);
try input.setValue(new_value, self);
input._selected = false;
return;
}
// Or append the value
const current_value = input.getValue();
const new_value = try std.mem.concat(self.arena, u8, &.{ current_value, v });
return input.setValue(new_value, self);
}
if (html_element.is(Element.Html.TextArea)) |textarea| {
const current_value = textarea.getValue();
const new_value = try std.mem.concat(self.arena, u8, &.{ current_value, v });
return textarea.setValue(new_value, self);
}
}
const RequestCookieOpts = struct {
is_http: bool = true,
is_navigation: bool = false,

View File

@@ -594,6 +594,11 @@ pub fn getAdoptedStyleSheets(self: *Document, page: *Page) !js.Object {
return obj;
}
pub fn hasFocus(_: *Document) bool {
log.debug(.not_implemented, "Document.hasFocus", .{});
return true;
}
pub fn setAdoptedStyleSheets(self: *Document, sheets: js.Object) !void {
self._adopted_style_sheets = try sheets.persist();
}
@@ -675,6 +680,7 @@ pub const JsApi = struct {
return page.window;
}
}.defaultView, null, .{ .cache = "defaultView" });
pub const hasFocus = bridge.function(Document.hasFocus, .{});
};
const testing = @import("../../testing.zig");

View File

@@ -75,6 +75,7 @@ _value: ?[]const u8 = null,
_checked: bool = false,
_checked_dirty: bool = false,
_input_type: Type = .text,
_selected: bool = false,
pub fn asElement(self: *Input) *Element {
return self._proto._proto;
@@ -246,6 +247,10 @@ pub fn setRequired(self: *Input, required: bool, page: *Page) !void {
}
}
pub fn select(self: *Input) void {
self._selected = true;
}
pub fn getForm(self: *Input, page: *Page) ?*Form {
const element = self.asElement();
@@ -337,6 +342,7 @@ pub const JsApi = struct {
pub const size = bridge.accessor(Input.getSize, Input.setSize, .{});
pub const src = bridge.accessor(Input.getSrc, Input.setSrc, .{});
pub const form = bridge.accessor(Input.getForm, null, .{});
pub const select = bridge.function(Input.select, .{});
};
pub const Build = struct {

View File

@@ -22,11 +22,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),
}
}
@@ -101,6 +103,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.?;