Skip to content

Commit df6a905

Browse files
committed
dom: add target and href accessors to anchor
1 parent 88c9875 commit df6a905

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/html/elements.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@
1515
//
1616
// You should have received a copy of the GNU Affero General Public License
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
const std = @import("std");
1819

1920
const parser = @import("../netsurf.zig");
2021
const generate = @import("../generate.zig");
2122

23+
const jsruntime = @import("jsruntime");
24+
const Case = jsruntime.test_utils.Case;
25+
const checkCases = jsruntime.test_utils.checkCases;
26+
2227
const Element = @import("../dom/element.zig").Element;
2328

2429
// HTMLElement interfaces
@@ -126,10 +131,31 @@ pub const HTMLUnknownElement = struct {
126131
pub const mem_guarantied = true;
127132
};
128133

134+
// https://html.spec.whatwg.org/#the-a-element
129135
pub const HTMLAnchorElement = struct {
130136
pub const Self = parser.Anchor;
131137
pub const prototype = *HTMLElement;
132138
pub const mem_guarantied = true;
139+
140+
pub fn get_target(self: *parser.Anchor) ![]const u8 {
141+
return try parser.anchorGetTarget(self);
142+
}
143+
144+
pub fn set_target(self: *parser.Anchor, href: []const u8) !void {
145+
return try parser.anchorSetTarget(self, href);
146+
}
147+
148+
pub fn get_download(_: *parser.Anchor) ![]const u8 {
149+
return ""; // TODO
150+
}
151+
152+
pub fn get_href(self: *parser.Anchor) ![]const u8 {
153+
return try parser.anchorGetHref(self);
154+
}
155+
156+
pub fn set_href(self: *parser.Anchor, href: []const u8) !void {
157+
return try parser.anchorSetTarget(self, href);
158+
}
133159
};
134160

135161
pub const HTMLAppletElement = struct {
@@ -589,3 +615,20 @@ pub fn toInterface(comptime T: type, e: *parser.Element) !T {
589615
.undef => .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(elem)) },
590616
};
591617
}
618+
619+
// Tests
620+
// -----
621+
622+
pub fn testExecFn(
623+
_: std.mem.Allocator,
624+
js_env: *jsruntime.Env,
625+
) anyerror!void {
626+
var anchor = [_]Case{
627+
.{ .src = "let a = document.getElementById('link')", .ex = "undefined" },
628+
.{ .src = "a.target", .ex = "" },
629+
.{ .src = "a.target = '_blank'", .ex = "_blank" },
630+
.{ .src = "a.href", .ex = "foo" },
631+
.{ .src = "a.href = 'https://lightpanda.io/'", .ex = "https://lightpanda.io/" },
632+
};
633+
try checkCases(js_env, &anchor);
634+
}

src/netsurf.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,33 @@ pub fn elementHTMLGetTagType(elem_html: *ElementHTML) !Tag {
15131513
return @as(Tag, @enumFromInt(tag_type));
15141514
}
15151515

1516+
// HTMLAnchorElement
1517+
pub fn anchorGetTarget(a: *Anchor) ![]const u8 {
1518+
var res: ?*String = undefined;
1519+
const err = c.dom_html_anchor_element_get_target(a, &res);
1520+
try DOMErr(err);
1521+
if (res == null) return "";
1522+
return strToData(res.?);
1523+
}
1524+
1525+
pub fn anchorSetTarget(a: *Anchor, target: []const u8) !void {
1526+
const err = c.dom_html_anchor_element_set_target(a, try strFromData(target));
1527+
try DOMErr(err);
1528+
}
1529+
1530+
pub fn anchorGetHref(a: *Anchor) ![]const u8 {
1531+
var res: ?*String = undefined;
1532+
const err = c.dom_html_anchor_element_get_href(a, &res);
1533+
try DOMErr(err);
1534+
if (res == null) return "";
1535+
return strToData(res.?);
1536+
}
1537+
1538+
pub fn anchorSetHref(a: *Anchor, href: []const u8) !void {
1539+
const err = c.dom_html_anchor_element_set_href(a, try strFromData(href));
1540+
try DOMErr(err);
1541+
}
1542+
15161543
// ElementsHTML
15171544

15181545
pub const MediaElement = struct { base: *c.dom_html_element };

src/run_tests.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const XHRTestExecFn = xhr.testExecFn;
5151
const ProgressEventTestExecFn = @import("xhr/progress_event.zig").testExecFn;
5252
const StorageTestExecFn = storage.testExecFn;
5353
const URLTestExecFn = url.testExecFn;
54+
const HTMLElementTestExecFn = @import("html/elements.zig").testExecFn;
5455

5556
pub const Types = jsruntime.reflect(apiweb.Interfaces);
5657

@@ -117,6 +118,7 @@ fn testsAllExecFn(
117118
ProcessingInstructionTestExecFn,
118119
StorageTestExecFn,
119120
URLTestExecFn,
121+
HTMLElementTestExecFn,
120122
};
121123

122124
inline for (testFns) |testFn| {

0 commit comments

Comments
 (0)