Skip to content

Commit 476fb7e

Browse files
committed
DOMException constructor
1 parent 7435274 commit 476fb7e

File tree

1 file changed

+80
-7
lines changed

1 file changed

+80
-7
lines changed

src/browser/dom/exceptions.zig

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ const std = @import("std");
2020
const allocPrint = std.fmt.allocPrint;
2121

2222
const parser = @import("../netsurf.zig");
23+
const Page = @import("../page.zig").Page;
2324

2425
// https://webidl.spec.whatwg.org/#idl-DOMException
2526
pub const DOMException = struct {
26-
err: parser.DOMError,
27+
err: ?parser.DOMError,
2728
str: []const u8,
2829

2930
pub const ErrorSet = parser.DOMError;
@@ -55,6 +56,17 @@ pub const DOMException = struct {
5556
pub const _INVALID_NODE_TYPE_ERR = 24;
5657
pub const _DATA_CLONE_ERR = 25;
5758

59+
pub fn constructor(message_: ?[]const u8, name_: ?[]const u8, page: *const Page) !DOMException {
60+
const message = message_ orelse "";
61+
const err = if (name_) |n| error_from_str(n) else null;
62+
const fixed_name = name(err);
63+
64+
if (message.len == 0) return .{ .err = err, .str = fixed_name };
65+
66+
const str = try allocPrint(page.arena, "{s}: {s}", .{ fixed_name, message });
67+
return .{ .err = err, .str = str };
68+
}
69+
5870
// TODO: deinit
5971
pub fn init(alloc: std.mem.Allocator, err: anyerror, callerName: []const u8) !DOMException {
6072
const errCast = @as(parser.DOMError, @errorCast(err));
@@ -75,14 +87,52 @@ pub const DOMException = struct {
7587
return .{ .err = errCast, .str = str };
7688
}
7789

78-
fn name(err: parser.DOMError) []const u8 {
90+
fn error_from_str(name_: []const u8) ?parser.DOMError {
91+
// @speed: Consider length first, left as is for maintainability, awaiting switch on string support
92+
if (std.mem.eql(u8, name_, "IndexSizeError")) return error.IndexSize;
93+
if (std.mem.eql(u8, name_, "StringSizeError")) return error.StringSize;
94+
if (std.mem.eql(u8, name_, "HierarchyRequestError")) return error.HierarchyRequest;
95+
if (std.mem.eql(u8, name_, "WrongDocumentError")) return error.WrongDocument;
96+
if (std.mem.eql(u8, name_, "InvalidCharacterError")) return error.InvalidCharacter;
97+
if (std.mem.eql(u8, name_, "NoDataAllowedError")) return error.NoDataAllowed;
98+
if (std.mem.eql(u8, name_, "NoModificationAllowedError")) return error.NoModificationAllowed;
99+
if (std.mem.eql(u8, name_, "NotFoundError")) return error.NotFound;
100+
if (std.mem.eql(u8, name_, "NotSupportedError")) return error.NotSupported;
101+
if (std.mem.eql(u8, name_, "InuseAttributeError")) return error.InuseAttribute;
102+
if (std.mem.eql(u8, name_, "InvalidStateError")) return error.InvalidState;
103+
if (std.mem.eql(u8, name_, "SyntaxError")) return error.Syntax;
104+
if (std.mem.eql(u8, name_, "InvalidModificationError")) return error.InvalidModification;
105+
if (std.mem.eql(u8, name_, "NamespaceError")) return error.Namespace;
106+
if (std.mem.eql(u8, name_, "InvalidAccessError")) return error.InvalidAccess;
107+
if (std.mem.eql(u8, name_, "ValidationError")) return error.Validation;
108+
if (std.mem.eql(u8, name_, "TypeMismatchError")) return error.TypeMismatch;
109+
if (std.mem.eql(u8, name_, "SecurityError")) return error.Security;
110+
if (std.mem.eql(u8, name_, "NetworkError")) return error.Network;
111+
if (std.mem.eql(u8, name_, "AbortError")) return error.Abort;
112+
if (std.mem.eql(u8, name_, "URLismatchError")) return error.URLismatch;
113+
if (std.mem.eql(u8, name_, "QuotaExceededError")) return error.QuotaExceeded;
114+
if (std.mem.eql(u8, name_, "TimeoutError")) return error.Timeout;
115+
if (std.mem.eql(u8, name_, "InvalidNodeTypeError")) return error.InvalidNodeType;
116+
if (std.mem.eql(u8, name_, "DataCloneError")) return error.DataClone;
117+
118+
// custom netsurf error
119+
if (std.mem.eql(u8, name_, "UnspecifiedEventTypeError")) return error.UnspecifiedEventType;
120+
if (std.mem.eql(u8, name_, "DispatchRequestError")) return error.DispatchRequest;
121+
if (std.mem.eql(u8, name_, "NoMemoryError")) return error.NoMemory;
122+
if (std.mem.eql(u8, name_, "AttributeWrongTypeError")) return error.AttributeWrongType;
123+
return null;
124+
}
125+
126+
fn name(err_: ?parser.DOMError) []const u8 {
127+
const err = err_ orelse return "Error";
128+
79129
return switch (err) {
80130
error.IndexSize => "IndexSizeError",
81-
error.StringSize => "StringSizeError",
131+
error.StringSize => "StringSizeError", // Legacy: DOMSTRING_SIZE_ERR
82132
error.HierarchyRequest => "HierarchyRequestError",
83133
error.WrongDocument => "WrongDocumentError",
84134
error.InvalidCharacter => "InvalidCharacterError",
85-
error.NoDataAllowed => "NoDataAllowedError",
135+
error.NoDataAllowed => "NoDataAllowedError", // Legacy: NO_DATA_ALLOWED_ERR
86136
error.NoModificationAllowed => "NoModificationAllowedError",
87137
error.NotFound => "NotFoundError",
88138
error.NotSupported => "NotSupportedError",
@@ -92,7 +142,7 @@ pub const DOMException = struct {
92142
error.InvalidModification => "InvalidModificationError",
93143
error.Namespace => "NamespaceError",
94144
error.InvalidAccess => "InvalidAccessError",
95-
error.Validation => "ValidationError",
145+
error.Validation => "ValidationError", // Legacy: VALIDATION_ERR
96146
error.TypeMismatch => "TypeMismatchError",
97147
error.Security => "SecurityError",
98148
error.Network => "NetworkError",
@@ -115,7 +165,8 @@ pub const DOMException = struct {
115165
// JS properties and methods
116166

117167
pub fn get_code(self: *const DOMException) u8 {
118-
return switch (self.err) {
168+
const err = self.err orelse return 0;
169+
return switch (err) {
119170
error.IndexSize => 1,
120171
error.StringSize => 2,
121172
error.HierarchyRequest => 3,
@@ -157,7 +208,8 @@ pub const DOMException = struct {
157208

158209
pub fn get_message(self: *const DOMException) []const u8 {
159210
const errName = DOMException.name(self.err);
160-
return self.str[errName.len + 2 ..];
211+
if (self.str.len <= errName.len + 2) return "";
212+
return self.str[errName.len + 2 ..]; // ! Requires str is formatted as "{name}: {message}"
161213
}
162214

163215
pub fn _toString(self: *const DOMException) []const u8 {
@@ -188,4 +240,25 @@ test "Browser.DOM.Exception" {
188240
.{ "he instanceof DOMException", "true" },
189241
.{ "he instanceof Error", "true" },
190242
}, .{});
243+
244+
// Test DOMException constructor
245+
try runner.testCases(&.{
246+
.{ "let exc0 = new DOMException()", "undefined" },
247+
.{ "exc0.name", "Error" },
248+
.{ "exc0.code", "0" },
249+
.{ "exc0.message", "" },
250+
.{ "exc0.toString()", "Error" },
251+
252+
.{ "let exc1 = new DOMException('Sandwich malfunction')", "undefined" },
253+
.{ "exc1.name", "Error" },
254+
.{ "exc1.code", "0" },
255+
.{ "exc1.message", "Sandwich malfunction" },
256+
.{ "exc1.toString()", "Error: Sandwich malfunction" },
257+
258+
.{ "let exc2 = new DOMException('Caterpillar turned into a butterfly', 'NoModificationAllowedError')", "undefined" },
259+
.{ "exc2.name", "NoModificationAllowedError" },
260+
.{ "exc2.code", "7" },
261+
.{ "exc2.message", "Caterpillar turned into a butterfly" },
262+
.{ "exc2.toString()", "NoModificationAllowedError: Caterpillar turned into a butterfly" },
263+
}, .{});
191264
}

0 commit comments

Comments
 (0)