mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
CustomEvent and document.createEvent
This commit is contained in:
@@ -544,6 +544,7 @@ pub const JsApis = flattenTypes(&.{
|
||||
@import("../webapi/encoding/TextDecoder.zig"),
|
||||
@import("../webapi/encoding/TextEncoder.zig"),
|
||||
@import("../webapi/Event.zig"),
|
||||
@import("../webapi/event/CustomEvent.zig"),
|
||||
@import("../webapi/event/ErrorEvent.zig"),
|
||||
@import("../webapi/event/ProgressEvent.zig"),
|
||||
@import("../webapi/EventTarget.zig"),
|
||||
|
||||
95
src/browser/tests/event/custom_event.html
Normal file
95
src/browser/tests/event/custom_event.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<script id=customEventConstructor>
|
||||
{
|
||||
const event = new CustomEvent('test');
|
||||
testing.expectEqual('test', event.type);
|
||||
testing.expectEqual(null, event.detail);
|
||||
testing.expectEqual(false, event.bubbles);
|
||||
testing.expectEqual(false, event.cancelable);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=customEventWithDetail>
|
||||
{
|
||||
const detail = { foo: 'bar', num: 42 };
|
||||
const event = new CustomEvent('custom', { detail });
|
||||
testing.expectEqual('custom', event.type);
|
||||
testing.expectEqual('bar', event.detail.foo);
|
||||
testing.expectEqual(42, event.detail.num);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=customEventWithOptions>
|
||||
{
|
||||
const event = new CustomEvent('opts', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: 'test-detail'
|
||||
});
|
||||
testing.expectEqual(true, event.bubbles);
|
||||
testing.expectEqual(true, event.cancelable);
|
||||
testing.expectEqual('test-detail', event.detail);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=customEventDispatch>
|
||||
{
|
||||
const target = document.createElement('div');
|
||||
let receivedEvent = null;
|
||||
|
||||
target.addEventListener('myevent', (e) => {
|
||||
receivedEvent = e;
|
||||
});
|
||||
|
||||
const event = new CustomEvent('myevent', {
|
||||
detail: { message: 'hello' }
|
||||
});
|
||||
target.dispatchEvent(event);
|
||||
|
||||
testing.expectEqual('hello', receivedEvent.detail.message);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createEventCustomEvent>
|
||||
{
|
||||
const event = document.createEvent('CustomEvent');
|
||||
testing.expectEqual('', event.type);
|
||||
testing.expectEqual(null, event.detail);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createEventCaseInsensitive>
|
||||
{
|
||||
const event1 = document.createEvent('customevent');
|
||||
testing.expectEqual('', event1.type);
|
||||
|
||||
const event2 = document.createEvent('CUSTOMEVENT');
|
||||
testing.expectEqual('', event2.type);
|
||||
|
||||
const event3 = document.createEvent('CustomEvents');
|
||||
testing.expectEqual('', event3.type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createEventGeneric>
|
||||
{
|
||||
const event1 = document.createEvent('Event');
|
||||
testing.expectEqual('', event1.type);
|
||||
|
||||
const event2 = document.createEvent('Events');
|
||||
testing.expectEqual('', event2.type);
|
||||
|
||||
const event3 = document.createEvent('HTMLEvents');
|
||||
testing.expectEqual('', event3.type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=customEventInheritance>
|
||||
{
|
||||
const event = new CustomEvent('inherit-test');
|
||||
testing.expectEqual(Event.NONE, event.eventPhase);
|
||||
testing.expectEqual(false, event.defaultPrevented);
|
||||
}
|
||||
</script>
|
||||
@@ -175,6 +175,26 @@ pub fn createTextNode(_: *const Document, data: []const u8, page: *Page) !*Node
|
||||
return page.createTextNode(data);
|
||||
}
|
||||
|
||||
pub fn createEvent(_: *const Document, event_type: []const u8, page: *Page) !*@import("Event.zig") {
|
||||
const Event = @import("Event.zig");
|
||||
|
||||
if (std.ascii.eqlIgnoreCase(event_type, "event") or std.ascii.eqlIgnoreCase(event_type, "events") or std.ascii.eqlIgnoreCase(event_type, "htmlevents")) {
|
||||
return Event.init("", null, page);
|
||||
}
|
||||
|
||||
if (std.ascii.eqlIgnoreCase(event_type, "customevent") or std.ascii.eqlIgnoreCase(event_type, "customevents")) {
|
||||
const CustomEvent = @import("event/CustomEvent.zig");
|
||||
const custom_event = try CustomEvent.init("", null, page);
|
||||
return custom_event.asEvent();
|
||||
}
|
||||
|
||||
if (std.ascii.eqlIgnoreCase(event_type, "messageevent")) {
|
||||
return error.NotSupported;
|
||||
}
|
||||
|
||||
return error.NotSupported;
|
||||
}
|
||||
|
||||
pub fn createTreeWalker(_: *const Document, root: *Node, what_to_show: ?u32, filter: ?DOMTreeWalker.FilterOpts, page: *Page) !*DOMTreeWalker {
|
||||
const show = what_to_show orelse NodeFilter.SHOW_ALL;
|
||||
return DOMTreeWalker.init(root, show, filter, page);
|
||||
@@ -239,6 +259,7 @@ pub const JsApi = struct {
|
||||
pub const createDocumentFragment = bridge.function(Document.createDocumentFragment, .{});
|
||||
pub const createComment = bridge.function(Document.createComment, .{});
|
||||
pub const createTextNode = bridge.function(Document.createTextNode, .{});
|
||||
pub const createEvent = bridge.function(Document.createEvent, .{ .dom_exception = true });
|
||||
pub const createTreeWalker = bridge.function(Document.createTreeWalker, .{});
|
||||
pub const createNodeIterator = bridge.function(Document.createNodeIterator, .{});
|
||||
pub const getElementById = bridge.function(Document.getElementById, .{});
|
||||
|
||||
@@ -48,6 +48,7 @@ pub const Type = union(enum) {
|
||||
generic,
|
||||
progress_event: *@import("event/ProgressEvent.zig"),
|
||||
error_event: *@import("event/ErrorEvent.zig"),
|
||||
custom_event: *@import("event/CustomEvent.zig"),
|
||||
};
|
||||
|
||||
const Options = struct {
|
||||
|
||||
78
src/browser/webapi/event/CustomEvent.zig
Normal file
78
src/browser/webapi/event/CustomEvent.zig
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (C) 2023-2025 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 js = @import("../../js/js.zig");
|
||||
|
||||
const Page = @import("../../Page.zig");
|
||||
const Event = @import("../Event.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const CustomEvent = @This();
|
||||
|
||||
_proto: *Event,
|
||||
_detail: ?js.Object = null,
|
||||
_arena: Allocator,
|
||||
|
||||
pub const InitOptions = struct {
|
||||
detail: ?js.Object = null,
|
||||
bubbles: bool = false,
|
||||
cancelable: bool = false,
|
||||
};
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?InitOptions, page: *Page) !*CustomEvent {
|
||||
const arena = page.arena;
|
||||
const opts = opts_ orelse InitOptions{};
|
||||
|
||||
const event = try page._factory.event(typ, CustomEvent{
|
||||
._arena = arena,
|
||||
._proto = undefined,
|
||||
._detail = if (opts.detail) |detail| try detail.persist() else null,
|
||||
});
|
||||
|
||||
event._proto._bubbles = opts.bubbles;
|
||||
event._proto._cancelable = opts.cancelable;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
pub fn asEvent(self: *CustomEvent) *Event {
|
||||
return self._proto;
|
||||
}
|
||||
|
||||
pub fn getDetail(self: *const CustomEvent) ?js.Object {
|
||||
return self._detail;
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(CustomEvent);
|
||||
|
||||
pub const Meta = struct {
|
||||
pub const name = "CustomEvent";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
};
|
||||
|
||||
pub const constructor = bridge.constructor(CustomEvent.init, .{});
|
||||
pub const detail = bridge.accessor(CustomEvent.getDetail, null, .{});
|
||||
};
|
||||
|
||||
const testing = @import("../../../testing.zig");
|
||||
test "WebApi: CustomEvent" {
|
||||
try testing.htmlRunner("event/custom_event.html", .{});
|
||||
}
|
||||
Reference in New Issue
Block a user