mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
130 lines
4.4 KiB
Zig
130 lines
4.4 KiB
Zig
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 this’s 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);
|
||
}
|