diff --git a/src/browser/html/elements.zig b/src/browser/html/elements.zig
index 40a3b2b7..7cd5c4dc 100644
--- a/src/browser/html/elements.zig
+++ b/src/browser/html/elements.zig
@@ -271,8 +271,18 @@ pub const HTMLAnchorElement = struct {
return try parser.nodeSetTextContent(parser.anchorToNode(self), v);
}
- inline fn url(self: *parser.Anchor, page: *Page) !URL {
- return URL.constructor(.{ .element = @alignCast(@ptrCast(self)) }, null, page); // TODO inject base url
+ fn url(self: *parser.Anchor, page: *Page) !URL {
+ // Although the URL.constructor union accepts an .{.element = X}, we
+ // can't use this here because the behavior is different.
+ // URL.constructor(document.createElement('a')
+ // should fail (a.href isn't a valid URL)
+ // But
+ // document.createElement('a').host
+ // should not fail, it should return an empty string
+ if (try parser.elementGetAttribute(@alignCast(@ptrCast(self)), "href")) |href| {
+ return URL.constructor(.{ .string = href }, null, page); // TODO inject base url
+ }
+ return .empty;
}
// TODO return a disposable string
@@ -1559,6 +1569,8 @@ test "Browser.HTML.Element" {
try runner.testCases(&.{
.{ "let a = document.createElement('a');", null },
+ .{ "a.href", "" },
+ .{ "a.host", "" },
.{ "a.href = 'about'", null },
.{ "a.href", "https://lightpanda.io/opensource-browser/about" },
}, .{});
diff --git a/src/browser/url/url.zig b/src/browser/url/url.zig
index 6d31d3c5..1b6e2c86 100644
--- a/src/browser/url/url.zig
+++ b/src/browser/url/url.zig
@@ -54,6 +54,11 @@ pub const URL = struct {
uri: std.Uri,
search_params: URLSearchParams,
+ pub const empty = URL{
+ .uri = .{ .scheme = "" },
+ .search_params = .{},
+ };
+
const URLArg = union(enum) {
url: *URL,
element: *parser.ElementHTML,