diff --git a/src/dom/element.zig b/src/dom/element.zig index c5f9a645..0410ad1e 100644 --- a/src/dom/element.zig +++ b/src/dom/element.zig @@ -2,6 +2,10 @@ const std = @import("std"); const parser = @import("../netsurf.zig"); +const jsruntime = @import("jsruntime"); +const Case = jsruntime.test_utils.Case; +const checkCases = jsruntime.test_utils.checkCases; + const Node = @import("node.zig").Node; const HTMLElem = @import("../html/elements.zig"); pub const Union = @import("../html/elements.zig").Union; @@ -22,4 +26,50 @@ pub const Element = struct { pub fn get_localName(self: *parser.Element) ![]const u8 { return try parser.elementLocalName(self); } + + pub fn _getAttribute(self: *parser.Element, qname: []const u8) !?[]const u8 { + return try parser.elementGetAttribute(self, qname); + } + + pub fn _setAttribute(self: *parser.Element, qname: []const u8, value: []const u8) !void { + return try parser.elementSetAttribute(self, qname, value); + } + + pub fn _removeAttribute(self: *parser.Element, qname: []const u8) !void { + return try parser.elementRemoveAttribute(self, qname); + } + + pub fn _hasAttribute(self: *parser.Element, qname: []const u8) !bool { + return try parser.elementHasAttribute(self, qname); + } }; + +// Tests +// ----- + +pub fn testExecFn( + _: std.mem.Allocator, + js_env: *jsruntime.Env, + comptime _: []jsruntime.API, +) !void { + var attribute = [_]Case{ + .{ .src = "let div = document.getElementById('content')", .ex = "undefined" }, + .{ .src = "div.getAttribute('id')", .ex = "content" }, + + .{ .src = "div.hasAttribute('foo')", .ex = "false" }, + .{ .src = "div.getAttribute('foo')", .ex = "null" }, + + .{ .src = "div.setAttribute('foo', 'bar')", .ex = "undefined" }, + .{ .src = "div.hasAttribute('foo')", .ex = "true" }, + .{ .src = "div.getAttribute('foo')", .ex = "bar" }, + + .{ .src = "div.setAttribute('foo', 'baz')", .ex = "undefined" }, + .{ .src = "div.hasAttribute('foo')", .ex = "true" }, + .{ .src = "div.getAttribute('foo')", .ex = "baz" }, + + .{ .src = "div.removeAttribute('foo')", .ex = "undefined" }, + .{ .src = "div.hasAttribute('foo')", .ex = "false" }, + .{ .src = "div.getAttribute('foo')", .ex = "null" }, + }; + try checkCases(js_env, &attribute); +} diff --git a/src/netsurf.zig b/src/netsurf.zig index a7d0a22f..1c857ad6 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -749,6 +749,34 @@ pub fn elementGetAttribute(elem: *Element, name: []const u8) !?[]const u8 { return stringToData(s.?); } +pub fn elementSetAttribute(elem: *Element, qname: []const u8, value: []const u8) !void { + const err = elementVtable(elem).dom_element_set_attribute.?( + elem, + try stringFromData(qname), + try stringFromData(value), + ); + try DOMErr(err); +} + +pub fn elementRemoveAttribute(elem: *Element, qname: []const u8) !void { + const err = elementVtable(elem).dom_element_remove_attribute.?( + elem, + try stringFromData(qname), + ); + try DOMErr(err); +} + +pub fn elementHasAttribute(elem: *Element, qname: []const u8) !bool { + var res: bool = undefined; + const err = elementVtable(elem).dom_element_has_attribute.?( + elem, + try stringFromData(qname), + &res, + ); + try DOMErr(err); + return res; +} + pub fn elementHasClass(elem: *Element, class: []const u8) !bool { var res: bool = undefined; const err = elementVtable(elem).dom_element_has_class.?( diff --git a/src/run_tests.zig b/src/run_tests.zig index 9edab848..e478b84f 100644 --- a/src/run_tests.zig +++ b/src/run_tests.zig @@ -11,6 +11,7 @@ const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn; const nodeTestExecFn = @import("dom/node.zig").testExecFn; const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn; const textTestExecFn = @import("dom/text.zig").testExecFn; +const elementTestExecFn = @import("dom/element.zig").testExecFn; const HTMLCollectionTestExecFn = @import("dom/html_collection.zig").testExecFn; const DOMExceptionTestExecFn = @import("dom/exceptions.zig").testExecFn; const DOMImplementationExecFn = @import("dom/implementation.zig").testExecFn; @@ -56,6 +57,7 @@ fn testsAllExecFn( nodeTestExecFn, characterDataTestExecFn, textTestExecFn, + elementTestExecFn, HTMLCollectionTestExecFn, DOMExceptionTestExecFn, DOMImplementationExecFn, diff --git a/tests/wpt/dom/nodes/Element-hasAttribute.html b/tests/wpt/dom/nodes/Element-hasAttribute.html new file mode 100644 index 00000000..26528d75 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-hasAttribute.html @@ -0,0 +1,32 @@ + + +