Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIEvent #176

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/events/event.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const parser = @import("../netsurf.zig");
const DOMException = @import("../dom/exceptions.zig").DOMException;
const EventTarget = @import("../dom/event_target.zig").EventTarget;
const EventTargetUnion = @import("../dom/event_target.zig").Union;
const UIEvent = @import("ui_event.zig").UIEvent;

// https://dom.spec.whatwg.org/#event
pub const Event = struct {
Expand Down Expand Up @@ -107,6 +108,7 @@ pub const Event = struct {
// Event interfaces
pub const Interfaces = generate.Tuple(.{
Event,
UIEvent,
});
const Generated = generate.Union.compile(Interfaces);
pub const Union = Generated._union;
Expand Down
51 changes: 51 additions & 0 deletions src/events/ui_event.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const std = @import("std");

const jsruntime = @import("jsruntime");
const Case = jsruntime.test_utils.Case;
const checkCases = jsruntime.test_utils.checkCases;

const parser = @import("../netsurf.zig");

const Event = @import("event.zig").Event;
const Window = @import("../html/window.zig").Window;

pub const UIEvent = struct {
pub const Self = parser.UIEvent;
pub const mem_guarantied = true;

pub const UIEventInit = parser.UIEventInit;

// JS
// --

pub fn constructor(typ: []const u8, opts: ?UIEventInit) !*parser.UIEvent {
const evt = try parser.uiEventCreate();
try parser.uiEventInit(evt, typ, opts orelse UIEventInit{});
return evt;
}

pub fn get_detail(self: *parser.UIEvent) !i32 {
return try parser.uiEventDetail(self);
}

pub fn get_view(self: *parser.UIEvent) !?Window {
return try parser.uiEventView(self);
}
};

pub fn testExecFn(
_: std.mem.Allocator,
js_env: *jsruntime.Env,
) anyerror!void {
var ui_event = [_]Case{
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
.{ .src = "var evt", .ex = "undefined" },
.{ .src = "content.addEventListener('evt', function(e) {evt = e})", .ex = "undefined" },
.{ .src = "content.dispatchEvent(new UIEvent('evt'))", .ex = "true" },
.{ .src = "evt instanceof UIEvent", .ex = "true" },
.{ .src = "evt.__proto__.constructor.name", .ex = "UIEvent" },
.{ .src = "evt.detail", .ex = "0" },
.{ .src = "evt.view", .ex = "null" },
};
try checkCases(js_env, &ui_event);
}
50 changes: 50 additions & 0 deletions src/netsurf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ const std = @import("std");
const c = @cImport({
@cInclude("dom/dom.h");
@cInclude("dom/bindings/hubbub/parser.h");
@cInclude("events/event.h");
@cInclude("events/ui_event.h");
});

const Callback = @import("jsruntime").Callback;

const Window = @import("html/window.zig").Window;

// Vtable
// ------

Expand Down Expand Up @@ -443,6 +447,52 @@ pub fn eventPreventDefault(evt: *Event) !void {
try DOMErr(err);
}

// UIEvent
pub const UIEvent = c.dom_ui_event;

pub fn uiEventCreate() !*UIEvent {
var evt: ?*UIEvent = undefined;
const err = c._dom_ui_event_create(&evt);
try DOMErr(err);
return evt.?;
}

pub const UIEventInit = struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about declaring this struct here. It's doesn't depend on netsurf, it could be declared directly inside dom/UIEvent

bubbles: bool = false,
cancelable: bool = false,

view: ?Window = null,
detail: i32 = 0,
};

pub fn uiEventInit(evt: *UIEvent, typ: []const u8, opts: UIEventInit) !void {
const err = c._dom_ui_event_init(
evt,
try strFromData(typ),
opts.bubbles,
opts.cancelable,
// TODO pass the Window as view.
// opts.view
null,
opts.detail,
);
try DOMErr(err);
}

pub fn uiEventDetail(evt: *UIEvent) !i32 {
var res: i32 = undefined;
const err = c._dom_ui_event_get_detail(evt, &res);
try DOMErr(err);
return res;
}

pub fn uiEventView(_: *UIEvent) !?Window {
// TODO retrieve the Window as view.
// const err = c._dom_ui_event_get_view(evt, &res);
// try DOMErr(err);
return null;
}

// EventHandler
fn event_handler_cbk(data: *anyopaque) *Callback {
const ptr: *align(@alignOf(*Callback)) anyopaque = @alignCast(data);
Expand Down
2 changes: 2 additions & 0 deletions src/run_tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const NodeListTestExecFn = @import("dom/nodelist.zig").testExecFn;
const AttrTestExecFn = @import("dom/attribute.zig").testExecFn;
const EventTargetTestExecFn = @import("dom/event_target.zig").testExecFn;
const EventTestExecFn = @import("events/event.zig").testExecFn;
const UIEventTestExecFn = @import("events/ui_event.zig").testExecFn;

pub const Types = jsruntime.reflect(apiweb.Interfaces);

Expand Down Expand Up @@ -77,6 +78,7 @@ fn testsAllExecFn(
AttrTestExecFn,
EventTargetTestExecFn,
EventTestExecFn,
UIEventTestExecFn,
};

inline for (testFns) |testFn| {
Expand Down
Loading