Skip to content

Commit d7155e6

Browse files
committed
An empty anchor should return empty strings for its getters
document.createElement('a').host or .href or .. should return an empty string. However, URL.constructor(document.createElement('a')) should fail. Because HTMLAnchorElement uses URL.constructor, we have the wrong behavior. This adds a guard for an empty anchor. This might not cover all of the cases which are valid for an anchor but invalid for a URL.constructor, but it's the most common.
1 parent 22a644b commit d7155e6

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/browser/html/elements.zig

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,18 @@ pub const HTMLAnchorElement = struct {
271271
return try parser.nodeSetTextContent(parser.anchorToNode(self), v);
272272
}
273273

274-
inline fn url(self: *parser.Anchor, page: *Page) !URL {
275-
return URL.constructor(.{ .element = @alignCast(@ptrCast(self)) }, null, page); // TODO inject base url
274+
fn url(self: *parser.Anchor, page: *Page) !URL {
275+
// Although the URL.constructor union accepts an .{.element = X}, we
276+
// can't use this here because the behavior is different.
277+
// new URL(document.createElement('a')
278+
// should fail (a.href isn't a valid URL)
279+
// But
280+
// document.createElement('a').host
281+
// should not fail, it should return an empty string
282+
if (try parser.elementGetAttribute(@alignCast(@ptrCast(self)), "href")) |href| {
283+
return URL.constructor(.{ .string = href }, null, page); // TODO inject base url
284+
}
285+
return .empty;
276286
}
277287

278288
// TODO return a disposable string
@@ -1559,6 +1569,8 @@ test "Browser.HTML.Element" {
15591569

15601570
try runner.testCases(&.{
15611571
.{ "let a = document.createElement('a');", null },
1572+
.{ "a.href", "" },
1573+
.{ "a.host", "" },
15621574
.{ "a.href = 'about'", null },
15631575
.{ "a.href", "https://lightpanda.io/opensource-browser/about" },
15641576
}, .{});

src/browser/url/url.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ pub const URL = struct {
5454
uri: std.Uri,
5555
search_params: URLSearchParams,
5656

57+
pub const empty = URL{
58+
.uri = .{ .scheme = "" },
59+
.search_params = .{},
60+
};
61+
5762
const URLArg = union(enum) {
5863
url: *URL,
5964
element: *parser.ElementHTML,

0 commit comments

Comments
 (0)