mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Check if event target has listener before adding it
Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
@@ -37,6 +37,13 @@ pub const EventTarget = struct {
|
|||||||
// TODO: hanle EventListenerOptions
|
// TODO: hanle EventListenerOptions
|
||||||
// see #https://github.com/lightpanda-io/jsruntime-lib/issues/114
|
// see #https://github.com/lightpanda-io/jsruntime-lib/issues/114
|
||||||
) !void {
|
) !void {
|
||||||
|
|
||||||
|
// check if event target has already this listener
|
||||||
|
const lst = try parser.eventTargetHasListener(self, eventType, cbk.id());
|
||||||
|
if (lst != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: when can we free this allocation?
|
// TODO: when can we free this allocation?
|
||||||
const cbk_ptr = try alloc.create(Callback);
|
const cbk_ptr = try alloc.create(Callback);
|
||||||
cbk_ptr.* = cbk;
|
cbk_ptr.* = cbk;
|
||||||
@@ -85,6 +92,14 @@ pub fn testExecFn(
|
|||||||
};
|
};
|
||||||
try checkCases(js_env, &basic);
|
try checkCases(js_env, &basic);
|
||||||
|
|
||||||
|
var basic_twice = [_]Case{
|
||||||
|
.{ .src = "nb = 0", .ex = "0" },
|
||||||
|
.{ .src = "content.addEventListener('basic', cbk)", .ex = "undefined" },
|
||||||
|
.{ .src = "content.dispatchEvent(new Event('basic'))", .ex = "true" },
|
||||||
|
.{ .src = "nb", .ex = "1" },
|
||||||
|
};
|
||||||
|
try checkCases(js_env, &basic_twice);
|
||||||
|
|
||||||
var basic_child = [_]Case{
|
var basic_child = [_]Case{
|
||||||
.{ .src = "nb = 0; evt = undefined; phase = undefined; cur = undefined", .ex = "undefined" },
|
.{ .src = "nb = 0; evt = undefined; phase = undefined; cur = undefined", .ex = "undefined" },
|
||||||
.{ .src = "para.dispatchEvent(new Event('basic'))", .ex = "true" },
|
.{ .src = "para.dispatchEvent(new Event('basic'))", .ex = "true" },
|
||||||
|
|||||||
@@ -458,6 +458,13 @@ const event_handler = struct {
|
|||||||
}
|
}
|
||||||
}.handle;
|
}.handle;
|
||||||
|
|
||||||
|
// EventListener
|
||||||
|
pub const EventListener = c.dom_event_listener;
|
||||||
|
|
||||||
|
pub fn eventListenerGetData(lst: *EventListener) ?*anyopaque {
|
||||||
|
return c.dom_event_listener_get_data(lst);
|
||||||
|
}
|
||||||
|
|
||||||
// EventTarget
|
// EventTarget
|
||||||
pub const EventTarget = c.dom_event_target;
|
pub const EventTarget = c.dom_event_target;
|
||||||
|
|
||||||
@@ -465,6 +472,44 @@ fn eventTargetVtable(et: *EventTarget) c.dom_event_target_vtable {
|
|||||||
return getVtable(c.dom_event_target_vtable, EventTarget, et);
|
return getVtable(c.dom_event_target_vtable, EventTarget, et);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eventTargetHasListener(et: *EventTarget, typ: []const u8, cbk_id: usize) !?*EventListener {
|
||||||
|
const str = try strFromData(typ);
|
||||||
|
|
||||||
|
const EventListenerEntry = c.listener_entry;
|
||||||
|
var current: ?*EventListenerEntry = null;
|
||||||
|
var next: ?*EventListenerEntry = undefined;
|
||||||
|
var lst: ?*EventListener = undefined;
|
||||||
|
|
||||||
|
// iterate over the EventTarget's listeners
|
||||||
|
while (true) {
|
||||||
|
const err = eventTargetVtable(et).iter_event_listener.?(et, str, current, &next, &lst);
|
||||||
|
try DOMErr(err);
|
||||||
|
|
||||||
|
if (lst) |listener| {
|
||||||
|
// the EventTarget has a listener for this event type,
|
||||||
|
// let's check if the callback is the same
|
||||||
|
defer c.dom_event_listener_unref(listener);
|
||||||
|
const data = eventListenerGetData(listener);
|
||||||
|
if (data) |d| {
|
||||||
|
const ptr: *align(@alignOf(*Callback)) anyopaque = @alignCast(d);
|
||||||
|
const cbk = @as(*Callback, @ptrCast(ptr));
|
||||||
|
if (cbk_id == cbk.id())
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next == null) {
|
||||||
|
// no more listeners, end of the iteration
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// next iteration
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eventTargetAddEventListener(
|
pub fn eventTargetAddEventListener(
|
||||||
et: *EventTarget,
|
et: *EventTarget,
|
||||||
typ: []const u8,
|
typ: []const u8,
|
||||||
@@ -473,7 +518,7 @@ pub fn eventTargetAddEventListener(
|
|||||||
) !void {
|
) !void {
|
||||||
const s = try strFromData(typ);
|
const s = try strFromData(typ);
|
||||||
const ctx = @as(*anyopaque, @ptrCast(cbk_ptr));
|
const ctx = @as(*anyopaque, @ptrCast(cbk_ptr));
|
||||||
var listener: ?*c.dom_event_listener = undefined;
|
var listener: ?*EventListener = undefined;
|
||||||
const errLst = c.dom_event_listener_create(event_handler, ctx, &listener);
|
const errLst = c.dom_event_listener_create(event_handler, ctx, &listener);
|
||||||
try DOMErr(errLst);
|
try DOMErr(errLst);
|
||||||
const err = eventTargetVtable(et).add_event_listener.?(et, s, listener, capture);
|
const err = eventTargetVtable(et).add_event_listener.?(et, s, listener, capture);
|
||||||
|
|||||||
2
vendor/jsruntime-lib
vendored
2
vendor/jsruntime-lib
vendored
Submodule vendor/jsruntime-lib updated: 7de65ccd30...637cd3a344
Reference in New Issue
Block a user