mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-30 15:41:48 +00:00
Updates, fix and Event properties
Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
@@ -8,12 +8,23 @@ const checkCases = jsruntime.test_utils.checkCases;
|
|||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
const DOMException = @import("exceptions.zig").DOMException;
|
const DOMException = @import("exceptions.zig").DOMException;
|
||||||
|
const Nod = @import("node.zig");
|
||||||
|
|
||||||
|
// EventTarget interfaces
|
||||||
|
pub const Union = Nod.Union;
|
||||||
|
|
||||||
|
// EventTarget implementation
|
||||||
pub const EventTarget = struct {
|
pub const EventTarget = struct {
|
||||||
pub const Self = parser.EventTarget;
|
pub const Self = parser.EventTarget;
|
||||||
pub const Exception = DOMException;
|
pub const Exception = DOMException;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
|
pub fn toInterface(et: *parser.EventTarget) !Union {
|
||||||
|
// NOTE: for now we state that all EventTarget are Nodes
|
||||||
|
// TODO: handle other types (eg. Window)
|
||||||
|
return Nod.Node.toInterface(@as(*parser.Node, @ptrCast(et)));
|
||||||
|
}
|
||||||
|
|
||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
@@ -22,11 +33,14 @@ pub const EventTarget = struct {
|
|||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
eventType: []const u8,
|
eventType: []const u8,
|
||||||
cbk: Callback,
|
cbk: Callback,
|
||||||
|
capture: ?bool,
|
||||||
|
// TODO: hanle EventListenerOptions
|
||||||
|
// see #https://github.com/lightpanda-io/jsruntime-lib/issues/114
|
||||||
) !void {
|
) !void {
|
||||||
// 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;
|
||||||
try parser.eventTargetAddEventListener(self, eventType, cbk_ptr);
|
try parser.eventTargetAddEventListener(self, eventType, cbk_ptr, capture orelse false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _dispatchEvent(self: *parser.EventTarget, event: *parser.Event) !bool {
|
pub fn _dispatchEvent(self: *parser.EventTarget, event: *parser.Event) !bool {
|
||||||
@@ -46,9 +60,25 @@ pub fn testExecFn(
|
|||||||
var basic = [_]Case{
|
var basic = [_]Case{
|
||||||
.{ .src = "let event = new Event('myEvent')", .ex = "undefined" },
|
.{ .src = "let event = new Event('myEvent')", .ex = "undefined" },
|
||||||
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
|
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
|
||||||
.{ .src = "var nb = 0; content.addEventListener('myEvent', function(event) {nb ++;})", .ex = "undefined" },
|
.{ .src =
|
||||||
|
\\var nb = 0;
|
||||||
|
\\var evt = undefined;
|
||||||
|
\\var phase = undefined;
|
||||||
|
\\var cur = undefined;
|
||||||
|
\\content.addEventListener('myEvent',
|
||||||
|
\\function(event) {
|
||||||
|
\\evt = event;
|
||||||
|
\\phase = event.eventPhase;
|
||||||
|
\\cur = event.currentTarget;
|
||||||
|
\\nb ++;
|
||||||
|
\\})
|
||||||
|
, .ex = "undefined" },
|
||||||
.{ .src = "content.dispatchEvent(event)", .ex = "true" },
|
.{ .src = "content.dispatchEvent(event)", .ex = "true" },
|
||||||
.{ .src = "nb", .ex = "2" }, // 2 because the callback is called twice
|
.{ .src = "nb", .ex = "1" },
|
||||||
|
.{ .src = "evt instanceof Event", .ex = "true" },
|
||||||
|
.{ .src = "evt.type", .ex = "myEvent" },
|
||||||
|
.{ .src = "phase", .ex = "2" },
|
||||||
|
.{ .src = "cur.localName", .ex = "div" },
|
||||||
};
|
};
|
||||||
try checkCases(js_env, &basic);
|
try checkCases(js_env, &basic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,85 @@ const generate = @import("../generate.zig");
|
|||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
const DOMException = @import("../dom/exceptions.zig").DOMException;
|
const DOMException = @import("../dom/exceptions.zig").DOMException;
|
||||||
|
const EventTarget = @import("../dom/event_target.zig").EventTarget;
|
||||||
|
const EventTargetUnion = @import("../dom/event_target.zig").Union;
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#event
|
||||||
pub const Event = struct {
|
pub const Event = struct {
|
||||||
pub const Self = parser.Event;
|
pub const Self = parser.Event;
|
||||||
pub const Exception = DOMException;
|
pub const Exception = DOMException;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
// JS funcs
|
pub const EventInit = parser.EventInit;
|
||||||
// --------
|
|
||||||
|
|
||||||
pub fn constructor(eventType: []const u8) !*parser.Event {
|
// JS
|
||||||
|
// --
|
||||||
|
|
||||||
|
pub const _CAPTURING_PHASE = 1;
|
||||||
|
pub const _AT_TARGET = 2;
|
||||||
|
pub const _BUBBLING_PHASE = 3;
|
||||||
|
|
||||||
|
pub fn constructor(eventType: []const u8, opts: ?EventInit) !*parser.Event {
|
||||||
const event = try parser.eventCreate();
|
const event = try parser.eventCreate();
|
||||||
try parser.eventInit(event, eventType);
|
try parser.eventInit(event, eventType, opts orelse EventInit{});
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
pub fn get_type(self: *parser.Event) ![]const u8 {
|
||||||
|
return try parser.eventType(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_target(self: *parser.Event) !?EventTargetUnion {
|
||||||
|
const et = try parser.eventTarget(self);
|
||||||
|
if (et == null) return null;
|
||||||
|
return try EventTarget.toInterface(et.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_currentTarget(self: *parser.Event) !?EventTargetUnion {
|
||||||
|
const et = try parser.eventCurrentTarget(self);
|
||||||
|
if (et == null) return null;
|
||||||
|
return try EventTarget.toInterface(et.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_eventPhase(self: *parser.Event) !u8 {
|
||||||
|
return try parser.eventPhase(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bubbles(self: *parser.Event) !bool {
|
||||||
|
return try parser.eventBubbles(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cancelable(self: *parser.Event) !bool {
|
||||||
|
return try parser.eventCancelable(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_defaultPrevented(self: *parser.Event) !bool {
|
||||||
|
return try parser.eventDefaultPrevented(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_isTrusted(self: *parser.Event) !bool {
|
||||||
|
return try parser.eventIsTrusted(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_timestamp(self: *parser.Event) !u32 {
|
||||||
|
return try parser.eventTimestamp(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
|
||||||
|
pub fn get_stopPropagation(self: *parser.Event) !void {
|
||||||
|
return try parser.eventStopPropagation(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_stopImmediatePropagation(self: *parser.Event) !void {
|
||||||
|
return try parser.eventStopImmediatePropagation(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_preventDefault(self: *parser.Event) !void {
|
||||||
|
return try parser.eventPreventDefault(self);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Event interfaces
|
// Event interfaces
|
||||||
|
|||||||
@@ -353,9 +353,93 @@ pub fn eventCreate() !*Event {
|
|||||||
return evt.?;
|
return evt.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eventInit(evt: *Event, eventType: []const u8) !void {
|
pub const EventInit = struct {
|
||||||
const s = try strFromData(eventType);
|
bubbles: bool = false,
|
||||||
const err = c._dom_event_init(evt, s, false, false);
|
cancelable: bool = false,
|
||||||
|
composed: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn eventInit(evt: *Event, typ: []const u8, opts: EventInit) !void {
|
||||||
|
const s = try strFromData(typ);
|
||||||
|
const err = c._dom_event_init(evt, s, opts.bubbles, opts.cancelable);
|
||||||
|
try DOMErr(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventType(evt: *Event) ![]const u8 {
|
||||||
|
var s: ?*String = undefined;
|
||||||
|
const err = c._dom_event_get_type(evt, &s);
|
||||||
|
try DOMErr(err);
|
||||||
|
return strToData(s.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventTarget(evt: *Event) !?*EventTarget {
|
||||||
|
var et: ?*EventTarget = undefined;
|
||||||
|
const err = c._dom_event_get_target(evt, &et);
|
||||||
|
try DOMErr(err);
|
||||||
|
return et;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventCurrentTarget(evt: *Event) !?*EventTarget {
|
||||||
|
var et: ?*EventTarget = undefined;
|
||||||
|
const err = c._dom_event_get_current_target(evt, &et);
|
||||||
|
try DOMErr(err);
|
||||||
|
return et;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventPhase(evt: *Event) !u8 {
|
||||||
|
var phase: c.dom_event_flow_phase = undefined;
|
||||||
|
const err = c._dom_event_get_event_phase(evt, &phase);
|
||||||
|
try DOMErr(err);
|
||||||
|
return @as(u8, @intCast(phase));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventBubbles(evt: *Event) !bool {
|
||||||
|
var res: bool = undefined;
|
||||||
|
const err = c._dom_event_get_bubbles(evt, &res);
|
||||||
|
try DOMErr(err);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventCancelable(evt: *Event) !bool {
|
||||||
|
var res: bool = undefined;
|
||||||
|
const err = c._dom_event_get_cancelable(evt, &res);
|
||||||
|
try DOMErr(err);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventDefaultPrevented(evt: *Event) !bool {
|
||||||
|
var res: bool = undefined;
|
||||||
|
const err = c._dom_event_is_default_prevented(evt, &res);
|
||||||
|
try DOMErr(err);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventIsTrusted(evt: *Event) !bool {
|
||||||
|
var res: bool = undefined;
|
||||||
|
const err = c._dom_event_get_is_trusted(evt, &res);
|
||||||
|
try DOMErr(err);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventTimestamp(evt: *Event) !u32 {
|
||||||
|
var ts: c_uint = undefined;
|
||||||
|
const err = c._dom_event_get_timestamp(evt, &ts);
|
||||||
|
try DOMErr(err);
|
||||||
|
return @as(u32, @intCast(ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventStopPropagation(evt: *Event) !void {
|
||||||
|
const err = c._dom_event_stop_propagation(evt);
|
||||||
|
try DOMErr(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventStopImmediatePropagation(evt: *Event) !void {
|
||||||
|
const err = c._dom_event_stop_immediate_propagation(evt);
|
||||||
|
try DOMErr(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eventPreventDefault(evt: *Event) !void {
|
||||||
|
const err = c._dom_event_prevent_default(evt);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,20 +467,22 @@ fn eventTargetVtable(et: *EventTarget) c.dom_event_target_vtable {
|
|||||||
|
|
||||||
pub fn eventTargetAddEventListener(
|
pub fn eventTargetAddEventListener(
|
||||||
et: *EventTarget,
|
et: *EventTarget,
|
||||||
eventType: []const u8,
|
typ: []const u8,
|
||||||
cbk_ptr: *Callback,
|
cbk_ptr: *Callback,
|
||||||
|
capture: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const s = try strFromData(eventType);
|
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: ?*c.dom_event_listener = 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, true);
|
const err = eventTargetVtable(et).add_event_listener.?(et, s, listener, capture);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eventTargetDispatchEvent(et: *EventTarget, event: *Event) !bool {
|
pub fn eventTargetDispatchEvent(et: *EventTarget, event: *Event) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
|
// const err = c.dom_event_target_dispatch_event(et, event, &res);
|
||||||
const err = eventTargetVtable(et).dispatch_event.?(et, event, &res);
|
const err = eventTargetVtable(et).dispatch_event.?(et, event, &res);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
Reference in New Issue
Block a user