Files
browser/src/dom/element.zig
2023-12-05 09:15:54 +01:00

130 lines
4.4 KiB
Zig
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
const DOMException = @import("exceptions.zig").DOMException;
// WEB IDL https://dom.spec.whatwg.org/#element
pub const Element = struct {
pub const Self = parser.Element;
pub const prototype = *Node;
pub const mem_guarantied = true;
pub fn toInterface(e: *parser.Element) !Union {
return try HTMLElem.toInterface(Union, e);
}
// JS funcs
// --------
pub fn get_localName(self: *parser.Element) ![]const u8 {
return try parser.elementLocalName(self);
}
pub fn get_attributes(self: *parser.Element) !*parser.NamedNodeMap {
return try parser.nodeGetAttributes(parser.elementToNode(self));
}
pub fn _hasAttributes(self: *parser.Element) !bool {
return try parser.nodeHasAttributes(parser.elementToNode(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);
}
// https://dom.spec.whatwg.org/#dom-element-toggleattribute
pub fn _toggleAttribute(self: *parser.Element, qname: []const u8, force: ?bool) !bool {
const exists = try parser.elementHasAttribute(self, qname);
// If attribute is null, then:
if (!exists) {
// If force is not given or is true, create an attribute whose
// local name is qualifiedName, value is the empty string and node
// document is thiss node document, then append this attribute to
// this, and then return true.
if (force == null or force.?) {
try parser.elementSetAttribute(self, qname, "");
return true;
}
// Return false.
return false;
}
// Otherwise, if force is not given or is false, remove an attribute
// given qualifiedName and this, and then return false.
if (force == null or !force.?) {
try parser.elementRemoveAttribute(self, qname);
return false;
}
// Return true.
return true;
}
};
// Tests
// -----
pub fn testExecFn(
_: std.mem.Allocator,
js_env: *jsruntime.Env,
comptime _: []jsruntime.API,
) !void {
var attribute = [_]Case{
.{ .src = "let a = document.getElementById('content')", .ex = "undefined" },
.{ .src = "a.hasAttributes()", .ex = "true" },
.{ .src = "a.attributes.length", .ex = "1" },
.{ .src = "a.getAttribute('id')", .ex = "content" },
.{ .src = "a.hasAttribute('foo')", .ex = "false" },
.{ .src = "a.getAttribute('foo')", .ex = "null" },
.{ .src = "a.setAttribute('foo', 'bar')", .ex = "undefined" },
.{ .src = "a.hasAttribute('foo')", .ex = "true" },
.{ .src = "a.getAttribute('foo')", .ex = "bar" },
.{ .src = "a.setAttribute('foo', 'baz')", .ex = "undefined" },
.{ .src = "a.hasAttribute('foo')", .ex = "true" },
.{ .src = "a.getAttribute('foo')", .ex = "baz" },
.{ .src = "a.removeAttribute('foo')", .ex = "undefined" },
.{ .src = "a.hasAttribute('foo')", .ex = "false" },
.{ .src = "a.getAttribute('foo')", .ex = "null" },
};
try checkCases(js_env, &attribute);
var toggleAttr = [_]Case{
.{ .src = "let b = document.getElementById('content')", .ex = "undefined" },
.{ .src = "b.toggleAttribute('foo')", .ex = "true" },
.{ .src = "b.hasAttribute('foo')", .ex = "true" },
.{ .src = "b.getAttribute('foo')", .ex = "" },
.{ .src = "b.toggleAttribute('foo')", .ex = "false" },
.{ .src = "b.hasAttribute('foo')", .ex = "false" },
};
try checkCases(js_env, &toggleAttr);
}