mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
Make "Safe" variants of Attribute work on String
This commit is contained in:
@@ -1037,7 +1037,7 @@ pub fn scriptAddedCallback(self: *Page, comptime from_parser: bool, script: *Ele
|
|||||||
self._script_manager.addFromElement(from_parser, script, "parsing") catch |err| {
|
self._script_manager.addFromElement(from_parser, script, "parsing") catch |err| {
|
||||||
log.err(.page, "page.scriptAddedCallback", .{
|
log.err(.page, "page.scriptAddedCallback", .{
|
||||||
.err = err,
|
.err = err,
|
||||||
.src = script.asElement().getAttributeSafe("src"),
|
.src = script.asElement().getAttributeSafe(comptime .literal("src")),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1122,7 @@ pub fn getElementByIdFromNode(self: *Page, node: *Node, id: []const u8) ?*Elemen
|
|||||||
}
|
}
|
||||||
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(node, .{});
|
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(node, .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
const element_id = el.getAttributeSafe("id") orelse continue;
|
const element_id = el.getAttributeSafe(comptime .literal("id")) orelse continue;
|
||||||
if (std.mem.eql(u8, element_id, id)) {
|
if (std.mem.eql(u8, element_id, id)) {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
@@ -1696,7 +1696,7 @@ pub fn createElementNS(self: *Page, namespace: Element.Namespace, name: []const
|
|||||||
// If page's base url is not already set, fill it with the base
|
// If page's base url is not already set, fill it with the base
|
||||||
// tag.
|
// tag.
|
||||||
if (self.base_url == null) {
|
if (self.base_url == null) {
|
||||||
if (n.as(Element).getAttributeSafe("href")) |href| {
|
if (n.as(Element).getAttributeSafe(comptime .literal("href"))) |href| {
|
||||||
self.base_url = try URL.resolve(self.arena, self.url, href, .{});
|
self.base_url = try URL.resolve(self.arena, self.url, href, .{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2307,7 +2307,7 @@ pub fn removeNode(self: *Page, parent: *Node, child: *Node, opts: RemoveNodeOpts
|
|||||||
if (parent.is(Element)) |parent_el| {
|
if (parent.is(Element)) |parent_el| {
|
||||||
if (self._element_shadow_roots.get(parent_el)) |shadow_root| {
|
if (self._element_shadow_roots.get(parent_el)) |shadow_root| {
|
||||||
// Signal slot changes for any affected slots
|
// Signal slot changes for any affected slots
|
||||||
const slot_name = el.getAttributeSafe("slot") orelse "";
|
const slot_name = el.getAttributeSafe(comptime .literal("slot")) orelse "";
|
||||||
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(shadow_root.asNode(), .{});
|
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(shadow_root.asNode(), .{});
|
||||||
while (tw.next()) |slot_el| {
|
while (tw.next()) |slot_el| {
|
||||||
if (slot_el.is(Element.Html.Slot)) |slot| {
|
if (slot_el.is(Element.Html.Slot)) |slot| {
|
||||||
@@ -2346,7 +2346,7 @@ pub fn removeNode(self: *Page, parent: *Node, child: *Node, opts: RemoveNodeOpts
|
|||||||
// the ID map and invoking disconnectedCallback for custom elements
|
// the ID map and invoking disconnectedCallback for custom elements
|
||||||
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(child, .{});
|
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(child, .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
if (el.getAttributeSafe("id")) |id| {
|
if (el.getAttributeSafe(comptime .literal("id"))) |id| {
|
||||||
self.removeElementIdWithMaps(id_maps.?, id);
|
self.removeElementIdWithMaps(id_maps.?, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2480,7 +2480,7 @@ pub fn _insertNodeRelative(self: *Page, comptime from_parser: bool, parent: *Nod
|
|||||||
// For main document parsing, we know nodes are connected (fast path)
|
// For main document parsing, we know nodes are connected (fast path)
|
||||||
// For fragment parsing (innerHTML), we need to check connectivity
|
// For fragment parsing (innerHTML), we need to check connectivity
|
||||||
if (child.isConnected() or child.isInShadowTree()) {
|
if (child.isConnected() or child.isInShadowTree()) {
|
||||||
if (el.getAttributeSafe("id")) |id| {
|
if (el.getAttributeSafe(comptime .literal("id"))) |id| {
|
||||||
try self.addElementId(parent, el, id);
|
try self.addElementId(parent, el, id);
|
||||||
}
|
}
|
||||||
try Element.Html.Custom.invokeConnectedCallbackOnElement(true, el, self);
|
try Element.Html.Custom.invokeConnectedCallbackOnElement(true, el, self);
|
||||||
@@ -2519,7 +2519,7 @@ pub fn _insertNodeRelative(self: *Page, comptime from_parser: bool, parent: *Nod
|
|||||||
|
|
||||||
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(child, .{});
|
var tw = @import("webapi/TreeWalker.zig").Full.Elements.init(child, .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
if (el.getAttributeSafe("id")) |id| {
|
if (el.getAttributeSafe(comptime .literal("id"))) |id| {
|
||||||
try self.addElementId(el.asNode()._parent.?, el, id);
|
try self.addElementId(el.asNode()._parent.?, el, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2622,7 +2622,7 @@ fn updateElementAssignedSlot(self: *Page, element: *Element) void {
|
|||||||
const parent_el = parent.is(Element) orelse return;
|
const parent_el = parent.is(Element) orelse return;
|
||||||
const shadow_root = self._element_shadow_roots.get(parent_el) orelse return;
|
const shadow_root = self._element_shadow_roots.get(parent_el) orelse return;
|
||||||
|
|
||||||
const slot_name = element.getAttributeSafe("slot") orelse "";
|
const slot_name = element.getAttributeSafe(comptime .literal("slot")) orelse "";
|
||||||
|
|
||||||
// Recursively search through the shadow root for a matching slot
|
// Recursively search through the shadow root for a matching slot
|
||||||
if (findMatchingSlot(shadow_root.asNode(), slot_name)) |slot| {
|
if (findMatchingSlot(shadow_root.asNode(), slot_name)) |slot| {
|
||||||
@@ -2919,7 +2919,7 @@ pub fn handleClick(self: *Page, target: *Node) !void {
|
|||||||
|
|
||||||
switch (html_element._type) {
|
switch (html_element._type) {
|
||||||
.anchor => |anchor| {
|
.anchor => |anchor| {
|
||||||
const href = element.getAttributeSafe("href") orelse return;
|
const href = element.getAttributeSafe(comptime .literal("href")) orelse return;
|
||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3015,7 +3015,7 @@ pub fn submitForm(self: *Page, submitter_: ?*Element, form_: ?*Element.Html.Form
|
|||||||
const form = form_ orelse return;
|
const form = form_ orelse return;
|
||||||
|
|
||||||
if (submitter_) |submitter| {
|
if (submitter_) |submitter| {
|
||||||
if (submitter.getAttributeSafe("disabled") != null) {
|
if (submitter.getAttributeSafe(comptime .literal("disabled")) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3028,13 +3028,13 @@ pub fn submitForm(self: *Page, submitter_: ?*Element, form_: ?*Element.Html.Form
|
|||||||
|
|
||||||
const transfer_arena = self._session.transfer_arena;
|
const transfer_arena = self._session.transfer_arena;
|
||||||
|
|
||||||
const encoding = form_element.getAttributeSafe("enctype");
|
const encoding = form_element.getAttributeSafe(comptime .literal("enctype"));
|
||||||
|
|
||||||
var buf = std.Io.Writer.Allocating.init(transfer_arena);
|
var buf = std.Io.Writer.Allocating.init(transfer_arena);
|
||||||
try form_data.write(encoding, &buf.writer);
|
try form_data.write(encoding, &buf.writer);
|
||||||
|
|
||||||
const method = form_element.getAttributeSafe("method") orelse "";
|
const method = form_element.getAttributeSafe(comptime .literal("method")) orelse "";
|
||||||
var action = form_element.getAttributeSafe("action") orelse self.url;
|
var action = form_element.getAttributeSafe(comptime .literal("action")) orelse self.url;
|
||||||
|
|
||||||
var opts = NavigateOpts{
|
var opts = NavigateOpts{
|
||||||
.reason = .form,
|
.reason = .form,
|
||||||
|
|||||||
@@ -152,14 +152,14 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
script_element._executed = true;
|
script_element._executed = true;
|
||||||
|
|
||||||
const element = script_element.asElement();
|
const element = script_element.asElement();
|
||||||
if (element.getAttributeSafe("nomodule") != null) {
|
if (element.getAttributeSafe(comptime .literal("nomodule")) != null) {
|
||||||
// these scripts should only be loaded if we don't support modules
|
// these scripts should only be loaded if we don't support modules
|
||||||
// but since we do support modules, we can just skip them.
|
// but since we do support modules, we can just skip them.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const kind: Script.Kind = blk: {
|
const kind: Script.Kind = blk: {
|
||||||
const script_type = element.getAttributeSafe("type") orelse break :blk .javascript;
|
const script_type = element.getAttributeSafe(comptime .literal("type")) orelse break :blk .javascript;
|
||||||
if (script_type.len == 0) {
|
if (script_type.len == 0) {
|
||||||
break :blk .javascript;
|
break :blk .javascript;
|
||||||
}
|
}
|
||||||
@@ -186,7 +186,7 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
var source: Script.Source = undefined;
|
var source: Script.Source = undefined;
|
||||||
var remote_url: ?[:0]const u8 = null;
|
var remote_url: ?[:0]const u8 = null;
|
||||||
const base_url = page.base();
|
const base_url = page.base();
|
||||||
if (element.getAttributeSafe("src")) |src| {
|
if (element.getAttributeSafe(comptime .literal("src"))) |src| {
|
||||||
if (try parseDataURI(page.arena, src)) |data_uri| {
|
if (try parseDataURI(page.arena, src)) |data_uri| {
|
||||||
source = .{ .@"inline" = data_uri };
|
source = .{ .@"inline" = data_uri };
|
||||||
} else {
|
} else {
|
||||||
@@ -217,12 +217,12 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
break :blk if (kind == .module) .@"defer" else .normal;
|
break :blk if (kind == .module) .@"defer" else .normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.getAttributeSafe("async") != null) {
|
if (element.getAttributeSafe(comptime .literal("async")) != null) {
|
||||||
break :blk .async;
|
break :blk .async;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for defer or module (before checking dynamic script default)
|
// Check for defer or module (before checking dynamic script default)
|
||||||
if (kind == .module or element.getAttributeSafe("defer") != null) {
|
if (kind == .module or element.getAttributeSafe(comptime .literal("defer")) != null) {
|
||||||
break :blk .@"defer";
|
break :blk .@"defer";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ fn _deep(node: *Node, opts: Opts, comptime force_slot: bool, writer: *std.Io.Wri
|
|||||||
// to render that "active" content, so when we're trying to render
|
// to render that "active" content, so when we're trying to render
|
||||||
// it, we don't want to skip it.
|
// it, we don't want to skip it.
|
||||||
if ((comptime force_slot == false) and opts.shadow == .rendered) {
|
if ((comptime force_slot == false) and opts.shadow == .rendered) {
|
||||||
if (el.getAttributeSafe("slot")) |_| {
|
if (el.getAttributeSafe(comptime .literal("slot"))) |_| {
|
||||||
// Skip - will be rendered by the Slot if it's the active container
|
// Skip - will be rendered by the Slot if it's the active container
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -253,12 +253,12 @@ fn shouldStripElement(el: *const Node.Element, opts: Opts) bool {
|
|||||||
if (std.mem.eql(u8, tag_name, "noscript")) return true;
|
if (std.mem.eql(u8, tag_name, "noscript")) return true;
|
||||||
|
|
||||||
if (std.mem.eql(u8, tag_name, "link")) {
|
if (std.mem.eql(u8, tag_name, "link")) {
|
||||||
if (el.getAttributeSafe("as")) |as| {
|
if (el.getAttributeSafe(comptime .literal("as"))) |as| {
|
||||||
if (std.mem.eql(u8, as, "script")) return true;
|
if (std.mem.eql(u8, as, "script")) return true;
|
||||||
}
|
}
|
||||||
if (el.getAttributeSafe("rel")) |rel| {
|
if (el.getAttributeSafe(comptime .literal("rel"))) |rel| {
|
||||||
if (std.mem.eql(u8, rel, "modulepreload") or std.mem.eql(u8, rel, "preload")) {
|
if (std.mem.eql(u8, rel, "modulepreload") or std.mem.eql(u8, rel, "preload")) {
|
||||||
if (el.getAttributeSafe("as")) |as| {
|
if (el.getAttributeSafe(comptime .literal("as"))) |as| {
|
||||||
if (std.mem.eql(u8, as, "script")) return true;
|
if (std.mem.eql(u8, as, "script")) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ fn shouldStripElement(el: *const Node.Element, opts: Opts) bool {
|
|||||||
if (std.mem.eql(u8, tag_name, "style")) return true;
|
if (std.mem.eql(u8, tag_name, "style")) return true;
|
||||||
|
|
||||||
if (std.mem.eql(u8, tag_name, "link")) {
|
if (std.mem.eql(u8, tag_name, "link")) {
|
||||||
if (el.getAttributeSafe("rel")) |rel| {
|
if (el.getAttributeSafe(comptime .literal("rel"))) |rel| {
|
||||||
if (std.mem.eql(u8, rel, "stylesheet")) return true;
|
if (std.mem.eql(u8, rel, "stylesheet")) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -624,14 +624,14 @@ fn jsValueToStruct(self: *const Local, comptime T: type, js_val: js.Value) !?T {
|
|||||||
if (!js_val.isString()) {
|
if (!js_val.isString()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return try self.valueToStringSSO(js_val, .{.allocator = self.ctx.call_arena});
|
return try self.valueToStringSSO(js_val, .{ .allocator = self.ctx.call_arena });
|
||||||
},
|
},
|
||||||
string.Global => {
|
string.Global => {
|
||||||
if (!js_val.isString()) {
|
if (!js_val.isString()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Use arena for persistent strings
|
// Use arena for persistent strings
|
||||||
return .{.str = try self.valueToStringSSO(js_val, .{ .allocator = self.ctx.arena }) };
|
return .{ .str = try self.valueToStringSSO(js_val, .{ .allocator = self.ctx.arena }) };
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
if (!js_val.isObject()) {
|
if (!js_val.isObject()) {
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ pub fn getElementById(self: *Document, id: []const u8, page: *Page) ?*Element {
|
|||||||
if (self._removed_ids.remove(id)) {
|
if (self._removed_ids.remove(id)) {
|
||||||
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
const element_id = el.getAttributeSafe("id") orelse continue;
|
const element_id = el.getAttributeSafe(comptime .literal("id")) orelse continue;
|
||||||
if (std.mem.eql(u8, element_id, id)) {
|
if (std.mem.eql(u8, element_id, id)) {
|
||||||
// we ignore this error to keep getElementById easy to call
|
// we ignore this error to keep getElementById easy to call
|
||||||
// if it really failed, then we're out of memory and nothing's
|
// if it really failed, then we're out of memory and nothing's
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ pub fn getElementById(self: *DocumentFragment, id: []const u8) ?*Element {
|
|||||||
|
|
||||||
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
if (el.getAttributeSafe("id")) |element_id| {
|
if (el.getAttributeSafe(comptime .literal("id"))) |element_id| {
|
||||||
if (std.mem.eql(u8, element_id, id)) {
|
if (std.mem.eql(u8, element_id, id)) {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ pub fn setInnerHTML(self: *Element, html: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getId(self: *const Element) []const u8 {
|
pub fn getId(self: *const Element) []const u8 {
|
||||||
return self.getAttributeSafe("id") orelse "";
|
return self.getAttributeSafe(comptime .literal("id")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setId(self: *Element, value: []const u8, page: *Page) !void {
|
pub fn setId(self: *Element, value: []const u8, page: *Page) !void {
|
||||||
@@ -435,7 +435,7 @@ pub fn setId(self: *Element, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSlot(self: *const Element) []const u8 {
|
pub fn getSlot(self: *const Element) []const u8 {
|
||||||
return self.getAttributeSafe("slot") orelse "";
|
return self.getAttributeSafe(comptime .literal("slot")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setSlot(self: *Element, value: []const u8, page: *Page) !void {
|
pub fn setSlot(self: *Element, value: []const u8, page: *Page) !void {
|
||||||
@@ -443,7 +443,7 @@ pub fn setSlot(self: *Element, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDir(self: *const Element) []const u8 {
|
pub fn getDir(self: *const Element) []const u8 {
|
||||||
return self.getAttributeSafe("dir") orelse "";
|
return self.getAttributeSafe(comptime .literal("dir")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDir(self: *Element, value: []const u8, page: *Page) !void {
|
pub fn setDir(self: *Element, value: []const u8, page: *Page) !void {
|
||||||
@@ -451,7 +451,7 @@ pub fn setDir(self: *Element, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getClassName(self: *const Element) []const u8 {
|
pub fn getClassName(self: *const Element) []const u8 {
|
||||||
return self.getAttributeSafe("class") orelse "";
|
return self.getAttributeSafe(comptime .literal("class")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setClassName(self: *Element, value: []const u8, page: *Page) !void {
|
pub fn setClassName(self: *Element, value: []const u8, page: *Page) !void {
|
||||||
@@ -484,7 +484,7 @@ pub fn getAttributeNS(
|
|||||||
return self.getAttribute(local_name, page);
|
return self.getAttribute(local_name, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAttributeSafe(self: *const Element, name: []const u8) ?[]const u8 {
|
pub fn getAttributeSafe(self: *const Element, name: String) ?[]const u8 {
|
||||||
const attributes = self._attributes orelse return null;
|
const attributes = self._attributes orelse return null;
|
||||||
return attributes.getSafe(name);
|
return attributes.getSafe(name);
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ pub fn hasAttribute(self: *const Element, name: []const u8, page: *Page) !bool {
|
|||||||
return value != null;
|
return value != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hasAttributeSafe(self: *const Element, name: []const u8) bool {
|
pub fn hasAttributeSafe(self: *const Element, name: String) bool {
|
||||||
const attributes = self._attributes orelse return false;
|
const attributes = self._attributes orelse return false;
|
||||||
return attributes.hasSafe(name);
|
return attributes.hasSafe(name);
|
||||||
}
|
}
|
||||||
@@ -666,7 +666,7 @@ pub fn getClassList(self: *Element, page: *Page) !*collections.DOMTokenList {
|
|||||||
if (!gop.found_existing) {
|
if (!gop.found_existing) {
|
||||||
gop.value_ptr.* = try page._factory.create(collections.DOMTokenList{
|
gop.value_ptr.* = try page._factory.create(collections.DOMTokenList{
|
||||||
._element = self,
|
._element = self,
|
||||||
._attribute_name = "class",
|
._attribute_name = comptime .literal("class"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return gop.value_ptr.*;
|
return gop.value_ptr.*;
|
||||||
@@ -677,7 +677,7 @@ pub fn getRelList(self: *Element, page: *Page) !*collections.DOMTokenList {
|
|||||||
if (!gop.found_existing) {
|
if (!gop.found_existing) {
|
||||||
gop.value_ptr.* = try page._factory.create(collections.DOMTokenList{
|
gop.value_ptr.* = try page._factory.create(collections.DOMTokenList{
|
||||||
._element = self,
|
._element = self,
|
||||||
._attribute_name = "rel",
|
._attribute_name = comptime .literal("rel"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return gop.value_ptr.*;
|
return gop.value_ptr.*;
|
||||||
@@ -919,10 +919,10 @@ fn getElementDimensions(self: *Element, page: *Page) !struct { width: f64, heigh
|
|||||||
if (width == 5.0) width = 1920.0;
|
if (width == 5.0) width = 1920.0;
|
||||||
if (height == 5.0) height = 100_000_000.0;
|
if (height == 5.0) height = 100_000_000.0;
|
||||||
} else if (tag == .img or tag == .iframe) {
|
} else if (tag == .img or tag == .iframe) {
|
||||||
if (self.getAttributeSafe("width")) |w| {
|
if (self.getAttributeSafe(comptime .literal("width"))) |w| {
|
||||||
width = std.fmt.parseFloat(f64, w) catch width;
|
width = std.fmt.parseFloat(f64, w) catch width;
|
||||||
}
|
}
|
||||||
if (self.getAttributeSafe("height")) |h| {
|
if (self.getAttributeSafe(comptime .literal("height"))) |h| {
|
||||||
height = std.fmt.parseFloat(f64, h) catch height;
|
height = std.fmt.parseFloat(f64, h) catch height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ pub fn getElementById(self: *ShadowRoot, id: []const u8, page: *Page) ?*Element
|
|||||||
// Do a tree walk to find another element with this ID
|
// Do a tree walk to find another element with this ID
|
||||||
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
var tw = @import("TreeWalker.zig").Full.Elements.init(self.asNode(), .{});
|
||||||
while (tw.next()) |el| {
|
while (tw.next()) |el| {
|
||||||
const element_id = el.getAttributeSafe("id") orelse continue;
|
const element_id = el.getAttributeSafe(comptime .literal("id")) orelse continue;
|
||||||
if (std.mem.eql(u8, element_id, id)) {
|
if (std.mem.eql(u8, element_id, id)) {
|
||||||
// we ignore this error to keep getElementById easy to call
|
// we ignore this error to keep getElementById easy to call
|
||||||
// if it really failed, then we're out of memory and nothing's
|
// if it really failed, then we're out of memory and nothing's
|
||||||
|
|||||||
@@ -18,8 +18,9 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const log = @import("../../../log.zig");
|
const log = @import("../../../log.zig");
|
||||||
const js = @import("../../js/js.zig");
|
const String = @import("../../../string.zig").String;
|
||||||
|
|
||||||
|
const js = @import("../../js/js.zig");
|
||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
const Element = @import("../Element.zig");
|
const Element = @import("../Element.zig");
|
||||||
const GenericIterator = @import("iterator.zig").Entry;
|
const GenericIterator = @import("iterator.zig").Entry;
|
||||||
@@ -31,7 +32,7 @@ pub const DOMTokenList = @This();
|
|||||||
// is that lists tend to be very short (often just 1 item).
|
// is that lists tend to be very short (often just 1 item).
|
||||||
|
|
||||||
_element: *Element,
|
_element: *Element,
|
||||||
_attribute_name: []const u8,
|
_attribute_name: String,
|
||||||
|
|
||||||
pub const KeyIterator = GenericIterator(Iterator, "0");
|
pub const KeyIterator = GenericIterator(Iterator, "0");
|
||||||
pub const ValueIterator = GenericIterator(Iterator, "1");
|
pub const ValueIterator = GenericIterator(Iterator, "1");
|
||||||
@@ -160,7 +161,7 @@ pub fn getValue(self: *const DOMTokenList) []const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setValue(self: *DOMTokenList, value: []const u8, page: *Page) !void {
|
pub fn setValue(self: *DOMTokenList, value: []const u8, page: *Page) !void {
|
||||||
try self._element.setAttribute(self._attribute_name, value, page);
|
try self._element.setAttribute(self._attribute_name.str(), value, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keys(self: *DOMTokenList, page: *Page) !*KeyIterator {
|
pub fn keys(self: *DOMTokenList, page: *Page) !*KeyIterator {
|
||||||
@@ -226,7 +227,7 @@ fn validateToken(token: []const u8) !void {
|
|||||||
|
|
||||||
fn updateAttribute(self: *DOMTokenList, tokens: Lookup, page: *Page) !void {
|
fn updateAttribute(self: *DOMTokenList, tokens: Lookup, page: *Page) !void {
|
||||||
const joined = try std.mem.join(page.call_arena, " ", tokens.keys());
|
const joined = try std.mem.join(page.call_arena, " ", tokens.keys());
|
||||||
try self._element.setAttribute(self._attribute_name, joined, page);
|
try self._element.setAttribute(self._attribute_name.str(), joined, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Iterator = struct {
|
const Iterator = struct {
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ pub fn getByName(self: *HTMLAllCollection, name: []const u8, page: *Page) ?*Elem
|
|||||||
|
|
||||||
while (tw.next()) |node| {
|
while (tw.next()) |node| {
|
||||||
if (node.is(Element)) |el| {
|
if (node.is(Element)) |el| {
|
||||||
if (el.getAttributeSafe("name")) |attr_name| {
|
if (el.getAttributeSafe(comptime .literal("name"))) |attr_name| {
|
||||||
if (std.mem.eql(u8, attr_name, name)) {
|
if (std.mem.eql(u8, attr_name, name)) {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ pub fn namedItem(self: *HTMLFormControlsCollection, name: []const u8, page: *Pag
|
|||||||
var it = try self.iterator();
|
var it = try self.iterator();
|
||||||
while (it.next()) |element| {
|
while (it.next()) |element| {
|
||||||
const is_match = blk: {
|
const is_match = blk: {
|
||||||
if (element.getAttributeSafe("id")) |id| {
|
if (element.getAttributeSafe(comptime .literal("id"))) |id| {
|
||||||
if (std.mem.eql(u8, id, name)) {
|
if (std.mem.eql(u8, id, name)) {
|
||||||
break :blk true;
|
break :blk true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (element.getAttributeSafe("name")) |elem_name| {
|
if (element.getAttributeSafe(comptime .literal("name"))) |elem_name| {
|
||||||
if (std.mem.eql(u8, elem_name, name)) {
|
if (std.mem.eql(u8, elem_name, name)) {
|
||||||
break :blk true;
|
break :blk true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub fn getValue(self: *RadioNodeList) ![]const u8 {
|
|||||||
if (!input.getChecked()) {
|
if (!input.getChecked()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return element.getAttributeSafe("value") orelse "on";
|
return element.getAttributeSafe(comptime .literal("value")) orelse "on";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ pub fn setValue(self: *RadioNodeList, value: []const u8, page: *Page) !void {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const input_value = element.getAttributeSafe("value");
|
const input_value = element.getAttributeSafe(comptime .literal("value"));
|
||||||
const matches_value = blk: {
|
const matches_value = blk: {
|
||||||
if (std.mem.eql(u8, value, "on")) {
|
if (std.mem.eql(u8, value, "on")) {
|
||||||
break :blk input_value == null or (input_value != null and std.mem.eql(u8, input_value.?, "on"));
|
break :blk input_value == null or (input_value != null and std.mem.eql(u8, input_value.?, "on"));
|
||||||
@@ -99,12 +99,12 @@ pub fn setValue(self: *RadioNodeList, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn matches(self: *const RadioNodeList, element: *Element) bool {
|
fn matches(self: *const RadioNodeList, element: *Element) bool {
|
||||||
if (element.getAttributeSafe("id")) |id| {
|
if (element.getAttributeSafe(comptime .literal("id"))) |id| {
|
||||||
if (std.mem.eql(u8, id, self._name)) {
|
if (std.mem.eql(u8, id, self._name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (element.getAttributeSafe("name")) |elem_name| {
|
if (element.getAttributeSafe(comptime .literal("name"))) |elem_name| {
|
||||||
if (std.mem.eql(u8, elem_name, self._name)) {
|
if (std.mem.eql(u8, elem_name, self._name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ pub fn NodeLive(comptime mode: Mode) type {
|
|||||||
// (like length or getAtIndex)
|
// (like length or getAtIndex)
|
||||||
var tw = self._tw.clone();
|
var tw = self._tw.clone();
|
||||||
while (self.nextTw(&tw)) |element| {
|
while (self.nextTw(&tw)) |element| {
|
||||||
const element_name = element.getAttributeSafe("name") orelse continue;
|
const element_name = element.getAttributeSafe(comptime .literal("name")) orelse continue;
|
||||||
if (std.mem.eql(u8, element_name, name)) {
|
if (std.mem.eql(u8, element_name, name)) {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ pub fn NodeLive(comptime mode: Mode) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const el = node.is(Element) orelse return false;
|
const el = node.is(Element) orelse return false;
|
||||||
const class_attr = el.getAttributeSafe("class") orelse return false;
|
const class_attr = el.getAttributeSafe(comptime .literal("class")) orelse return false;
|
||||||
for (self._filter) |class_name| {
|
for (self._filter) |class_name| {
|
||||||
if (!Selector.classAttributeContains(class_attr, class_name)) {
|
if (!Selector.classAttributeContains(class_attr, class_name)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -238,7 +238,7 @@ pub fn NodeLive(comptime mode: Mode) type {
|
|||||||
},
|
},
|
||||||
.name => {
|
.name => {
|
||||||
const el = node.is(Element) orelse return false;
|
const el = node.is(Element) orelse return false;
|
||||||
const name_attr = el.getAttributeSafe("name") orelse return false;
|
const name_attr = el.getAttributeSafe(comptime .literal("name")) orelse return false;
|
||||||
return std.mem.eql(u8, name_attr, self._filter);
|
return std.mem.eql(u8, name_attr, self._filter);
|
||||||
},
|
},
|
||||||
.all_elements => return node._type == .element,
|
.all_elements => return node._type == .element,
|
||||||
@@ -258,14 +258,14 @@ pub fn NodeLive(comptime mode: Mode) type {
|
|||||||
const el = node.is(Element) orelse return false;
|
const el = node.is(Element) orelse return false;
|
||||||
const Anchor = Element.Html.Anchor;
|
const Anchor = Element.Html.Anchor;
|
||||||
if (el.is(Anchor) == null) return false;
|
if (el.is(Anchor) == null) return false;
|
||||||
return el.hasAttributeSafe("href");
|
return el.hasAttributeSafe(comptime .literal("href"));
|
||||||
},
|
},
|
||||||
.anchors => {
|
.anchors => {
|
||||||
// Anchors are <a> elements with name attribute
|
// Anchors are <a> elements with name attribute
|
||||||
const el = node.is(Element) orelse return false;
|
const el = node.is(Element) orelse return false;
|
||||||
const Anchor = Element.Html.Anchor;
|
const Anchor = Element.Html.Anchor;
|
||||||
if (el.is(Anchor) == null) return false;
|
if (el.is(Anchor) == null) return false;
|
||||||
return el.hasAttributeSafe("name");
|
return el.hasAttributeSafe(comptime .literal("name"));
|
||||||
},
|
},
|
||||||
.form => {
|
.form => {
|
||||||
const el = node.is(Element) orelse return false;
|
const el = node.is(Element) orelse return false;
|
||||||
@@ -273,8 +273,8 @@ pub fn NodeLive(comptime mode: Mode) type {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.getAttributeSafe("form")) |form_attr| {
|
if (el.getAttributeSafe(comptime .literal("form"))) |form_attr| {
|
||||||
const form_id = self._filter.asElement().getAttributeSafe("id") orelse return false;
|
const form_id = self._filter.asElement().getAttributeSafe(comptime .literal("id")) orelse return false;
|
||||||
return std.mem.eql(u8, form_attr, form_id);
|
return std.mem.eql(u8, form_attr, form_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,13 +170,13 @@ pub const List = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// meant for internal usage, where the name is known to be properly cased
|
// meant for internal usage, where the name is known to be properly cased
|
||||||
pub fn getSafe(self: *const List, name: []const u8) ?[]const u8 {
|
pub fn getSafe(self: *const List, name: String) ?[]const u8 {
|
||||||
const entry = self.getEntryWithNormalizedName(name) orelse return null;
|
const entry = self.getEntryWithNormalizedName(name) orelse return null;
|
||||||
return entry._value.str();
|
return entry._value.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// meant for internal usage, where the name is known to be properly cased
|
// meant for internal usage, where the name is known to be properly cased
|
||||||
pub fn hasSafe(self: *const List, name: []const u8) bool {
|
pub fn hasSafe(self: *const List, name: String) bool {
|
||||||
return self.getEntryWithNormalizedName(name) != null;
|
return self.getEntryWithNormalizedName(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ pub const List = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn putSafe(self: *List, name: []const u8, value: []const u8, element: *Element, page: *Page) !*Entry {
|
pub fn putSafe(self: *List, name: []const u8, value: []const u8, element: *Element, page: *Page) !*Entry {
|
||||||
const entry = self.getEntryWithNormalizedName(name);
|
const entry = self.getEntryWithNormalizedNameOld(name);
|
||||||
return self._put(.{ .entry = entry, .normalized = name }, value, element, page);
|
return self._put(.{ .entry = entry, .normalized = name }, value, element, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,11 +331,24 @@ pub const List = struct {
|
|||||||
|
|
||||||
return .{
|
return .{
|
||||||
.normalized = normalized,
|
.normalized = normalized,
|
||||||
.entry = self.getEntryWithNormalizedName(normalized),
|
.entry = self.getEntryWithNormalizedNameOld(normalized),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getEntryWithNormalizedName(self: *const List, name: []const u8) ?*Entry {
|
fn getEntryWithNormalizedName(self: *const List, name: String) ?*Entry {
|
||||||
|
var node = self._list.first;
|
||||||
|
while (node) |n| {
|
||||||
|
var e = Entry.fromNode(n);
|
||||||
|
if (e._name.eql(name)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
node = n.next;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO remove when we're done making everything String-based
|
||||||
|
fn getEntryWithNormalizedNameOld(self: *const List, name: []const u8) ?*Entry {
|
||||||
var node = self._list.first;
|
var node = self._list.first;
|
||||||
while (node) |n| {
|
while (node) |n| {
|
||||||
var e = Entry.fromNode(n);
|
var e = Entry.fromNode(n);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub fn asNode(self: *Anchor) *Node {
|
|||||||
|
|
||||||
pub fn getHref(self: *Anchor, page: *Page) ![]const u8 {
|
pub fn getHref(self: *Anchor, page: *Page) ![]const u8 {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
const href = element.getAttributeSafe("href") orelse return "";
|
const href = element.getAttributeSafe(comptime .literal("href")) orelse return "";
|
||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ pub fn setHref(self: *Anchor, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTarget(self: *Anchor) []const u8 {
|
pub fn getTarget(self: *Anchor) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("target") orelse "";
|
return self.asElement().getAttributeSafe(comptime .literal("target")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setTarget(self: *Anchor, value: []const u8, page: *Page) !void {
|
pub fn setTarget(self: *Anchor, value: []const u8, page: *Page) !void {
|
||||||
@@ -167,7 +167,7 @@ pub fn setProtocol(self: *Anchor, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getType(self: *Anchor) []const u8 {
|
pub fn getType(self: *Anchor) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("type") orelse "";
|
return self.asElement().getAttributeSafe(comptime .literal("type")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setType(self: *Anchor, value: []const u8, page: *Page) !void {
|
pub fn setType(self: *Anchor, value: []const u8, page: *Page) !void {
|
||||||
@@ -175,7 +175,7 @@ pub fn setType(self: *Anchor, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Anchor) []const u8 {
|
pub fn getName(self: *const Anchor) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Anchor, value: []const u8, page: *Page) !void {
|
pub fn setName(self: *Anchor, value: []const u8, page: *Page) !void {
|
||||||
@@ -191,7 +191,7 @@ pub fn setText(self: *Anchor, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn getResolvedHref(self: *Anchor, page: *Page) !?[:0]const u8 {
|
fn getResolvedHref(self: *Anchor, page: *Page) !?[:0]const u8 {
|
||||||
const href = self.asElement().getAttributeSafe("href") orelse return null;
|
const href = self.asElement().getAttributeSafe(comptime .literal("href")) orelse return null;
|
||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ pub const JsApi = struct {
|
|||||||
pub const Build = struct {
|
pub const Build = struct {
|
||||||
pub fn complete(node: *Node, page: *Page) !void {
|
pub fn complete(node: *Node, page: *Page) !void {
|
||||||
const el = node.as(Element);
|
const el = node.as(Element);
|
||||||
const on_load = el.getAttributeSafe("onload") orelse return;
|
const on_load = el.getAttributeSafe(comptime .literal("onload")) orelse return;
|
||||||
if (page.js.stringToPersistedFunction(on_load)) |func| {
|
if (page.js.stringToPersistedFunction(on_load)) |func| {
|
||||||
page.window._on_load = func;
|
page.window._on_load = func;
|
||||||
} else |err| {
|
} else |err| {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub fn asNode(self: *Button) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisabled(self: *const Button) bool {
|
pub fn getDisabled(self: *const Button) bool {
|
||||||
return self.asConstElement().getAttributeSafe("disabled") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisabled(self: *Button, disabled: bool, page: *Page) !void {
|
pub fn setDisabled(self: *Button, disabled: bool, page: *Page) !void {
|
||||||
@@ -51,7 +51,7 @@ pub fn setDisabled(self: *Button, disabled: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Button) []const u8 {
|
pub fn getName(self: *const Button) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Button, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Button, name: []const u8, page: *Page) !void {
|
||||||
@@ -59,7 +59,7 @@ pub fn setName(self: *Button, name: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getType(self: *const Button) []const u8 {
|
pub fn getType(self: *const Button) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("type") orelse "submit";
|
return self.asConstElement().getAttributeSafe(comptime .literal("type")) orelse "submit";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setType(self: *Button, typ: []const u8, page: *Page) !void {
|
pub fn setType(self: *Button, typ: []const u8, page: *Page) !void {
|
||||||
@@ -67,7 +67,7 @@ pub fn setType(self: *Button, typ: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getValue(self: *const Button) []const u8 {
|
pub fn getValue(self: *const Button) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("value") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("value")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setValue(self: *Button, value: []const u8, page: *Page) !void {
|
pub fn setValue(self: *Button, value: []const u8, page: *Page) !void {
|
||||||
@@ -75,7 +75,7 @@ pub fn setValue(self: *Button, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRequired(self: *const Button) bool {
|
pub fn getRequired(self: *const Button) bool {
|
||||||
return self.asConstElement().getAttributeSafe("required") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("required")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRequired(self: *Button, required: bool, page: *Page) !void {
|
pub fn setRequired(self: *Button, required: bool, page: *Page) !void {
|
||||||
@@ -90,7 +90,7 @@ pub fn getForm(self: *Button, page: *Page) ?*Form {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// If form attribute exists, ONLY use that (even if it references nothing)
|
// If form attribute exists, ONLY use that (even if it references nothing)
|
||||||
if (element.getAttributeSafe("form")) |form_id| {
|
if (element.getAttributeSafe(comptime .literal("form"))) |form_id| {
|
||||||
if (page.document.getElementById(form_id, page)) |form_element| {
|
if (page.document.getElementById(form_id, page)) |form_element| {
|
||||||
return form_element.is(Form);
|
return form_element.is(Form);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub fn asNode(self: *Canvas) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getWidth(self: *const Canvas) u32 {
|
pub fn getWidth(self: *const Canvas) u32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("width") orelse return 300;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("width")) orelse return 300;
|
||||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 300;
|
return std.fmt.parseUnsigned(u32, attr, 10) catch 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ pub fn setWidth(self: *Canvas, value: u32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHeight(self: *const Canvas) u32 {
|
pub fn getHeight(self: *const Canvas) u32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("height") orelse return 150;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("height")) orelse return 150;
|
||||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 150;
|
return std.fmt.parseUnsigned(u32, attr, 10) catch 150;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ fn invokeCallbackOnElement(element: *Element, definition: *CustomElementDefiniti
|
|||||||
|
|
||||||
// Check if element has "is" attribute and attach customized built-in definition
|
// Check if element has "is" attribute and attach customized built-in definition
|
||||||
pub fn checkAndAttachBuiltIn(element: *Element, page: *Page) !void {
|
pub fn checkAndAttachBuiltIn(element: *Element, page: *Page) !void {
|
||||||
const is_value = element.getAttributeSafe("is") orelse return;
|
const is_value = element.getAttributeSafe(comptime .literal("is")) orelse return;
|
||||||
|
|
||||||
const custom_elements = page.window.getCustomElements();
|
const custom_elements = page.window.getCustomElements();
|
||||||
const definition = custom_elements._definitions.get(is_value) orelse return;
|
const definition = custom_elements._definitions.get(is_value) orelse return;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn asNode(self: *Data) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getValue(self: *Data) []const u8 {
|
pub fn getValue(self: *Data) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("value") orelse "";
|
return self.asElement().getAttributeSafe(comptime .literal("value")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setValue(self: *Data, value: []const u8, page: *Page) !void {
|
pub fn setValue(self: *Data, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub fn asNode(self: *Dialog) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOpen(self: *const Dialog) bool {
|
pub fn getOpen(self: *const Dialog) bool {
|
||||||
return self.asConstElement().getAttributeSafe("open") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("open")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setOpen(self: *Dialog, open: bool, page: *Page) !void {
|
pub fn setOpen(self: *Dialog, open: bool, page: *Page) !void {
|
||||||
@@ -32,7 +32,7 @@ pub fn setOpen(self: *Dialog, open: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getReturnValue(self: *const Dialog) []const u8 {
|
pub fn getReturnValue(self: *const Dialog) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("returnvalue") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("returnvalue")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setReturnValue(self: *Dialog, value: []const u8, page: *Page) !void {
|
pub fn setReturnValue(self: *Dialog, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ pub fn asNode(self: *Form) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Form) []const u8 {
|
pub fn getName(self: *const Form) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Form, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Form, name: []const u8, page: *Page) !void {
|
||||||
@@ -51,7 +51,7 @@ pub fn setName(self: *Form, name: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMethod(self: *const Form) []const u8 {
|
pub fn getMethod(self: *const Form) []const u8 {
|
||||||
const method = self.asConstElement().getAttributeSafe("method") orelse return "get";
|
const method = self.asConstElement().getAttributeSafe(comptime .literal("method")) orelse return "get";
|
||||||
|
|
||||||
if (std.ascii.eqlIgnoreCase(method, "post")) {
|
if (std.ascii.eqlIgnoreCase(method, "post")) {
|
||||||
return "post";
|
return "post";
|
||||||
@@ -68,7 +68,7 @@ pub fn setMethod(self: *Form, method: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getElements(self: *Form, page: *Page) !*collections.HTMLFormControlsCollection {
|
pub fn getElements(self: *Form, page: *Page) !*collections.HTMLFormControlsCollection {
|
||||||
const form_id = self.asElement().getAttributeSafe("id");
|
const form_id = self.asElement().getAttributeSafe(comptime .literal("id"));
|
||||||
const root = if (form_id != null)
|
const root = if (form_id != null)
|
||||||
self.asNode().getRootNode(null) // Has ID: walk entire document to find form=ID controls
|
self.asNode().getRootNode(null) // Has ID: walk entire document to find form=ID controls
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn asNode(self: *Image) *Node {
|
|||||||
|
|
||||||
pub fn getSrc(self: *const Image, page: *Page) ![]const u8 {
|
pub fn getSrc(self: *const Image, page: *Page) ![]const u8 {
|
||||||
const element = self.asConstElement();
|
const element = self.asConstElement();
|
||||||
const src = element.getAttributeSafe("src") orelse return "";
|
const src = element.getAttributeSafe(comptime .literal("src")) orelse return "";
|
||||||
if (src.len == 0) {
|
if (src.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ pub fn setSrc(self: *Image, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAlt(self: *const Image) []const u8 {
|
pub fn getAlt(self: *const Image) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("alt") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("alt")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setAlt(self: *Image, value: []const u8, page: *Page) !void {
|
pub fn setAlt(self: *Image, value: []const u8, page: *Page) !void {
|
||||||
@@ -58,7 +58,7 @@ pub fn setAlt(self: *Image, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getWidth(self: *const Image) u32 {
|
pub fn getWidth(self: *const Image) u32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("width") orelse return 0;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("width")) orelse return 0;
|
||||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ pub fn setWidth(self: *Image, value: u32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHeight(self: *const Image) u32 {
|
pub fn getHeight(self: *const Image) u32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("height") orelse return 0;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("height")) orelse return 0;
|
||||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ pub fn setHeight(self: *Image, value: u32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCrossOrigin(self: *const Image) ?[]const u8 {
|
pub fn getCrossOrigin(self: *const Image) ?[]const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("crossorigin");
|
return self.asConstElement().getAttributeSafe(comptime .literal("crossorigin"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setCrossOrigin(self: *Image, value: ?[]const u8, page: *Page) !void {
|
pub fn setCrossOrigin(self: *Image, value: ?[]const u8, page: *Page) !void {
|
||||||
@@ -89,7 +89,7 @@ pub fn setCrossOrigin(self: *Image, value: ?[]const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getLoading(self: *const Image) []const u8 {
|
pub fn getLoading(self: *const Image) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("loading") orelse "eager";
|
return self.asConstElement().getAttributeSafe(comptime .literal("loading")) orelse "eager";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setLoading(self: *Image, value: []const u8, page: *Page) !void {
|
pub fn setLoading(self: *Image, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ pub fn setDefaultChecked(self: *Input, checked: bool, page: *Page) !void {
|
|||||||
pub fn getDisabled(self: *const Input) bool {
|
pub fn getDisabled(self: *const Input) bool {
|
||||||
// TODO: Also check for disabled fieldset ancestors
|
// TODO: Also check for disabled fieldset ancestors
|
||||||
// (but not if we're inside a <legend> of that fieldset)
|
// (but not if we're inside a <legend> of that fieldset)
|
||||||
return self.asConstElement().getAttributeSafe("disabled") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisabled(self: *Input, disabled: bool, page: *Page) !void {
|
pub fn setDisabled(self: *Input, disabled: bool, page: *Page) !void {
|
||||||
@@ -168,7 +168,7 @@ pub fn setDisabled(self: *Input, disabled: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Input) []const u8 {
|
pub fn getName(self: *const Input) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Input, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Input, name: []const u8, page: *Page) !void {
|
||||||
@@ -176,7 +176,7 @@ pub fn setName(self: *Input, name: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAccept(self: *const Input) []const u8 {
|
pub fn getAccept(self: *const Input) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("accept") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("accept")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setAccept(self: *Input, accept: []const u8, page: *Page) !void {
|
pub fn setAccept(self: *Input, accept: []const u8, page: *Page) !void {
|
||||||
@@ -184,7 +184,7 @@ pub fn setAccept(self: *Input, accept: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAlt(self: *const Input) []const u8 {
|
pub fn getAlt(self: *const Input) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("alt") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("alt")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setAlt(self: *Input, alt: []const u8, page: *Page) !void {
|
pub fn setAlt(self: *Input, alt: []const u8, page: *Page) !void {
|
||||||
@@ -192,7 +192,7 @@ pub fn setAlt(self: *Input, alt: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMaxLength(self: *const Input) i32 {
|
pub fn getMaxLength(self: *const Input) i32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("maxlength") orelse return -1;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("maxlength")) orelse return -1;
|
||||||
return std.fmt.parseInt(i32, attr, 10) catch -1;
|
return std.fmt.parseInt(i32, attr, 10) catch -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ pub fn setMaxLength(self: *Input, max_length: i32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSize(self: *const Input) i32 {
|
pub fn getSize(self: *const Input) i32 {
|
||||||
const attr = self.asConstElement().getAttributeSafe("size") orelse return 20;
|
const attr = self.asConstElement().getAttributeSafe(comptime .literal("size")) orelse return 20;
|
||||||
const parsed = std.fmt.parseInt(i32, attr, 10) catch return 20;
|
const parsed = std.fmt.parseInt(i32, attr, 10) catch return 20;
|
||||||
return if (parsed == 0) 20 else parsed;
|
return if (parsed == 0) 20 else parsed;
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ pub fn setSize(self: *Input, size: i32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSrc(self: *const Input, page: *Page) ![]const u8 {
|
pub fn getSrc(self: *const Input, page: *Page) ![]const u8 {
|
||||||
const src = self.asConstElement().getAttributeSafe("src") orelse return "";
|
const src = self.asConstElement().getAttributeSafe(comptime .literal("src")) orelse return "";
|
||||||
// If attribute is explicitly set (even if empty), resolve it against the base URL
|
// If attribute is explicitly set (even if empty), resolve it against the base URL
|
||||||
return @import("../../URL.zig").resolve(page.call_arena, page.base(), src, .{});
|
return @import("../../URL.zig").resolve(page.call_arena, page.base(), src, .{});
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@ pub fn setSrc(self: *Input, src: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getReadonly(self: *const Input) bool {
|
pub fn getReadonly(self: *const Input) bool {
|
||||||
return self.asConstElement().getAttributeSafe("readonly") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("readonly")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setReadonly(self: *Input, readonly: bool, page: *Page) !void {
|
pub fn setReadonly(self: *Input, readonly: bool, page: *Page) !void {
|
||||||
@@ -248,7 +248,7 @@ pub fn setReadonly(self: *Input, readonly: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRequired(self: *const Input) bool {
|
pub fn getRequired(self: *const Input) bool {
|
||||||
return self.asConstElement().getAttributeSafe("required") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("required")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRequired(self: *Input, required: bool, page: *Page) !void {
|
pub fn setRequired(self: *Input, required: bool, page: *Page) !void {
|
||||||
@@ -379,7 +379,7 @@ pub fn getForm(self: *Input, page: *Page) ?*Form {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// If form attribute exists, ONLY use that (even if it references nothing)
|
// If form attribute exists, ONLY use that (even if it references nothing)
|
||||||
if (element.getAttributeSafe("form")) |form_id| {
|
if (element.getAttributeSafe(comptime .literal("form"))) |form_id| {
|
||||||
if (page.document.getElementById(form_id, page)) |form_element| {
|
if (page.document.getElementById(form_id, page)) |form_element| {
|
||||||
return form_element.is(Form);
|
return form_element.is(Form);
|
||||||
}
|
}
|
||||||
@@ -402,7 +402,7 @@ pub fn getForm(self: *Input, page: *Page) ?*Form {
|
|||||||
fn uncheckRadioGroup(self: *Input, page: *Page) !void {
|
fn uncheckRadioGroup(self: *Input, page: *Page) !void {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
const name = element.getAttributeSafe("name") orelse return;
|
const name = element.getAttributeSafe(comptime .literal("name")) orelse return;
|
||||||
if (name.len == 0) {
|
if (name.len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -420,7 +420,7 @@ fn uncheckRadioGroup(self: *Input, page: *Page) !void {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const other_name = other_element.getAttributeSafe("name") orelse continue;
|
const other_name = other_element.getAttributeSafe(comptime .literal("name")) orelse continue;
|
||||||
if (!std.mem.eql(u8, name, other_name)) {
|
if (!std.mem.eql(u8, name, other_name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -481,14 +481,14 @@ pub const Build = struct {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// Store initial values from attributes
|
// Store initial values from attributes
|
||||||
self._default_value = element.getAttributeSafe("value");
|
self._default_value = element.getAttributeSafe(comptime .literal("value"));
|
||||||
self._default_checked = element.getAttributeSafe("checked") != null;
|
self._default_checked = element.getAttributeSafe(comptime .literal("checked")) != null;
|
||||||
|
|
||||||
// Current state starts equal to default
|
// Current state starts equal to default
|
||||||
self._value = self._default_value;
|
self._value = self._default_value;
|
||||||
self._checked = self._default_checked;
|
self._checked = self._default_checked;
|
||||||
|
|
||||||
self._input_type = if (element.getAttributeSafe("type")) |type_attr|
|
self._input_type = if (element.getAttributeSafe(comptime .literal("type"))) |type_attr|
|
||||||
Type.fromString(type_attr)
|
Type.fromString(type_attr)
|
||||||
else
|
else
|
||||||
.text;
|
.text;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn asNode(self: *Link) *Node {
|
|||||||
|
|
||||||
pub fn getHref(self: *Link, page: *Page) ![]const u8 {
|
pub fn getHref(self: *Link, page: *Page) ![]const u8 {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
const href = element.getAttributeSafe("href") orelse return "";
|
const href = element.getAttributeSafe(comptime .literal("href")) orelse return "";
|
||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ pub fn setHref(self: *Link, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRel(self: *Link) []const u8 {
|
pub fn getRel(self: *Link) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("rel") orelse return "";
|
return self.asElement().getAttributeSafe(comptime .literal("rel")) orelse return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRel(self: *Link, value: []const u8, page: *Page) !void {
|
pub fn setRel(self: *Link, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ pub fn setCurrentTime(self: *Media, value: f64) void {
|
|||||||
|
|
||||||
pub fn getSrc(self: *const Media, page: *Page) ![]const u8 {
|
pub fn getSrc(self: *const Media, page: *Page) ![]const u8 {
|
||||||
const element = self.asConstElement();
|
const element = self.asConstElement();
|
||||||
const src = element.getAttributeSafe("src") orelse return "";
|
const src = element.getAttributeSafe(comptime .literal("src")) orelse return "";
|
||||||
if (src.len == 0) {
|
if (src.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ pub fn setSrc(self: *Media, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAutoplay(self: *const Media) bool {
|
pub fn getAutoplay(self: *const Media) bool {
|
||||||
return self.asConstElement().getAttributeSafe("autoplay") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("autoplay")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setAutoplay(self: *Media, value: bool, page: *Page) !void {
|
pub fn setAutoplay(self: *Media, value: bool, page: *Page) !void {
|
||||||
@@ -244,7 +244,7 @@ pub fn setAutoplay(self: *Media, value: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getControls(self: *const Media) bool {
|
pub fn getControls(self: *const Media) bool {
|
||||||
return self.asConstElement().getAttributeSafe("controls") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("controls")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setControls(self: *Media, value: bool, page: *Page) !void {
|
pub fn setControls(self: *Media, value: bool, page: *Page) !void {
|
||||||
@@ -256,7 +256,7 @@ pub fn setControls(self: *Media, value: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getLoop(self: *const Media) bool {
|
pub fn getLoop(self: *const Media) bool {
|
||||||
return self.asConstElement().getAttributeSafe("loop") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("loop")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setLoop(self: *Media, value: bool, page: *Page) !void {
|
pub fn setLoop(self: *Media, value: bool, page: *Page) !void {
|
||||||
@@ -268,7 +268,7 @@ pub fn setLoop(self: *Media, value: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPreload(self: *const Media) []const u8 {
|
pub fn getPreload(self: *const Media) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("preload") orelse "auto";
|
return self.asConstElement().getAttributeSafe(comptime .literal("preload")) orelse "auto";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setPreload(self: *Media, value: []const u8, page: *Page) !void {
|
pub fn setPreload(self: *Media, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub fn asNode(self: *Meta) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *Meta) []const u8 {
|
pub fn getName(self: *Meta) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("name") orelse return "";
|
return self.asElement().getAttributeSafe(comptime .literal("name")) orelse return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Meta, value: []const u8, page: *Page) !void {
|
pub fn setName(self: *Meta, value: []const u8, page: *Page) !void {
|
||||||
@@ -45,7 +45,7 @@ pub fn setName(self: *Meta, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHttpEquiv(self: *Meta) []const u8 {
|
pub fn getHttpEquiv(self: *Meta) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("http-equiv") orelse return "";
|
return self.asElement().getAttributeSafe(comptime .literal("http-equiv")) orelse return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setHttpEquiv(self: *Meta, value: []const u8, page: *Page) !void {
|
pub fn setHttpEquiv(self: *Meta, value: []const u8, page: *Page) !void {
|
||||||
@@ -53,7 +53,7 @@ pub fn setHttpEquiv(self: *Meta, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getContent(self: *Meta) []const u8 {
|
pub fn getContent(self: *Meta) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("content") orelse return "";
|
return self.asElement().getAttributeSafe(comptime .literal("content")) orelse return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setContent(self: *Meta, value: []const u8, page: *Page) !void {
|
pub fn setContent(self: *Meta, value: []const u8, page: *Page) !void {
|
||||||
@@ -61,7 +61,7 @@ pub fn setContent(self: *Meta, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMedia(self: *Meta) []const u8 {
|
pub fn getMedia(self: *Meta) []const u8 {
|
||||||
return self.asElement().getAttributeSafe("media") orelse return "";
|
return self.asElement().getAttributeSafe(comptime .literal("media")) orelse return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setMedia(self: *Meta, value: []const u8, page: *Page) !void {
|
pub fn setMedia(self: *Meta, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ pub fn setDisabled(self: *Option, disabled: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Option) []const u8 {
|
pub fn getName(self: *const Option) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Option, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Option, name: []const u8, page: *Page) !void {
|
||||||
@@ -124,14 +124,14 @@ pub const Build = struct {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// Check for value attribute
|
// Check for value attribute
|
||||||
self._value = element.getAttributeSafe("value");
|
self._value = element.getAttributeSafe(comptime .literal("value"));
|
||||||
|
|
||||||
// Check for selected attribute
|
// Check for selected attribute
|
||||||
self._default_selected = element.getAttributeSafe("selected") != null;
|
self._default_selected = element.getAttributeSafe(comptime .literal("selected")) != null;
|
||||||
self._selected = self._default_selected;
|
self._selected = self._default_selected;
|
||||||
|
|
||||||
// Check for disabled attribute
|
// Check for disabled attribute
|
||||||
self._disabled = element.getAttributeSafe("disabled") != null;
|
self._disabled = element.getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributeChange(element: *Element, name: []const u8, value: []const u8, _: *Page) !void {
|
pub fn attributeChange(element: *Element, name: []const u8, value: []const u8, _: *Page) !void {
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ pub fn getSrc(self: *const Script, page: *Page) ![]const u8 {
|
|||||||
pub fn setSrc(self: *Script, src: []const u8, page: *Page) !void {
|
pub fn setSrc(self: *Script, src: []const u8, page: *Page) !void {
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
try element.setAttributeSafe("src", src, page);
|
try element.setAttributeSafe("src", src, page);
|
||||||
self._src = element.getAttributeSafe("src") orelse unreachable;
|
self._src = element.getAttributeSafe(comptime .literal("src")) orelse unreachable;
|
||||||
if (element.asNode().isConnected()) {
|
if (element.asNode().isConnected()) {
|
||||||
try page.scriptAddedCallback(false, self);
|
try page.scriptAddedCallback(false, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getType(self: *const Script) []const u8 {
|
pub fn getType(self: *const Script) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("type") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("type")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setType(self: *Script, value: []const u8, page: *Page) !void {
|
pub fn setType(self: *Script, value: []const u8, page: *Page) !void {
|
||||||
@@ -69,7 +69,7 @@ pub fn setType(self: *Script, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNonce(self: *const Script) []const u8 {
|
pub fn getNonce(self: *const Script) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("nonce") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("nonce")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setNonce(self: *Script, value: []const u8, page: *Page) !void {
|
pub fn setNonce(self: *Script, value: []const u8, page: *Page) !void {
|
||||||
@@ -93,7 +93,7 @@ pub fn setOnError(self: *Script, cb: ?js.Function.Global) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNoModule(self: *const Script) bool {
|
pub fn getNoModule(self: *const Script) bool {
|
||||||
return self.asConstElement().getAttributeSafe("nomodule") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("nomodule")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setInnerText(self: *Script, text: []const u8, page: *Page) !void {
|
pub fn setInnerText(self: *Script, text: []const u8, page: *Page) !void {
|
||||||
@@ -127,9 +127,9 @@ pub const Build = struct {
|
|||||||
pub fn complete(node: *Node, page: *Page) !void {
|
pub fn complete(node: *Node, page: *Page) !void {
|
||||||
const self = node.as(Script);
|
const self = node.as(Script);
|
||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
self._src = element.getAttributeSafe("src") orelse "";
|
self._src = element.getAttributeSafe(comptime .literal("src")) orelse "";
|
||||||
|
|
||||||
if (element.getAttributeSafe("onload")) |on_load| {
|
if (element.getAttributeSafe(comptime .literal("onload"))) |on_load| {
|
||||||
if (page.js.stringToPersistedFunction(on_load)) |func| {
|
if (page.js.stringToPersistedFunction(on_load)) |func| {
|
||||||
self._on_load = func;
|
self._on_load = func;
|
||||||
} else |err| {
|
} else |err| {
|
||||||
@@ -137,7 +137,7 @@ pub const Build = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.getAttributeSafe("onerror")) |on_error| {
|
if (element.getAttributeSafe(comptime .literal("onerror"))) |on_error| {
|
||||||
if (page.js.stringToPersistedFunction(on_error)) |func| {
|
if (page.js.stringToPersistedFunction(on_error)) |func| {
|
||||||
self._on_error = func;
|
self._on_error = func;
|
||||||
} else |err| {
|
} else |err| {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ pub fn setSelectedIndex(self: *Select, index: i32) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMultiple(self: *const Select) bool {
|
pub fn getMultiple(self: *const Select) bool {
|
||||||
return self.asConstElement().getAttributeSafe("multiple") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("multiple")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setMultiple(self: *Select, multiple: bool, page: *Page) !void {
|
pub fn setMultiple(self: *Select, multiple: bool, page: *Page) !void {
|
||||||
@@ -133,7 +133,7 @@ pub fn setMultiple(self: *Select, multiple: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisabled(self: *const Select) bool {
|
pub fn getDisabled(self: *const Select) bool {
|
||||||
return self.asConstElement().getAttributeSafe("disabled") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisabled(self: *Select, disabled: bool, page: *Page) !void {
|
pub fn setDisabled(self: *Select, disabled: bool, page: *Page) !void {
|
||||||
@@ -145,7 +145,7 @@ pub fn setDisabled(self: *Select, disabled: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Select) []const u8 {
|
pub fn getName(self: *const Select) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Select, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Select, name: []const u8, page: *Page) !void {
|
||||||
@@ -153,7 +153,7 @@ pub fn setName(self: *Select, name: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSize(self: *const Select) u32 {
|
pub fn getSize(self: *const Select) u32 {
|
||||||
const s = self.asConstElement().getAttributeSafe("size") orelse return 0;
|
const s = self.asConstElement().getAttributeSafe(comptime .literal("size")) orelse return 0;
|
||||||
|
|
||||||
const trimmed = std.mem.trimLeft(u8, s, &std.ascii.whitespace);
|
const trimmed = std.mem.trimLeft(u8, s, &std.ascii.whitespace);
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ pub fn setSize(self: *Select, size: u32, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRequired(self: *const Select) bool {
|
pub fn getRequired(self: *const Select) bool {
|
||||||
return self.asConstElement().getAttributeSafe("required") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("required")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRequired(self: *Select, required: bool, page: *Page) !void {
|
pub fn setRequired(self: *Select, required: bool, page: *Page) !void {
|
||||||
@@ -218,7 +218,7 @@ pub fn getForm(self: *Select, page: *Page) ?*Form {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// If form attribute exists, ONLY use that (even if it references nothing)
|
// If form attribute exists, ONLY use that (even if it references nothing)
|
||||||
if (element.getAttributeSafe("form")) |form_id| {
|
if (element.getAttributeSafe(comptime .literal("form"))) |form_id| {
|
||||||
if (page.document.getElementById(form_id, page)) |form_element| {
|
if (page.document.getElementById(form_id, page)) |form_element| {
|
||||||
return form_element.is(Form);
|
return form_element.is(Form);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub fn asNode(self: *Slot) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const Slot) []const u8 {
|
pub fn getName(self: *const Slot) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *Slot, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *Slot, name: []const u8, page: *Page) !void {
|
||||||
@@ -131,7 +131,7 @@ fn isAssignedToSlot(node: *Node, slot_name: []const u8) bool {
|
|||||||
// Check if a node should be assigned to a slot with the given name
|
// Check if a node should be assigned to a slot with the given name
|
||||||
if (node.is(Element)) |element| {
|
if (node.is(Element)) |element| {
|
||||||
// Get the slot attribute from the element
|
// Get the slot attribute from the element
|
||||||
const node_slot = element.getAttributeSafe("slot") orelse "";
|
const node_slot = element.getAttributeSafe(comptime .literal("slot")) orelse "";
|
||||||
|
|
||||||
// Match if:
|
// Match if:
|
||||||
// - Both are empty (default slot)
|
// - Both are empty (default slot)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub fn asNode(self: *Style) *Node {
|
|||||||
// Attribute-backed properties
|
// Attribute-backed properties
|
||||||
|
|
||||||
pub fn getBlocking(self: *const Style) []const u8 {
|
pub fn getBlocking(self: *const Style) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("blocking") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("blocking")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setBlocking(self: *Style, value: []const u8, page: *Page) !void {
|
pub fn setBlocking(self: *Style, value: []const u8, page: *Page) !void {
|
||||||
@@ -47,7 +47,7 @@ pub fn setBlocking(self: *Style, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMedia(self: *const Style) []const u8 {
|
pub fn getMedia(self: *const Style) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("media") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("media")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setMedia(self: *Style, value: []const u8, page: *Page) !void {
|
pub fn setMedia(self: *Style, value: []const u8, page: *Page) !void {
|
||||||
@@ -55,7 +55,7 @@ pub fn setMedia(self: *Style, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getType(self: *const Style) []const u8 {
|
pub fn getType(self: *const Style) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("type") orelse "text/css";
|
return self.asConstElement().getAttributeSafe(comptime .literal("type")) orelse "text/css";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setType(self: *Style, value: []const u8, page: *Page) !void {
|
pub fn setType(self: *Style, value: []const u8, page: *Page) !void {
|
||||||
@@ -63,7 +63,7 @@ pub fn setType(self: *Style, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisabled(self: *const Style) bool {
|
pub fn getDisabled(self: *const Style) bool {
|
||||||
return self.asConstElement().getAttributeSafe("disabled") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisabled(self: *Style, disabled: bool, page: *Page) !void {
|
pub fn setDisabled(self: *Style, disabled: bool, page: *Page) !void {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ pub fn setDefaultValue(self: *TextArea, value: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisabled(self: *const TextArea) bool {
|
pub fn getDisabled(self: *const TextArea) bool {
|
||||||
return self.asConstElement().getAttributeSafe("disabled") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisabled(self: *TextArea, disabled: bool, page: *Page) !void {
|
pub fn setDisabled(self: *TextArea, disabled: bool, page: *Page) !void {
|
||||||
@@ -96,7 +96,7 @@ pub fn setDisabled(self: *TextArea, disabled: bool, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(self: *const TextArea) []const u8 {
|
pub fn getName(self: *const TextArea) []const u8 {
|
||||||
return self.asConstElement().getAttributeSafe("name") orelse "";
|
return self.asConstElement().getAttributeSafe(comptime .literal("name")) orelse "";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setName(self: *TextArea, name: []const u8, page: *Page) !void {
|
pub fn setName(self: *TextArea, name: []const u8, page: *Page) !void {
|
||||||
@@ -104,7 +104,7 @@ pub fn setName(self: *TextArea, name: []const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRequired(self: *const TextArea) bool {
|
pub fn getRequired(self: *const TextArea) bool {
|
||||||
return self.asConstElement().getAttributeSafe("required") != null;
|
return self.asConstElement().getAttributeSafe(comptime .literal("required")) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRequired(self: *TextArea, required: bool, page: *Page) !void {
|
pub fn setRequired(self: *TextArea, required: bool, page: *Page) !void {
|
||||||
@@ -221,7 +221,7 @@ pub fn getForm(self: *TextArea, page: *Page) ?*Form {
|
|||||||
const element = self.asElement();
|
const element = self.asElement();
|
||||||
|
|
||||||
// If form attribute exists, ONLY use that (even if it references nothing)
|
// If form attribute exists, ONLY use that (even if it references nothing)
|
||||||
if (element.getAttributeSafe("form")) |form_id| {
|
if (element.getAttributeSafe(comptime .literal("form"))) |form_id| {
|
||||||
if (page.document.getElementById(form_id, page)) |form_element| {
|
if (page.document.getElementById(form_id, page)) |form_element| {
|
||||||
return form_element.is(Form);
|
return form_element.is(Form);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ pub fn getVideoHeight(_: *const Video) u32 {
|
|||||||
|
|
||||||
pub fn getPoster(self: *const Video, page: *Page) ![]const u8 {
|
pub fn getPoster(self: *const Video, page: *Page) ![]const u8 {
|
||||||
const element = self.asConstElement();
|
const element = self.asConstElement();
|
||||||
const poster = element.getAttributeSafe("poster") orelse return "";
|
const poster = element.getAttributeSafe(comptime .literal("poster")) orelse return "";
|
||||||
if (poster.len == 0) {
|
if (poster.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ fn collectForm(arena: Allocator, form_: ?*Form, submitter_: ?*Element, page: *Pa
|
|||||||
var elements = try form.getElements(page);
|
var elements = try form.getElements(page);
|
||||||
var it = try elements.iterator();
|
var it = try elements.iterator();
|
||||||
while (it.next()) |element| {
|
while (it.next()) |element| {
|
||||||
if (element.getAttributeSafe("disabled") != null) {
|
if (element.getAttributeSafe(comptime .literal("disabled")) != null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ fn collectForm(arena: Allocator, form_: ?*Form, submitter_: ?*Element, page: *Pa
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = element.getAttributeSafe("name");
|
const name = element.getAttributeSafe(comptime .literal("name"));
|
||||||
const x_key = if (name) |n| try std.fmt.allocPrint(arena, "{s}.x", .{n}) else "x";
|
const x_key = if (name) |n| try std.fmt.allocPrint(arena, "{s}.x", .{n}) else "x";
|
||||||
const y_key = if (name) |n| try std.fmt.allocPrint(arena, "{s}.y", .{n}) else "y";
|
const y_key = if (name) |n| try std.fmt.allocPrint(arena, "{s}.y", .{n}) else "y";
|
||||||
try list.append(arena, x_key, "0");
|
try list.append(arena, x_key, "0");
|
||||||
@@ -148,7 +148,7 @@ fn collectForm(arena: Allocator, form_: ?*Form, submitter_: ?*Element, page: *Pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = element.getAttributeSafe("name") orelse continue;
|
const name = element.getAttributeSafe(comptime .literal("name")) orelse continue;
|
||||||
const value = blk: {
|
const value = blk: {
|
||||||
if (element.is(Form.Input)) |input| {
|
if (element.is(Form.Input)) |input| {
|
||||||
const input_type = input._input_type;
|
const input_type = input._input_type;
|
||||||
|
|||||||
@@ -412,11 +412,11 @@ fn matchesCompound(el: *Node.Element, compound: Selector.Compound, scope: *Node,
|
|||||||
fn matchesPart(el: *Node.Element, part: Part, scope: *Node, page: *Page) bool {
|
fn matchesPart(el: *Node.Element, part: Part, scope: *Node, page: *Page) bool {
|
||||||
switch (part) {
|
switch (part) {
|
||||||
.id => |id| {
|
.id => |id| {
|
||||||
const element_id = el.getAttributeSafe("id") orelse return false;
|
const element_id = el.getAttributeSafe(comptime .literal("id")) orelse return false;
|
||||||
return std.mem.eql(u8, element_id, id);
|
return std.mem.eql(u8, element_id, id);
|
||||||
},
|
},
|
||||||
.class => |cls| {
|
.class => |cls| {
|
||||||
const class_attr = el.getAttributeSafe("class") orelse return false;
|
const class_attr = el.getAttributeSafe(comptime .literal("class")) orelse return false;
|
||||||
return Selector.classAttributeContains(class_attr, cls);
|
return Selector.classAttributeContains(class_attr, cls);
|
||||||
},
|
},
|
||||||
.tag => |tag| {
|
.tag => |tag| {
|
||||||
@@ -526,10 +526,10 @@ fn matchesPseudoClass(el: *Node.Element, pseudo: Selector.PseudoClass, scope: *N
|
|||||||
return input.getChecked();
|
return input.getChecked();
|
||||||
},
|
},
|
||||||
.disabled => {
|
.disabled => {
|
||||||
return el.getAttributeSafe("disabled") != null;
|
return el.getAttributeSafe(comptime .literal("disabled")) != null;
|
||||||
},
|
},
|
||||||
.enabled => {
|
.enabled => {
|
||||||
return el.getAttributeSafe("disabled") == null;
|
return el.getAttributeSafe(comptime .literal("disabled")) == null;
|
||||||
},
|
},
|
||||||
.indeterminate => return false,
|
.indeterminate => return false,
|
||||||
|
|
||||||
@@ -537,19 +537,19 @@ fn matchesPseudoClass(el: *Node.Element, pseudo: Selector.PseudoClass, scope: *N
|
|||||||
.valid => return false,
|
.valid => return false,
|
||||||
.invalid => return false,
|
.invalid => return false,
|
||||||
.required => {
|
.required => {
|
||||||
return el.getAttributeSafe("required") != null;
|
return el.getAttributeSafe(comptime .literal("required")) != null;
|
||||||
},
|
},
|
||||||
.optional => {
|
.optional => {
|
||||||
return el.getAttributeSafe("required") == null;
|
return el.getAttributeSafe(comptime .literal("required")) == null;
|
||||||
},
|
},
|
||||||
.in_range => return false,
|
.in_range => return false,
|
||||||
.out_of_range => return false,
|
.out_of_range => return false,
|
||||||
.placeholder_shown => return false,
|
.placeholder_shown => return false,
|
||||||
.read_only => {
|
.read_only => {
|
||||||
return el.getAttributeSafe("readonly") != null;
|
return el.getAttributeSafe(comptime .literal("readonly")) != null;
|
||||||
},
|
},
|
||||||
.read_write => {
|
.read_write => {
|
||||||
return el.getAttributeSafe("readonly") == null;
|
return el.getAttributeSafe(comptime .literal("readonly")) == null;
|
||||||
},
|
},
|
||||||
.default => return false,
|
.default => return false,
|
||||||
|
|
||||||
@@ -571,10 +571,10 @@ fn matchesPseudoClass(el: *Node.Element, pseudo: Selector.PseudoClass, scope: *N
|
|||||||
.visited => return false,
|
.visited => return false,
|
||||||
.any_link => {
|
.any_link => {
|
||||||
if (el.getTag() != .anchor) return false;
|
if (el.getTag() != .anchor) return false;
|
||||||
return el.getAttributeSafe("href") != null;
|
return el.getAttributeSafe(comptime .literal("href")) != null;
|
||||||
},
|
},
|
||||||
.target => {
|
.target => {
|
||||||
const element_id = el.getAttributeSafe("id") orelse return false;
|
const element_id = el.getAttributeSafe(comptime .literal("id")) orelse return false;
|
||||||
const location = page.document._location orelse return false;
|
const location = page.document._location orelse return false;
|
||||||
const hash = location.getHash();
|
const hash = location.getHash();
|
||||||
if (hash.len <= 1) return false;
|
if (hash.len <= 1) return false;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const String = @import("../../../string.zig").String;
|
||||||
|
|
||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ const ParseError = error{
|
|||||||
UnknownPseudoClass,
|
UnknownPseudoClass,
|
||||||
InvalidTagSelector,
|
InvalidTagSelector,
|
||||||
InvalidSelector,
|
InvalidSelector,
|
||||||
|
StringTooLarge,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parseList(arena: Allocator, input: []const u8, page: *Page) ParseError![]const Selector.Selector {
|
pub fn parseList(arena: Allocator, input: []const u8, page: *Page) ParseError![]const Selector.Selector {
|
||||||
@@ -846,7 +848,7 @@ fn attribute(self: *Parser, arena: Allocator, page: *Page) !Selector.Attribute {
|
|||||||
const attr_name = try self.attributeName();
|
const attr_name = try self.attributeName();
|
||||||
// Normalize the name to lowercase for fast matching (consistent with Attribute.normalizeNameForLookup)
|
// Normalize the name to lowercase for fast matching (consistent with Attribute.normalizeNameForLookup)
|
||||||
const normalized = try Attribute.normalizeNameForLookup(attr_name, page);
|
const normalized = try Attribute.normalizeNameForLookup(attr_name, page);
|
||||||
const name = try arena.dupe(u8, normalized);
|
const name = try String.init(arena, normalized, .{});
|
||||||
var case_insensitive = false;
|
var case_insensitive = false;
|
||||||
_ = self.skipSpaces();
|
_ = self.skipSpaces();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const String = @import("../../../string.zig").String;
|
||||||
|
|
||||||
const Parser = @import("Parser.zig");
|
const Parser = @import("Parser.zig");
|
||||||
const Node = @import("../Node.zig");
|
const Node = @import("../Node.zig");
|
||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
@@ -117,7 +119,7 @@ pub const Part = union(enum) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Attribute = struct {
|
pub const Attribute = struct {
|
||||||
name: []const u8,
|
name: String,
|
||||||
matcher: AttributeMatcher,
|
matcher: AttributeMatcher,
|
||||||
case_insensitive: bool,
|
case_insensitive: bool,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ pub const Writer = struct {
|
|||||||
},
|
},
|
||||||
.input => {
|
.input => {
|
||||||
const input = el.as(DOMNode.Element.Html.Input);
|
const input = el.as(DOMNode.Element.Html.Input);
|
||||||
const is_disabled = el.hasAttributeSafe("disabled");
|
const is_disabled = el.hasAttributeSafe(comptime .literal("disabled"));
|
||||||
|
|
||||||
switch (input._input_type) {
|
switch (input._input_type) {
|
||||||
.text, .email, .tel, .url, .search, .password, .number => {
|
.text, .email, .tel, .url, .search, .password, .number => {
|
||||||
@@ -305,8 +305,8 @@ pub const Writer = struct {
|
|||||||
try self.writeAXProperty(.{ .name = .settable, .value = .{ .booleanOrUndefined = true } }, w);
|
try self.writeAXProperty(.{ .name = .settable, .value = .{ .booleanOrUndefined = true } }, w);
|
||||||
}
|
}
|
||||||
try self.writeAXProperty(.{ .name = .multiline, .value = .{ .boolean = false } }, w);
|
try self.writeAXProperty(.{ .name = .multiline, .value = .{ .boolean = false } }, w);
|
||||||
try self.writeAXProperty(.{ .name = .readonly, .value = .{ .boolean = el.hasAttributeSafe("readonly") } }, w);
|
try self.writeAXProperty(.{ .name = .readonly, .value = .{ .boolean = el.hasAttributeSafe(comptime .literal("readonly")) } }, w);
|
||||||
try self.writeAXProperty(.{ .name = .required, .value = .{ .boolean = el.hasAttributeSafe("required") } }, w);
|
try self.writeAXProperty(.{ .name = .required, .value = .{ .boolean = el.hasAttributeSafe(comptime .literal("required")) } }, w);
|
||||||
},
|
},
|
||||||
.button, .submit, .reset, .image => {
|
.button, .submit, .reset, .image => {
|
||||||
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
||||||
@@ -319,14 +319,14 @@ pub const Writer = struct {
|
|||||||
if (!is_disabled) {
|
if (!is_disabled) {
|
||||||
try self.writeAXProperty(.{ .name = .focusable, .value = .{ .booleanOrUndefined = true } }, w);
|
try self.writeAXProperty(.{ .name = .focusable, .value = .{ .booleanOrUndefined = true } }, w);
|
||||||
}
|
}
|
||||||
const is_checked = el.hasAttributeSafe("checked");
|
const is_checked = el.hasAttributeSafe(comptime .literal("checked"));
|
||||||
try self.writeAXProperty(.{ .name = .checked, .value = .{ .token = if (is_checked) "true" else "false" } }, w);
|
try self.writeAXProperty(.{ .name = .checked, .value = .{ .token = if (is_checked) "true" else "false" } }, w);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.textarea => {
|
.textarea => {
|
||||||
const is_disabled = el.hasAttributeSafe("disabled");
|
const is_disabled = el.hasAttributeSafe(comptime .literal("disabled"));
|
||||||
|
|
||||||
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
||||||
if (!is_disabled) {
|
if (!is_disabled) {
|
||||||
@@ -337,11 +337,11 @@ pub const Writer = struct {
|
|||||||
try self.writeAXProperty(.{ .name = .settable, .value = .{ .booleanOrUndefined = true } }, w);
|
try self.writeAXProperty(.{ .name = .settable, .value = .{ .booleanOrUndefined = true } }, w);
|
||||||
}
|
}
|
||||||
try self.writeAXProperty(.{ .name = .multiline, .value = .{ .boolean = true } }, w);
|
try self.writeAXProperty(.{ .name = .multiline, .value = .{ .boolean = true } }, w);
|
||||||
try self.writeAXProperty(.{ .name = .readonly, .value = .{ .boolean = el.hasAttributeSafe("readonly") } }, w);
|
try self.writeAXProperty(.{ .name = .readonly, .value = .{ .boolean = el.hasAttributeSafe(comptime .literal("readonly")) } }, w);
|
||||||
try self.writeAXProperty(.{ .name = .required, .value = .{ .boolean = el.hasAttributeSafe("required") } }, w);
|
try self.writeAXProperty(.{ .name = .required, .value = .{ .boolean = el.hasAttributeSafe(comptime .literal("required")) } }, w);
|
||||||
},
|
},
|
||||||
.select => {
|
.select => {
|
||||||
const is_disabled = el.hasAttributeSafe("disabled");
|
const is_disabled = el.hasAttributeSafe(comptime .literal("disabled"));
|
||||||
|
|
||||||
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
||||||
if (!is_disabled) {
|
if (!is_disabled) {
|
||||||
@@ -385,7 +385,7 @@ pub const Writer = struct {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.button => {
|
.button => {
|
||||||
const is_disabled = el.hasAttributeSafe("disabled");
|
const is_disabled = el.hasAttributeSafe(comptime .literal("disabled"));
|
||||||
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
try self.writeAXProperty(.{ .name = .invalid, .value = .{ .token = "false" } }, w);
|
||||||
if (!is_disabled) {
|
if (!is_disabled) {
|
||||||
try self.writeAXProperty(.{ .name = .focusable, .value = .{ .booleanOrUndefined = true } }, w);
|
try self.writeAXProperty(.{ .name = .focusable, .value = .{ .booleanOrUndefined = true } }, w);
|
||||||
@@ -629,10 +629,10 @@ pub const AXRole = enum(u8) {
|
|||||||
},
|
},
|
||||||
.textarea => .textbox,
|
.textarea => .textbox,
|
||||||
.select => {
|
.select => {
|
||||||
if (el.getAttributeSafe("multiple") != null) {
|
if (el.getAttributeSafe(comptime .literal("multiple")) != null) {
|
||||||
return .listbox;
|
return .listbox;
|
||||||
}
|
}
|
||||||
if (el.getAttributeSafe("size")) |size| {
|
if (el.getAttributeSafe(comptime .literal("size"))) |size| {
|
||||||
if (!std.ascii.eqlIgnoreCase(size, "1")) {
|
if (!std.ascii.eqlIgnoreCase(size, "1")) {
|
||||||
return .listbox;
|
return .listbox;
|
||||||
}
|
}
|
||||||
@@ -649,7 +649,7 @@ pub const AXRole = enum(u8) {
|
|||||||
|
|
||||||
// Interactive Elements
|
// Interactive Elements
|
||||||
.anchor, .area => {
|
.anchor, .area => {
|
||||||
if (el.getAttributeSafe("href") == null) {
|
if (el.getAttributeSafe(comptime .literal("href")) == null) {
|
||||||
return .none;
|
return .none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ pub const AXRole = enum(u8) {
|
|||||||
.thead, .tbody, .tfoot => .rowgroup,
|
.thead, .tbody, .tfoot => .rowgroup,
|
||||||
.tr => .row,
|
.tr => .row,
|
||||||
.th => {
|
.th => {
|
||||||
if (el.getAttributeSafe("scope")) |scope| {
|
if (el.getAttributeSafe(comptime .literal("scope"))) |scope| {
|
||||||
if (std.ascii.eqlIgnoreCase(scope, "row")) {
|
if (std.ascii.eqlIgnoreCase(scope, "row")) {
|
||||||
return .rowheader;
|
return .rowheader;
|
||||||
}
|
}
|
||||||
@@ -722,7 +722,7 @@ pub fn fromNode(dom: *DOMNode) AXNode {
|
|||||||
break :blk null;
|
break :blk null;
|
||||||
}
|
}
|
||||||
const elt = dom.as(DOMNode.Element);
|
const elt = dom.as(DOMNode.Element);
|
||||||
break :blk elt.getAttributeSafe("role");
|
break :blk elt.getAttributeSafe(comptime .literal("role"));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -759,7 +759,7 @@ fn writeName(axnode: AXNode, w: anytype, page: *Page) !?AXSource {
|
|||||||
},
|
},
|
||||||
.element => |el| {
|
.element => |el| {
|
||||||
// Handle aria-labelledby attribute (highest priority)
|
// Handle aria-labelledby attribute (highest priority)
|
||||||
if (el.getAttributeSafe("aria-labelledby")) |labelledby| {
|
if (el.getAttributeSafe(.literal("aria-labelledby"))) |labelledby| {
|
||||||
// Get the document to look up elements by ID
|
// Get the document to look up elements by ID
|
||||||
const doc = node.ownerDocument(page) orelse return null;
|
const doc = node.ownerDocument(page) orelse return null;
|
||||||
|
|
||||||
@@ -786,12 +786,12 @@ fn writeName(axnode: AXNode, w: anytype, page: *Page) !?AXSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.getAttributeSafe("aria-label")) |aria_label| {
|
if (el.getAttributeSafe(comptime .literal("aria-label"))) |aria_label| {
|
||||||
try w.write(aria_label);
|
try w.write(aria_label);
|
||||||
return .aria_label;
|
return .aria_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.getAttributeSafe("alt")) |alt| {
|
if (el.getAttributeSafe(comptime .literal("alt"))) |alt| {
|
||||||
try w.write(alt);
|
try w.write(alt);
|
||||||
return .alt;
|
return .alt;
|
||||||
}
|
}
|
||||||
@@ -836,12 +836,12 @@ fn writeName(axnode: AXNode, w: anytype, page: *Page) !?AXSource {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.getAttributeSafe("title")) |title| {
|
if (el.getAttributeSafe(comptime .literal("title"))) |title| {
|
||||||
try w.write(title);
|
try w.write(title);
|
||||||
return .title;
|
return .title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.getAttributeSafe("placeholder")) |placeholder| {
|
if (el.getAttributeSafe(comptime .literal("placeholder"))) |placeholder| {
|
||||||
try w.write(placeholder);
|
try w.write(placeholder);
|
||||||
return .placeholder;
|
return .placeholder;
|
||||||
}
|
}
|
||||||
@@ -857,17 +857,17 @@ fn writeName(axnode: AXNode, w: anytype, page: *Page) !?AXSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn isHidden(elt: *DOMNode.Element) bool {
|
fn isHidden(elt: *DOMNode.Element) bool {
|
||||||
if (elt.getAttributeSafe("aria-hidden")) |value| {
|
if (elt.getAttributeSafe(comptime .literal("aria-hidden"))) |value| {
|
||||||
if (std.mem.eql(u8, value, "true")) {
|
if (std.mem.eql(u8, value, "true")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elt.hasAttributeSafe("hidden")) {
|
if (elt.hasAttributeSafe(comptime .literal("hidden"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elt.hasAttributeSafe("inert")) {
|
if (elt.hasAttributeSafe(comptime .literal("inert"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,7 +940,7 @@ fn isIgnore(self: AXNode, page: *Page) bool {
|
|||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
.img => {
|
.img => {
|
||||||
// Check for empty decorative images
|
// Check for empty decorative images
|
||||||
const alt_ = elt.getAttributeSafe("alt");
|
const alt_ = elt.getAttributeSafe(comptime .literal("alt"));
|
||||||
if (alt_ == null or alt_.?.len == 0) {
|
if (alt_ == null or alt_.?.len == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -967,9 +967,9 @@ fn isIgnore(self: AXNode, page: *Page) bool {
|
|||||||
|
|
||||||
// Generic containers with no semantic value
|
// Generic containers with no semantic value
|
||||||
if (tag == .div or tag == .span) {
|
if (tag == .div or tag == .span) {
|
||||||
const has_role = elt.hasAttributeSafe("role");
|
const has_role = elt.hasAttributeSafe(comptime .literal("role"));
|
||||||
const has_aria_label = elt.hasAttributeSafe("aria-label");
|
const has_aria_label = elt.hasAttributeSafe(comptime .literal("aria-label"));
|
||||||
const has_aria_labelledby = elt.hasAttributeSafe("aria-labelledby");
|
const has_aria_labelledby = elt.hasAttributeSafe(.literal("aria-labelledby"));
|
||||||
|
|
||||||
if (!has_role and !has_aria_label and !has_aria_labelledby) {
|
if (!has_role and !has_aria_label and !has_aria_labelledby) {
|
||||||
// Check if it has any non-ignored children
|
// Check if it has any non-ignored children
|
||||||
|
|||||||
@@ -34,6 +34,44 @@ pub const String = packed struct {
|
|||||||
pub const empty = String{ .len = 0, .payload = .{ .content = @splat(0) } };
|
pub const empty = String{ .len = 0, .payload = .{ .content = @splat(0) } };
|
||||||
pub const deleted = String{ .len = tombstone, .payload = .{ .content = @splat(0) } };
|
pub const deleted = String{ .len = tombstone, .payload = .{ .content = @splat(0) } };
|
||||||
|
|
||||||
|
// Create a String from a string literal. For strings with len <= 12, the
|
||||||
|
// this can be done at comptime: comptime String.literal("id");
|
||||||
|
// For strings with len > 12, this must be done at runtime. This is because,
|
||||||
|
// at comptime, we do not have a ptr for data and thus can't store it.
|
||||||
|
pub fn literal(input: anytype) String {
|
||||||
|
if (@inComptime()) {
|
||||||
|
const l = input.len;
|
||||||
|
if (l > 12) {
|
||||||
|
@compileError("Comptime string must be <= 12 bytes (SSO only): " ++ input);
|
||||||
|
}
|
||||||
|
|
||||||
|
var content: [12]u8 = @splat(0);
|
||||||
|
@memcpy(content[0..l], input);
|
||||||
|
return .{ .len = @intCast(l), .payload = .{ .content = content } };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime path - handle both String and []const u8
|
||||||
|
if (@TypeOf(input) == String) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
const l = input.len;
|
||||||
|
|
||||||
|
if (l <= 12) {
|
||||||
|
var content: [12]u8 = @splat(0);
|
||||||
|
@memcpy(content[0..l], input);
|
||||||
|
return .{ .len = @intCast(l), .payload = .{ .content = content } };
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.len = @intCast(l),
|
||||||
|
.payload = .{ .heap = .{
|
||||||
|
.prefix = input[0..4].*,
|
||||||
|
.ptr = input.ptr,
|
||||||
|
} },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub const InitOpts = struct {
|
pub const InitOpts = struct {
|
||||||
dupe: bool = true,
|
dupe: bool = true,
|
||||||
};
|
};
|
||||||
@@ -47,13 +85,11 @@ pub const String = packed struct {
|
|||||||
@memcpy(content[0..l], input);
|
@memcpy(content[0..l], input);
|
||||||
return .{ .len = @intCast(l), .payload = .{ .content = content } };
|
return .{ .len = @intCast(l), .payload = .{ .content = content } };
|
||||||
}
|
}
|
||||||
var prefix: [4]u8 = @splat(0);
|
|
||||||
@memcpy(&prefix, input[0..4]);
|
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.len = @intCast(l),
|
.len = @intCast(l),
|
||||||
.payload = .{ .heap = .{
|
.payload = .{ .heap = .{
|
||||||
.prefix = prefix,
|
.prefix = input[0..4].*,
|
||||||
.ptr = (intern(input) orelse (if (opts.dupe) (try allocator.dupe(u8, input)) else input)).ptr,
|
.ptr = (intern(input) orelse (if (opts.dupe) (try allocator.dupe(u8, input)) else input)).ptr,
|
||||||
} },
|
} },
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user