Skip to content

Commit 3ef815e

Browse files
committed
implement KeyboardEvent properties and methods
1 parent f16440d commit 3ef815e

File tree

3 files changed

+148
-57
lines changed

3 files changed

+148
-57
lines changed

src/browser/events/keyboard_event.zig

Lines changed: 101 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,12 @@
1818

1919
const std = @import("std");
2020
const log = @import("../../log.zig");
21+
const builtin = @import("builtin");
2122

2223
const netsurf = @import("../netsurf.zig");
2324
const Event = @import("event.zig").Event;
2425
const JsObject = @import("../env.zig").JsObject;
2526

26-
const c = @cImport({
27-
@cInclude("dom/dom.h");
28-
@cInclude("core/pi.h");
29-
@cInclude("dom/bindings/hubbub/parser.h");
30-
@cInclude("events/event_target.h");
31-
@cInclude("events/event.h");
32-
@cInclude("events/mouse_event.h");
33-
@cInclude("events/keyboard_event.h");
34-
@cInclude("utils/validate.h");
35-
@cInclude("html/html_element.h");
36-
@cInclude("html/html_document.h");
37-
});
38-
3927
// TODO: We currently don't have a UIEvent interface so we skip it in the prototype chain.
4028
// https://developer.mozilla.org/en-US/docs/Web/API/UIEvent
4129
const UIEvent = Event;
@@ -45,51 +33,125 @@ pub const KeyboardEvent = struct {
4533
pub const Self = netsurf.KeyboardEvent;
4634
pub const prototype = *UIEvent;
4735

48-
pub const KeyLocationCode = enum(u16) {
49-
standard = 0x00,
50-
left = 0x01,
51-
right = 0x02,
52-
numpad = 0x03,
53-
mobile = 0x04, // Non-standard, deprecated.
54-
joystick = 0x05, // Non-standard, deprecated.
55-
};
56-
5736
pub const ConstructorOptions = struct {
5837
key: []const u8 = "",
5938
code: []const u8 = "",
60-
location: KeyLocationCode = .standard,
61-
char_code: u32 = 0,
62-
key_code: u32 = 0,
63-
which: u32 = 0,
39+
location: netsurf.KeyboardEventOpts.LocationCode = .standard,
6440
repeat: bool = false,
65-
ctrl_key: bool = false,
66-
shift_key: bool = false,
67-
alt_key: bool = false,
68-
meta_key: bool = false,
69-
is_composing: bool = false,
41+
isComposing: bool = false,
42+
// Currently not supported but we take as argument.
43+
charCode: u32 = 0,
44+
// Currently not supported but we take as argument.
45+
keyCode: u32 = 0,
46+
// Currently not supported but we take as argument.
47+
which: u32 = 0,
48+
ctrlKey: bool = false,
49+
shiftKey: bool = false,
50+
altKey: bool = false,
51+
metaKey: bool = false,
7052
};
7153

7254
pub fn constructor(event_type: []const u8, maybe_options: ?ConstructorOptions) !*netsurf.KeyboardEvent {
73-
const options = maybe_options orelse ConstructorOptions{};
55+
const options: ConstructorOptions = maybe_options orelse .{};
56+
57+
var event = try netsurf.keyboardEventCreate();
58+
try netsurf.eventSetInternalType(@ptrCast(&event), .keyboard_event);
7459

75-
const event = try netsurf.keyboardEventCreate();
7660
try netsurf.keyboardEventInit(
7761
event,
7862
event_type,
7963
.{
80-
.bubbles = false,
81-
.cancelable = false,
8264
.key = options.key,
8365
.code = options.code,
84-
.alt = options.alt_key,
85-
.ctrl = options.ctrl_key,
86-
.meta = options.meta_key,
87-
.shift = options.shift_key,
66+
.location = options.location,
67+
.repeat = options.repeat,
68+
.is_composing = options.isComposing,
69+
.ctrl_key = options.ctrlKey,
70+
.shift_key = options.shiftKey,
71+
.alt_key = options.altKey,
72+
.meta_key = options.metaKey,
8873
},
8974
);
9075

9176
return event;
9277
}
78+
79+
// Returns the modifier state for given modifier key.
80+
pub fn _getModifierState(self: *Self, key: []const u8) bool {
81+
// Chrome and Firefox do case-sensitive match, here we prefer the same.
82+
if (std.mem.eql(u8, key, "Alt")) {
83+
return get_altKey(self);
84+
}
85+
86+
if (std.mem.eql(u8, key, "AltGraph")) {
87+
return (get_altKey(self) and get_ctrlKey(self));
88+
}
89+
90+
if (std.mem.eql(u8, key, "Control")) {
91+
return get_ctrlKey(self);
92+
}
93+
94+
if (std.mem.eql(u8, key, "Shift")) {
95+
return get_shiftKey(self);
96+
}
97+
98+
if (std.mem.eql(u8, key, "Meta") or std.mem.eql(u8, key, "OS")) {
99+
return get_metaKey(self);
100+
}
101+
102+
// Special case for IE.
103+
if (comptime builtin.os.tag == .windows) {
104+
if (std.mem.eql(u8, key, "Win")) {
105+
return get_metaKey(self);
106+
}
107+
}
108+
109+
// getModifierState() also accepts a deprecated virtual modifier named "Accel".
110+
// event.getModifierState("Accel") returns true when at least one of
111+
// KeyboardEvent.ctrlKey or KeyboardEvent.metaKey is true.
112+
//
113+
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState#accel_virtual_modifier
114+
if (std.mem.eql(u8, key, "Accel")) {
115+
return (get_ctrlKey(self) or get_metaKey(self));
116+
}
117+
118+
// TODO: Add support for "CapsLock", "ScrollLock".
119+
return false;
120+
}
121+
122+
// Getters.
123+
124+
pub fn get_altKey(self: *Self) bool {
125+
return netsurf.keyboardEventKeyIsSet(self, .alt);
126+
}
127+
128+
pub fn get_ctrlKey(self: *Self) bool {
129+
return netsurf.keyboardEventKeyIsSet(self, .ctrl);
130+
}
131+
132+
pub fn get_metaKey(self: *Self) bool {
133+
return netsurf.keyboardEventKeyIsSet(self, .meta);
134+
}
135+
136+
pub fn get_shiftKey(self: *Self) bool {
137+
return netsurf.keyboardEventKeyIsSet(self, .shift);
138+
}
139+
140+
pub fn get_isComposing(self: *Self) bool {
141+
return self.is_composing;
142+
}
143+
144+
pub fn get_location(self: *Self) u32 {
145+
return self.location;
146+
}
147+
148+
pub fn get_key(self: *Self) ![]const u8 {
149+
return netsurf.keyboardEventGetKey(self);
150+
}
151+
152+
pub fn get_repeat(self: *Self) bool {
153+
return self.repeat;
154+
}
93155
};
94156

