mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
Merge pull request #1299 from lightpanda-io/cdp-inserttext
backport cdp Input.insertText
This commit is contained in:
@@ -2500,6 +2500,13 @@ pub fn handleKeydown(self: *Page, target: *Node, event: *Event) !void {
|
|||||||
|
|
||||||
// Handle printable characters
|
// Handle printable characters
|
||||||
if (key.isPrintable()) {
|
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 current_value = input.getValue();
|
||||||
const new_value = try std.mem.concat(self.arena, u8, &.{ current_value, key.asString() });
|
const new_value = try std.mem.concat(self.arena, u8, &.{ current_value, key.asString() });
|
||||||
try input.setValue(new_value, self);
|
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);
|
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 {
|
const RequestCookieOpts = struct {
|
||||||
is_http: bool = true,
|
is_http: bool = true,
|
||||||
is_navigation: bool = false,
|
is_navigation: bool = false,
|
||||||
|
|||||||
@@ -594,6 +594,11 @@ pub fn getAdoptedStyleSheets(self: *Document, page: *Page) !js.Object {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hasFocus(_: *Document) bool {
|
||||||
|
log.debug(.not_implemented, "Document.hasFocus", .{});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setAdoptedStyleSheets(self: *Document, sheets: js.Object) !void {
|
pub fn setAdoptedStyleSheets(self: *Document, sheets: js.Object) !void {
|
||||||
self._adopted_style_sheets = try sheets.persist();
|
self._adopted_style_sheets = try sheets.persist();
|
||||||
}
|
}
|
||||||
@@ -675,6 +680,7 @@ pub const JsApi = struct {
|
|||||||
return page.window;
|
return page.window;
|
||||||
}
|
}
|
||||||
}.defaultView, null, .{ .cache = "defaultView" });
|
}.defaultView, null, .{ .cache = "defaultView" });
|
||||||
|
pub const hasFocus = bridge.function(Document.hasFocus, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ _value: ?[]const u8 = null,
|
|||||||
_checked: bool = false,
|
_checked: bool = false,
|
||||||
_checked_dirty: bool = false,
|
_checked_dirty: bool = false,
|
||||||
_input_type: Type = .text,
|
_input_type: Type = .text,
|
||||||
|
_selected: bool = false,
|
||||||
|
|
||||||
pub fn asElement(self: *Input) *Element {
|
pub fn asElement(self: *Input) *Element {
|
||||||
return self._proto._proto;
|
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 {
|
pub fn getForm(self: *Input, page: *Page) ?*Form {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
@@ -337,6 +342,7 @@ pub const JsApi = struct {
|
|||||||
pub const size = bridge.accessor(Input.getSize, Input.setSize, .{});
|
pub const size = bridge.accessor(Input.getSize, Input.setSize, .{});
|
||||||
pub const src = bridge.accessor(Input.getSrc, Input.setSrc, .{});
|
pub const src = bridge.accessor(Input.getSrc, Input.setSrc, .{});
|
||||||
pub const form = bridge.accessor(Input.getForm, null, .{});
|
pub const form = bridge.accessor(Input.getForm, null, .{});
|
||||||
|
pub const select = bridge.function(Input.select, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Build = struct {
|
pub const Build = struct {
|
||||||
|
|||||||
@@ -22,11 +22,13 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
dispatchKeyEvent,
|
dispatchKeyEvent,
|
||||||
dispatchMouseEvent,
|
dispatchMouseEvent,
|
||||||
|
insertText,
|
||||||
}, cmd.input.action) orelse return error.UnknownMethod;
|
}, cmd.input.action) orelse return error.UnknownMethod;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
.dispatchKeyEvent => return dispatchKeyEvent(cmd),
|
.dispatchKeyEvent => return dispatchKeyEvent(cmd),
|
||||||
.dispatchMouseEvent => return dispatchMouseEvent(cmd),
|
.dispatchMouseEvent => return dispatchMouseEvent(cmd),
|
||||||
|
.insertText => return insertText(cmd),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +103,20 @@ fn dispatchMouseEvent(cmd: anytype) !void {
|
|||||||
// result already sent
|
// 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 {
|
fn clickNavigate(cmd: anytype, uri: std.Uri) !void {
|
||||||
const bc = cmd.browser_context.?;
|
const bc = cmd.browser_context.?;
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ fn logLogfmt(comptime scope: Scope, level: Level, comptime msg: []const u8, data
|
|||||||
inline for (@typeInfo(@TypeOf(data)).@"struct".fields) |f| {
|
inline for (@typeInfo(@TypeOf(data)).@"struct".fields) |f| {
|
||||||
const value = @field(data, f.name);
|
const value = @field(data, f.name);
|
||||||
if (std.meta.hasMethod(@TypeOf(value), "logFmt")) {
|
if (std.meta.hasMethod(@TypeOf(value), "logFmt")) {
|
||||||
try value.logFmt(f.name, LogFormatWriter{.writer = writer});
|
try value.logFmt(f.name, LogFormatWriter{ .writer = writer });
|
||||||
} else {
|
} else {
|
||||||
const key = " " ++ f.name ++ "=";
|
const key = " " ++ f.name ++ "=";
|
||||||
try writer.writeAll(key);
|
try writer.writeAll(key);
|
||||||
|
|||||||
Reference in New Issue
Block a user