mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-05 14:57:11 +00:00
move everything to global_event_handlers.zig
This commit is contained in:
@@ -65,6 +65,9 @@ const timestamp = @import("../datetime.zig").timestamp;
|
|||||||
const milliTimestamp = @import("../datetime.zig").milliTimestamp;
|
const milliTimestamp = @import("../datetime.zig").milliTimestamp;
|
||||||
|
|
||||||
const WebApiURL = @import("webapi/URL.zig");
|
const WebApiURL = @import("webapi/URL.zig");
|
||||||
|
const global_event_handlers = @import("webapi/global_event_handlers.zig");
|
||||||
|
const GlobalEventHandlersLookup = global_event_handlers.Lookup;
|
||||||
|
const GlobalEventHandler = global_event_handlers.Handler;
|
||||||
|
|
||||||
var default_url = WebApiURL{ ._raw = "about:blank" };
|
var default_url = WebApiURL{ ._raw = "about:blank" };
|
||||||
pub var default_location: Location = Location{ ._url = &default_url };
|
pub var default_location: Location = Location{ ._url = &default_url };
|
||||||
@@ -119,7 +122,7 @@ _element_assigned_slots: Element.AssignedSlotLookup = .{},
|
|||||||
/// ```js
|
/// ```js
|
||||||
/// img.setAttribute("onload", "(() => { ... })()");
|
/// img.setAttribute("onload", "(() => { ... })()");
|
||||||
/// ```
|
/// ```
|
||||||
_element_attr_listeners: Element.AttrListenerLookup = .{},
|
_element_attr_listeners: GlobalEventHandlersLookup = .{},
|
||||||
|
|
||||||
_script_manager: ScriptManager,
|
_script_manager: ScriptManager,
|
||||||
|
|
||||||
@@ -1215,7 +1218,7 @@ pub fn getElementByIdFromNode(self: *Page, node: *Node, id: []const u8) ?*Elemen
|
|||||||
pub fn setAttrListener(
|
pub fn setAttrListener(
|
||||||
self: *Page,
|
self: *Page,
|
||||||
element: *Element,
|
element: *Element,
|
||||||
listener_type: Element.KnownListener,
|
listener_type: GlobalEventHandler,
|
||||||
listener_callback: JS.Function.Global,
|
listener_callback: JS.Function.Global,
|
||||||
) !void {
|
) !void {
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
@@ -1225,7 +1228,7 @@ pub fn setAttrListener(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = element.calcAttrListenerKey(listener_type);
|
const key = global_event_handlers.calculateKey(element.asEventTarget(), listener_type);
|
||||||
const gop = try self._element_attr_listeners.getOrPut(self.arena, key);
|
const gop = try self._element_attr_listeners.getOrPut(self.arena, key);
|
||||||
gop.value_ptr.* = listener_callback;
|
gop.value_ptr.* = listener_callback;
|
||||||
}
|
}
|
||||||
@@ -1234,9 +1237,10 @@ pub fn setAttrListener(
|
|||||||
pub fn getAttrListener(
|
pub fn getAttrListener(
|
||||||
self: *const Page,
|
self: *const Page,
|
||||||
element: *Element,
|
element: *Element,
|
||||||
listener_type: Element.KnownListener,
|
listener_type: GlobalEventHandler,
|
||||||
) ?JS.Function.Global {
|
) ?JS.Function.Global {
|
||||||
return self._element_attr_listeners.get(element.calcAttrListenerKey(listener_type));
|
const key = global_event_handlers.calculateKey(element.asEventTarget(), listener_type);
|
||||||
|
return self._element_attr_listeners.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerPerformanceObserver(self: *Page, observer: *PerformanceObserver) !void {
|
pub fn registerPerformanceObserver(self: *Page, observer: *PerformanceObserver) !void {
|
||||||
|
|||||||
@@ -49,129 +49,6 @@ pub const RelListLookup = std.AutoHashMapUnmanaged(*Element, *collections.DOMTok
|
|||||||
pub const ShadowRootLookup = std.AutoHashMapUnmanaged(*Element, *ShadowRoot);
|
pub const ShadowRootLookup = std.AutoHashMapUnmanaged(*Element, *ShadowRoot);
|
||||||
pub const AssignedSlotLookup = std.AutoHashMapUnmanaged(*Element, *Html.Slot);
|
pub const AssignedSlotLookup = std.AutoHashMapUnmanaged(*Element, *Html.Slot);
|
||||||
|
|
||||||
/// Better to discriminate it since not directly a pointer int.
|
|
||||||
///
|
|
||||||
/// See `calcAttrListenerKey` to obtain one.
|
|
||||||
const AttrListenerKey = u64;
|
|
||||||
/// Use `getAttrListenerKey` to create a key.
|
|
||||||
pub const AttrListenerLookup = std.AutoHashMapUnmanaged(AttrListenerKey, js.Function.Global);
|
|
||||||
|
|
||||||
/// Enum of known event listeners; increasing the size of it (u7)
|
|
||||||
/// can cause `AttrListenerKey` to behave incorrectly.
|
|
||||||
pub const KnownListener = enum(u7) {
|
|
||||||
onabort,
|
|
||||||
onanimationcancel,
|
|
||||||
onanimationend,
|
|
||||||
onanimationiteration,
|
|
||||||
onanimationstart,
|
|
||||||
onauxclick,
|
|
||||||
onbeforeinput,
|
|
||||||
onbeforematch,
|
|
||||||
onbeforetoggle,
|
|
||||||
onblur,
|
|
||||||
oncancel,
|
|
||||||
oncanplay,
|
|
||||||
oncanplaythrough,
|
|
||||||
onchange,
|
|
||||||
onclick,
|
|
||||||
onclose,
|
|
||||||
oncommand,
|
|
||||||
oncontentvisibilityautostatechange,
|
|
||||||
oncontextlost,
|
|
||||||
oncontextmenu,
|
|
||||||
oncontextrestored,
|
|
||||||
oncopy,
|
|
||||||
oncuechange,
|
|
||||||
oncut,
|
|
||||||
ondblclick,
|
|
||||||
ondrag,
|
|
||||||
ondragend,
|
|
||||||
ondragenter,
|
|
||||||
ondragexit,
|
|
||||||
ondragleave,
|
|
||||||
ondragover,
|
|
||||||
ondragstart,
|
|
||||||
ondrop,
|
|
||||||
ondurationchange,
|
|
||||||
onemptied,
|
|
||||||
onended,
|
|
||||||
onerror,
|
|
||||||
onfocus,
|
|
||||||
onformdata,
|
|
||||||
onfullscreenchange,
|
|
||||||
onfullscreenerror,
|
|
||||||
ongotpointercapture,
|
|
||||||
oninput,
|
|
||||||
oninvalid,
|
|
||||||
onkeydown,
|
|
||||||
onkeypress,
|
|
||||||
onkeyup,
|
|
||||||
onload,
|
|
||||||
onloadeddata,
|
|
||||||
onloadedmetadata,
|
|
||||||
onloadstart,
|
|
||||||
onlostpointercapture,
|
|
||||||
onmousedown,
|
|
||||||
onmousemove,
|
|
||||||
onmouseout,
|
|
||||||
onmouseover,
|
|
||||||
onmouseup,
|
|
||||||
onpaste,
|
|
||||||
onpause,
|
|
||||||
onplay,
|
|
||||||
onplaying,
|
|
||||||
onpointercancel,
|
|
||||||
onpointerdown,
|
|
||||||
onpointerenter,
|
|
||||||
onpointerleave,
|
|
||||||
onpointermove,
|
|
||||||
onpointerout,
|
|
||||||
onpointerover,
|
|
||||||
onpointerrawupdate,
|
|
||||||
onpointerup,
|
|
||||||
onprogress,
|
|
||||||
onratechange,
|
|
||||||
onreset,
|
|
||||||
onresize,
|
|
||||||
onscroll,
|
|
||||||
onscrollend,
|
|
||||||
onsecuritypolicyviolation,
|
|
||||||
onseeked,
|
|
||||||
onseeking,
|
|
||||||
onselect,
|
|
||||||
onselectionchange,
|
|
||||||
onselectstart,
|
|
||||||
onslotchange,
|
|
||||||
onstalled,
|
|
||||||
onsubmit,
|
|
||||||
onsuspend,
|
|
||||||
ontimeupdate,
|
|
||||||
ontoggle,
|
|
||||||
ontransitioncancel,
|
|
||||||
ontransitionend,
|
|
||||||
ontransitionrun,
|
|
||||||
ontransitionstart,
|
|
||||||
onvolumechange,
|
|
||||||
onwaiting,
|
|
||||||
onwheel,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Calculates a lookup key (`AttrListenerKey`) to use with `AttrListenerLookup` for an element.
|
|
||||||
/// NEVER use generated key to retrieve a pointer back. Portability is not guaranteed.
|
|
||||||
pub fn calcAttrListenerKey(self: *Element, event_type: KnownListener) AttrListenerKey {
|
|
||||||
// We can use `Element` for the key too; `EventTarget` is strict about
|
|
||||||
// its size and alignment, though.
|
|
||||||
const target = self.asEventTarget();
|
|
||||||
// Check if we have 3 bits available from alignment of 8.
|
|
||||||
lp.assert(@alignOf(@TypeOf(target)) == 8, "calcAttrListenerKey: incorrect alignment", .{
|
|
||||||
.event_target_alignment = @alignOf(@TypeOf(target)),
|
|
||||||
});
|
|
||||||
|
|
||||||
const ptr = @intFromPtr(target) >> 3;
|
|
||||||
lp.assert(ptr < (1 << 57), "calcAttrListenerKey: pointer overflow", .{ .ptr = ptr });
|
|
||||||
return ptr | (@as(u64, @intFromEnum(event_type)) << 57);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Namespace = enum(u8) {
|
pub const Namespace = enum(u8) {
|
||||||
html,
|
html,
|
||||||
svg,
|
svg,
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ const js = @import("../../js/js.zig");
|
|||||||
const reflect = @import("../../reflect.zig");
|
const reflect = @import("../../reflect.zig");
|
||||||
const log = @import("../../../log.zig");
|
const log = @import("../../../log.zig");
|
||||||
|
|
||||||
|
const global_event_handlers = @import("../global_event_handlers.zig");
|
||||||
|
const GlobalEventHandlersLookup = global_event_handlers.Lookup;
|
||||||
|
const GlobalEventHandler = global_event_handlers.Handler;
|
||||||
|
|
||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
const Node = @import("../Node.zig");
|
const Node = @import("../Node.zig");
|
||||||
const Element = @import("../Element.zig");
|
const Element = @import("../Element.zig");
|
||||||
@@ -335,7 +339,7 @@ pub fn click(self: *HtmlElement, page: *Page) !void {
|
|||||||
|
|
||||||
fn getAttributeFunction(
|
fn getAttributeFunction(
|
||||||
self: *HtmlElement,
|
self: *HtmlElement,
|
||||||
listener_type: Element.KnownListener,
|
listener_type: GlobalEventHandler,
|
||||||
page: *Page,
|
page: *Page,
|
||||||
) !?js.Function.Global {
|
) !?js.Function.Global {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|||||||
145
src/browser/webapi/global_event_handlers.zig
Normal file
145
src/browser/webapi/global_event_handlers.zig
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// Copyright (C) 2023-2026 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const lp = @import("lightpanda");
|
||||||
|
|
||||||
|
const js = @import("../js/js.zig");
|
||||||
|
|
||||||
|
const EventTarget = @import("EventTarget.zig");
|
||||||
|
|
||||||
|
/// Better to discriminate it since not directly a pointer int.
|
||||||
|
///
|
||||||
|
/// See `calculateKey` to obtain one.
|
||||||
|
const Key = u64;
|
||||||
|
|
||||||
|
/// Use `calculateKey` to create a key.
|
||||||
|
pub const Lookup = std.AutoHashMapUnmanaged(Key, js.Function.Global);
|
||||||
|
|
||||||
|
/// Enum of known event listeners; increasing the size of it (u7)
|
||||||
|
/// can cause `Key` to behave incorrectly.
|
||||||
|
pub const Handler = enum(u7) {
|
||||||
|
onabort,
|
||||||
|
onanimationcancel,
|
||||||
|
onanimationend,
|
||||||
|
onanimationiteration,
|
||||||
|
onanimationstart,
|
||||||
|
onauxclick,
|
||||||
|
onbeforeinput,
|
||||||
|
onbeforematch,
|
||||||
|
onbeforetoggle,
|
||||||
|
onblur,
|
||||||
|
oncancel,
|
||||||
|
oncanplay,
|
||||||
|
oncanplaythrough,
|
||||||
|
onchange,
|
||||||
|
onclick,
|
||||||
|
onclose,
|
||||||
|
oncommand,
|
||||||
|
oncontentvisibilityautostatechange,
|
||||||
|
oncontextlost,
|
||||||
|
oncontextmenu,
|
||||||
|
oncontextrestored,
|
||||||
|
oncopy,
|
||||||
|
oncuechange,
|
||||||
|
oncut,
|
||||||
|
ondblclick,
|
||||||
|
ondrag,
|
||||||
|
ondragend,
|
||||||
|
ondragenter,
|
||||||
|
ondragexit,
|
||||||
|
ondragleave,
|
||||||
|
ondragover,
|
||||||
|
ondragstart,
|
||||||
|
ondrop,
|
||||||
|
ondurationchange,
|
||||||
|
onemptied,
|
||||||
|
onended,
|
||||||
|
onerror,
|
||||||
|
onfocus,
|
||||||
|
onformdata,
|
||||||
|
onfullscreenchange,
|
||||||
|
onfullscreenerror,
|
||||||
|
ongotpointercapture,
|
||||||
|
oninput,
|
||||||
|
oninvalid,
|
||||||
|
onkeydown,
|
||||||
|
onkeypress,
|
||||||
|
onkeyup,
|
||||||
|
onload,
|
||||||
|
onloadeddata,
|
||||||
|
onloadedmetadata,
|
||||||
|
onloadstart,
|
||||||
|
onlostpointercapture,
|
||||||
|
onmousedown,
|
||||||
|
onmousemove,
|
||||||
|
onmouseout,
|
||||||
|
onmouseover,
|
||||||
|
onmouseup,
|
||||||
|
onpaste,
|
||||||
|
onpause,
|
||||||
|
onplay,
|
||||||
|
onplaying,
|
||||||
|
onpointercancel,
|
||||||
|
onpointerdown,
|
||||||
|
onpointerenter,
|
||||||
|
onpointerleave,
|
||||||
|
onpointermove,
|
||||||
|
onpointerout,
|
||||||
|
onpointerover,
|
||||||
|
onpointerrawupdate,
|
||||||
|
onpointerup,
|
||||||
|
onprogress,
|
||||||
|
onratechange,
|
||||||
|
onreset,
|
||||||
|
onresize,
|
||||||
|
onscroll,
|
||||||
|
onscrollend,
|
||||||
|
onsecuritypolicyviolation,
|
||||||
|
onseeked,
|
||||||
|
onseeking,
|
||||||
|
onselect,
|
||||||
|
onselectionchange,
|
||||||
|
onselectstart,
|
||||||
|
onslotchange,
|
||||||
|
onstalled,
|
||||||
|
onsubmit,
|
||||||
|
onsuspend,
|
||||||
|
ontimeupdate,
|
||||||
|
ontoggle,
|
||||||
|
ontransitioncancel,
|
||||||
|
ontransitionend,
|
||||||
|
ontransitionrun,
|
||||||
|
ontransitionstart,
|
||||||
|
onvolumechange,
|
||||||
|
onwaiting,
|
||||||
|
onwheel,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Calculates a lookup key to use with lookup for event target.
|
||||||
|
/// NEVER use generated key to retrieve a pointer back. Portability is not guaranteed.
|
||||||
|
pub fn calculateKey(event_target: *EventTarget, handler_type: Handler) Key {
|
||||||
|
// Check if we have 3 bits available from alignment of 8.
|
||||||
|
lp.assert(@alignOf(EventTarget) == 8, "calculateKey: incorrect alignment", .{
|
||||||
|
.event_target_alignment = @alignOf(EventTarget),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ptr = @intFromPtr(event_target) >> 3;
|
||||||
|
lp.assert(ptr < (1 << 57), "calculateKey: pointer overflow", .{ .ptr = ptr });
|
||||||
|
return ptr | (@as(Key, @intFromEnum(handler_type)) << 57);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user