95157
const testing = @import("../../testing.zig");

src/browser/netsurf.zig

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -952,15 +952,44 @@ pub fn keyboardEventDestroy(evt: *KeyboardEvent) void {
952952
c._dom_keyboard_event_destroy(evt);
953953
}
954954

955-
const KeyboardEventOpts = struct {
956-
key: []const u8,
957-
code: []const u8,
955+
pub inline fn keyboardEventKeyIsSet(
956+
evt: *KeyboardEvent,
957+
comptime key: enum { ctrl, alt, shift, meta },
958+
) bool {
959+
var is_set: bool = false;
960+
const err = switch (key) {
961+
.ctrl => c._dom_keyboard_event_get_ctrl_key(evt, &is_set),
962+
.alt => c._dom_keyboard_event_get_alt_key(evt, &is_set),
963+
.shift => c._dom_keyboard_event_get_shift_key(evt, &is_set),
964+
.meta => c._dom_keyboard_event_get_meta_key(evt, &is_set),
965+
};
966+
// None of the earlier can fail.
967+
std.debug.assert(err == c.DOM_NO_ERR);
968+
969+
return is_set;
970+
}
971+
972+
pub const KeyboardEventOpts = struct {
973+
key: []const u8 = "",
974+
code: []const u8 = "",
975+
location: LocationCode = .standard,
976+
repeat: bool = false,
958977
bubbles: bool = false,
959978
cancelable: bool = false,
960-
ctrl: bool = false,
961-
alt: bool = false,
962-
shift: bool = false,
963-
meta: bool = false,
979+
is_composing: bool = false,
980+
ctrl_key: bool = false,
981+
alt_key: bool = false,
982+
shift_key: bool = false,
983+
meta_key: bool = false,
984+
985+
pub const LocationCode = enum(u32) {
986+
standard = c.DOM_KEY_LOCATION_STANDARD,
987+
left = c.DOM_KEY_LOCATION_LEFT,
988+
right = c.DOM_KEY_LOCATION_RIGHT,
989+
numpad = c.DOM_KEY_LOCATION_NUMPAD,
990+
mobile = 0x04, // Non-standard, deprecated.
991+
joystick = 0x05, // Non-standard, deprecated.
992+
};
964993
};
965994

966995
pub fn keyboardEventInit(evt: *KeyboardEvent, typ: []const u8, opts: KeyboardEventOpts) !void {
@@ -973,13 +1002,13 @@ pub fn keyboardEventInit(evt: *KeyboardEvent, typ: []const u8, opts: KeyboardEve
9731002
null, // dom_abstract_view* ?
9741003
try strFromData(opts.key),
9751004
try strFromData(opts.code),
976-
0, // location 0 == standard
977-
opts.ctrl,
978-
opts.shift,
979-
opts.alt,
980-
opts.meta,
981-
false, // repease
982-
false, // is_composiom
1005+
@intFromEnum(opts.location),
1006+
opts.ctrl_key,
1007+
opts.shift_key,
1008+
opts.alt_key,
1009+
opts.meta_key,
1010+
opts.repeat, // repease
1011+
opts.is_composing, // is_composiom
9831012
);
9841013
try DOMErr(err);
9851014
}

src/browser/page.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -942,10 +942,10 @@ pub const Page = struct {
942942
.cancelable = true,
943943
.key = kbe.key,
944944
.code = kbe.code,
945-
.alt = kbe.alt,
946-
.ctrl = kbe.ctrl,
947-
.meta = kbe.meta,
948-
.shift = kbe.shift,
945+
.alt_key = kbe.alt,
946+
.ctrl_key = kbe.ctrl,
947+
.meta_key = kbe.meta,
948+
.shift_key = kbe.shift,
949949
});
950950
_ = try parser.elementDispatchEvent(element, @ptrCast(event));
951951
}

0 commit comments

Comments
 (0)