mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Add DOMException
Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
const generate = @import("../generate.zig");
|
const generate = @import("../generate.zig");
|
||||||
|
|
||||||
|
const DOMException = @import("exceptions.zig").DOMException;
|
||||||
const EventTarget = @import("event_target.zig").EventTarget;
|
const EventTarget = @import("event_target.zig").EventTarget;
|
||||||
const Nod = @import("node.zig");
|
const Nod = @import("node.zig");
|
||||||
|
|
||||||
pub const Interfaces = generate.Tuple(.{
|
pub const Interfaces = generate.Tuple(.{
|
||||||
|
DOMException,
|
||||||
EventTarget,
|
EventTarget,
|
||||||
Nod.Node,
|
Nod.Node,
|
||||||
Nod.Interfaces,
|
Nod.Interfaces,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
|
const DOMException = @import("exceptions.zig").DOMException;
|
||||||
|
|
||||||
pub const EventTarget = struct {
|
pub const EventTarget = struct {
|
||||||
pub const Self = parser.EventTarget;
|
pub const Self = parser.EventTarget;
|
||||||
|
pub const Exception = DOMException;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
};
|
};
|
||||||
|
|||||||
133
src/dom/exceptions.zig
Normal file
133
src/dom/exceptions.zig
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const allocPrint = std.fmt.allocPrint;
|
||||||
|
|
||||||
|
const jsruntime = @import("jsruntime");
|
||||||
|
const Case = jsruntime.test_utils.Case;
|
||||||
|
const checkCases = jsruntime.test_utils.checkCases;
|
||||||
|
|
||||||
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
|
pub const DOMException = struct {
|
||||||
|
err: parser.DOMError,
|
||||||
|
str: []const u8,
|
||||||
|
|
||||||
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
|
pub const ErrorSet = parser.DOMError;
|
||||||
|
|
||||||
|
// static attributes
|
||||||
|
pub const _INDEX_SIZE_ERR = 1;
|
||||||
|
pub const _DOMSTRING_SIZE_ERR = 2;
|
||||||
|
pub const _HIERARCHY_REQUEST_ERR = 3;
|
||||||
|
pub const _WRONG_DOCUMENT_ERR = 4;
|
||||||
|
pub const _INVALID_CHARACTER_ERR = 5;
|
||||||
|
pub const _NO_DATA_ALLOWED_ERR = 6;
|
||||||
|
pub const _NO_MODIFICATION_ALLOWED_ERR = 7;
|
||||||
|
pub const _NOT_FOUND_ERR = 8;
|
||||||
|
pub const _NOT_SUPPORTED_ERR = 9;
|
||||||
|
pub const _INUSE_ATTRIBUTE_ERR = 10;
|
||||||
|
pub const _INVALID_STATE_ERR = 11;
|
||||||
|
pub const _SYNTAX_ERR = 12;
|
||||||
|
pub const _INVALID_MODIFICATION_ERR = 13;
|
||||||
|
pub const _NAMESPACE_ERR = 14;
|
||||||
|
pub const _INVALID_ACCESS_ERR = 15;
|
||||||
|
pub const _VALIDATION_ERR = 16;
|
||||||
|
pub const _TYPE_MISMATCH_ERR = 17;
|
||||||
|
|
||||||
|
// TODO: deinit
|
||||||
|
pub fn init(alloc: std.mem.Allocator, err: parser.DOMError, callerName: []const u8) anyerror!DOMException {
|
||||||
|
const errName = DOMException.name(err);
|
||||||
|
const str = switch (err) {
|
||||||
|
error.HierarchyRequest => try allocPrint(
|
||||||
|
alloc,
|
||||||
|
"{s}: Failed to execute '{s}' on 'Node': The new child element contains the parent.",
|
||||||
|
.{ errName, callerName },
|
||||||
|
),
|
||||||
|
error.NoError => unreachable,
|
||||||
|
else => "", // TODO: implement other messages
|
||||||
|
};
|
||||||
|
return .{ .err = err, .str = str };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(err: parser.DOMError) []const u8 {
|
||||||
|
return switch (err) {
|
||||||
|
error.IndexSize => "IndexSizeError",
|
||||||
|
error.StringSize => "StringSizeError",
|
||||||
|
error.HierarchyRequest => "HierarchyRequestError",
|
||||||
|
error.WrongDocument => "WrongDocumentError",
|
||||||
|
error.InvalidCharacter => "InvalidCharacterError",
|
||||||
|
error.NoDataAllowed => "NoDataAllowedError",
|
||||||
|
error.NoModificationAllowed => "NoModificationAllowedError",
|
||||||
|
error.NotFound => "NotFoundError",
|
||||||
|
error.NotSupported => "NotSupportedError",
|
||||||
|
error.InuseAttribute => "InuseAttributeError",
|
||||||
|
error.InvalidState => "InvalidStateError",
|
||||||
|
error.Syntax => "SyntaxError",
|
||||||
|
error.InvalidModification => "InvalidModificationError",
|
||||||
|
error.Namespace => "NamespaceError",
|
||||||
|
error.InvalidAccess => "InvalidAccessError",
|
||||||
|
error.Validation => "ValidationError",
|
||||||
|
error.TypeMismatch => "TypeMismatchError",
|
||||||
|
error.NoError => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// JS properties and methods
|
||||||
|
|
||||||
|
pub fn get_code(self: DOMException) u8 {
|
||||||
|
return switch (self.err) {
|
||||||
|
error.IndexSize => 1,
|
||||||
|
error.StringSize => 2,
|
||||||
|
error.HierarchyRequest => 3,
|
||||||
|
error.WrongDocument => 4,
|
||||||
|
error.InvalidCharacter => 5,
|
||||||
|
error.NoDataAllowed => 6,
|
||||||
|
error.NoModificationAllowed => 7,
|
||||||
|
error.NotFound => 8,
|
||||||
|
error.NotSupported => 9,
|
||||||
|
error.InuseAttribute => 10,
|
||||||
|
error.InvalidState => 11,
|
||||||
|
error.Syntax => 12,
|
||||||
|
error.InvalidModification => 13,
|
||||||
|
error.Namespace => 14,
|
||||||
|
error.InvalidAccess => 15,
|
||||||
|
error.Validation => 16,
|
||||||
|
error.TypeMismatch => 17,
|
||||||
|
error.NoError => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_name(self: DOMException) []const u8 {
|
||||||
|
return DOMException.name(self.err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_message(self: DOMException) []const u8 {
|
||||||
|
const errName = DOMException.name(self.err);
|
||||||
|
return self.str[errName.len + 2 ..];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _toString(self: DOMException) []const u8 {
|
||||||
|
return self.str;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tests
|
||||||
|
// -----
|
||||||
|
|
||||||
|
pub fn testExecFn(
|
||||||
|
_: std.mem.Allocator,
|
||||||
|
js_env: *jsruntime.Env,
|
||||||
|
comptime _: []jsruntime.API,
|
||||||
|
) !void {
|
||||||
|
const err = "Failed to execute 'appendChild' on 'Node': The new child element contains the parent.";
|
||||||
|
var cases = [_]Case{
|
||||||
|
.{ .src = "let content = document.getElementById('content')", .ex = "undefined" },
|
||||||
|
.{ .src = "let link = document.getElementById('link')", .ex = "undefined" },
|
||||||
|
// HierarchyRequestError
|
||||||
|
.{ .src = "var HierarchyRequestError; try {link.appendChild(content)} catch (error) {HierarchyRequestError = error} HierarchyRequestError.name", .ex = "HierarchyRequestError" },
|
||||||
|
.{ .src = "HierarchyRequestError.code", .ex = "3" },
|
||||||
|
.{ .src = "HierarchyRequestError.message", .ex = err },
|
||||||
|
.{ .src = "HierarchyRequestError.toString()", .ex = "HierarchyRequestError: " ++ err },
|
||||||
|
};
|
||||||
|
try checkCases(js_env, &cases);
|
||||||
|
}
|
||||||
@@ -150,9 +150,9 @@ pub const Node = struct {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
pub fn _appendChild(self: *parser.Node, child: *parser.Node) Union {
|
pub fn _appendChild(self: *parser.Node, child: *parser.Node) !Union {
|
||||||
// TODO: DocumentFragment special case
|
// TODO: DocumentFragment special case
|
||||||
const res = parser.nodeAppendChild(self, child);
|
const res = try parser.nodeAppendChild(self, child);
|
||||||
return Node.toInterface(res);
|
return Node.toInterface(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -274,6 +274,54 @@ pub const Tag = enum(u8) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// DOMException
|
||||||
|
|
||||||
|
pub const DOMError = error{
|
||||||
|
NoError,
|
||||||
|
IndexSize,
|
||||||
|
StringSize,
|
||||||
|
HierarchyRequest,
|
||||||
|
WrongDocument,
|
||||||
|
InvalidCharacter,
|
||||||
|
NoDataAllowed,
|
||||||
|
NoModificationAllowed,
|
||||||
|
NotFound,
|
||||||
|
NotSupported,
|
||||||
|
InuseAttribute,
|
||||||
|
InvalidState,
|
||||||
|
Syntax,
|
||||||
|
InvalidModification,
|
||||||
|
Namespace,
|
||||||
|
InvalidAccess,
|
||||||
|
Validation,
|
||||||
|
TypeMismatch,
|
||||||
|
};
|
||||||
|
|
||||||
|
const DOMException = c.dom_exception;
|
||||||
|
|
||||||
|
fn DOMExceptionError(except: DOMException) DOMError {
|
||||||
|
return switch (except) {
|
||||||
|
c.DOM_INDEX_SIZE_ERR => DOMError.IndexSize,
|
||||||
|
c.DOM_DOMSTRING_SIZE_ERR => DOMError.StringSize,
|
||||||
|
c.DOM_HIERARCHY_REQUEST_ERR => DOMError.HierarchyRequest,
|
||||||
|
c.DOM_WRONG_DOCUMENT_ERR => DOMError.WrongDocument,
|
||||||
|
c.DOM_INVALID_CHARACTER_ERR => DOMError.InvalidCharacter,
|
||||||
|
c.DOM_NO_DATA_ALLOWED_ERR => DOMError.NoDataAllowed,
|
||||||
|
c.DOM_NO_MODIFICATION_ALLOWED_ERR => DOMError.NoModificationAllowed,
|
||||||
|
c.DOM_NOT_FOUND_ERR => DOMError.NotFound,
|
||||||
|
c.DOM_NOT_SUPPORTED_ERR => DOMError.NotSupported,
|
||||||
|
c.DOM_INUSE_ATTRIBUTE_ERR => DOMError.InuseAttribute,
|
||||||
|
c.DOM_INVALID_STATE_ERR => DOMError.InvalidState,
|
||||||
|
c.DOM_SYNTAX_ERR => DOMError.Syntax,
|
||||||
|
c.DOM_INVALID_MODIFICATION_ERR => DOMError.InvalidModification,
|
||||||
|
c.DOM_NAMESPACE_ERR => DOMError.Namespace,
|
||||||
|
c.DOM_INVALID_ACCESS_ERR => DOMError.InvalidAccess,
|
||||||
|
c.DOM_VALIDATION_ERR => DOMError.Validation,
|
||||||
|
c.DOM_TYPE_MISMATCH_ERR => DOMError.TypeMismatch,
|
||||||
|
else => DOMError.NoError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// EventTarget
|
// EventTarget
|
||||||
pub const EventTarget = c.dom_event_target;
|
pub const EventTarget = c.dom_event_target;
|
||||||
|
|
||||||
@@ -451,9 +499,10 @@ pub fn nodeSetTextContent(node: *Node, value: []const u8) void {
|
|||||||
_ = nodeVtable(node).dom_node_set_text_content.?(node, s);
|
_ = nodeVtable(node).dom_node_set_text_content.?(node, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeAppendChild(node: *Node, child: *Node) *Node {
|
pub fn nodeAppendChild(node: *Node, child: *Node) DOMError!*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_append_child.?(node, child, &res);
|
const err = nodeVtable(node).dom_node_append_child.?(node, child, &res);
|
||||||
|
if (err != 0) return DOMExceptionError(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const nodeTestExecFn = @import("dom/node.zig").testExecFn;
|
|||||||
const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn;
|
const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn;
|
||||||
const textTestExecFn = @import("dom/text.zig").testExecFn;
|
const textTestExecFn = @import("dom/text.zig").testExecFn;
|
||||||
const HTMLCollectionTestExecFn = @import("dom/html_collection.zig").testExecFn;
|
const HTMLCollectionTestExecFn = @import("dom/html_collection.zig").testExecFn;
|
||||||
|
const DOMExceptionTestExecFn = @import("dom/exceptions.zig").testExecFn;
|
||||||
|
|
||||||
var doc: *parser.DocumentHTML = undefined;
|
var doc: *parser.DocumentHTML = undefined;
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ fn testsAllExecFn(
|
|||||||
characterDataTestExecFn,
|
characterDataTestExecFn,
|
||||||
textTestExecFn,
|
textTestExecFn,
|
||||||
HTMLCollectionTestExecFn,
|
HTMLCollectionTestExecFn,
|
||||||
|
DOMExceptionTestExecFn,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline for (testFns) |testFn| {
|
inline for (testFns) |testFn| {
|
||||||
|
|||||||
Reference in New Issue
Block a user