mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-30 07:31:47 +00:00
dom: document first element can be null
This commit is contained in:
@@ -34,9 +34,10 @@ pub const Document = struct {
|
||||
return DOMImplementation{};
|
||||
}
|
||||
|
||||
pub fn get_documentElement(self: *parser.Document) !ElementUnion {
|
||||
pub fn get_documentElement(self: *parser.Document) !?ElementUnion {
|
||||
const e = try parser.documentGetDocumentElement(self);
|
||||
return try Element.toInterface(e);
|
||||
if (e == null) return null;
|
||||
return try Element.toInterface(e.?);
|
||||
}
|
||||
|
||||
pub fn get_documentURI(self: *parser.Document) ![]const u8 {
|
||||
@@ -105,13 +106,12 @@ pub const Document = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
tag_name: []const u8,
|
||||
) !collection.HTMLCollection {
|
||||
const root = try parser.documentGetDocumentElement(self);
|
||||
return try collection.HTMLCollectionByTagName(
|
||||
alloc,
|
||||
parser.elementToNode(root),
|
||||
tag_name,
|
||||
true,
|
||||
);
|
||||
var elt: ?*parser.Node = null;
|
||||
if (try parser.documentGetDocumentElement(self)) |root| {
|
||||
elt = parser.elementToNode(root);
|
||||
}
|
||||
|
||||
return try collection.HTMLCollectionByTagName(alloc, elt, tag_name, true);
|
||||
}
|
||||
|
||||
pub fn _getElementsByClassName(
|
||||
@@ -119,13 +119,12 @@ pub const Document = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
classNames: []const u8,
|
||||
) !collection.HTMLCollection {
|
||||
const root = try parser.documentGetDocumentElement(self);
|
||||
return try collection.HTMLCollectionByClassName(
|
||||
alloc,
|
||||
parser.elementToNode(root),
|
||||
classNames,
|
||||
true,
|
||||
);
|
||||
var elt: ?*parser.Node = null;
|
||||
if (try parser.documentGetDocumentElement(self)) |root| {
|
||||
elt = parser.elementToNode(root);
|
||||
}
|
||||
|
||||
return try collection.HTMLCollectionByClassName(alloc, elt, classNames, true);
|
||||
}
|
||||
|
||||
pub fn _createDocumentFragment(self: *parser.Document) !*parser.DocumentFragment {
|
||||
@@ -169,8 +168,11 @@ pub const Document = struct {
|
||||
// ParentNode
|
||||
// https://dom.spec.whatwg.org/#parentnode
|
||||
pub fn get_children(self: *parser.Document) !collection.HTMLCollection {
|
||||
const root = try parser.documentGetDocumentElement(self);
|
||||
return try collection.HTMLCollectionChildren(parser.elementToNode(root), true);
|
||||
var elt: ?*parser.Node = null;
|
||||
if (try parser.documentGetDocumentElement(self)) |root| {
|
||||
elt = parser.elementToNode(root);
|
||||
}
|
||||
return try collection.HTMLCollectionChildren(elt, true);
|
||||
}
|
||||
|
||||
pub fn deinit(_: *parser.Document, _: std.mem.Allocator) void {}
|
||||
@@ -188,6 +190,12 @@ pub fn testExecFn(
|
||||
.{ .src = "document.__proto__.__proto__.constructor.name", .ex = "Document" },
|
||||
.{ .src = "document.__proto__.__proto__.__proto__.constructor.name", .ex = "Node" },
|
||||
.{ .src = "document.__proto__.__proto__.__proto__.__proto__.constructor.name", .ex = "EventTarget" },
|
||||
|
||||
.{ .src = "let newdoc = new Document()", .ex = "undefined" },
|
||||
.{ .src = "newdoc.documentElement", .ex = "null" },
|
||||
.{ .src = "newdoc.children.length", .ex = "0" },
|
||||
.{ .src = "newdoc.getElementsByTagName('*').length", .ex = "0" },
|
||||
.{ .src = "newdoc.getElementsByTagName('*').item(0)", .ex = "null" },
|
||||
};
|
||||
try checkCases(js_env, &constructor);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ pub const MatchByTagName = struct {
|
||||
|
||||
pub fn HTMLCollectionByTagName(
|
||||
alloc: std.mem.Allocator,
|
||||
root: *parser.Node,
|
||||
root: ?*parser.Node,
|
||||
tag_name: []const u8,
|
||||
include_root: bool,
|
||||
) !HTMLCollection {
|
||||
@@ -101,7 +101,7 @@ pub const MatchByClassName = struct {
|
||||
|
||||
pub fn HTMLCollectionByClassName(
|
||||
alloc: std.mem.Allocator,
|
||||
root: *parser.Node,
|
||||
root: ?*parser.Node,
|
||||
classNames: []const u8,
|
||||
include_root: bool,
|
||||
) !HTMLCollection {
|
||||
@@ -116,7 +116,7 @@ pub fn HTMLCollectionByClassName(
|
||||
}
|
||||
|
||||
pub fn HTMLCollectionChildren(
|
||||
root: *parser.Node,
|
||||
root: ?*parser.Node,
|
||||
include_root: bool,
|
||||
) !HTMLCollection {
|
||||
return HTMLCollection{
|
||||
@@ -219,7 +219,7 @@ pub const HTMLCollection = struct {
|
||||
matcher: Matcher,
|
||||
walker: Walker,
|
||||
|
||||
root: *parser.Node,
|
||||
root: ?*parser.Node,
|
||||
|
||||
// By default the HTMLCollection walk on the root's descendant only.
|
||||
// But on somes cases, like for dom document, we want to walk over the root
|
||||
@@ -232,17 +232,21 @@ pub const HTMLCollection = struct {
|
||||
|
||||
// start returns the first node to walk on.
|
||||
fn start(self: HTMLCollection) !?*parser.Node {
|
||||
if (self.root == null) return null;
|
||||
|
||||
if (self.include_root) {
|
||||
return self.root;
|
||||
return self.root.?;
|
||||
}
|
||||
|
||||
return try self.walker.get_next(self.root, null);
|
||||
return try self.walker.get_next(self.root.?, null);
|
||||
}
|
||||
|
||||
/// get_length computes the collection's length dynamically according to
|
||||
/// the current root structure.
|
||||
// TODO: nodes retrieved must be de-referenced.
|
||||
pub fn get_length(self: *HTMLCollection) !u32 {
|
||||
if (self.root == null) return 0;
|
||||
|
||||
var len: u32 = 0;
|
||||
var node = try self.start() orelse return 0;
|
||||
|
||||
@@ -253,13 +257,15 @@ pub const HTMLCollection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
node = try self.walker.get_next(self.root, node) orelse break;
|
||||
node = try self.walker.get_next(self.root.?, node) orelse break;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
pub fn _item(self: *HTMLCollection, index: u32) !?Union {
|
||||
if (self.root == null) return null;
|
||||
|
||||
var i: u32 = 0;
|
||||
var node: *parser.Node = undefined;
|
||||
|
||||
@@ -288,16 +294,15 @@ pub const HTMLCollection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
node = try self.walker.get_next(self.root, node) orelse break;
|
||||
node = try self.walker.get_next(self.root.?, node) orelse break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn _namedItem(self: *HTMLCollection, name: []const u8) !?Union {
|
||||
if (name.len == 0) {
|
||||
return null;
|
||||
}
|
||||
if (self.root == null) return null;
|
||||
if (name.len == 0) return null;
|
||||
|
||||
var node = try self.start() orelse return null;
|
||||
|
||||
@@ -320,7 +325,7 @@ pub const HTMLCollection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
node = try self.walker.get_next(self.root, node) orelse break;
|
||||
node = try self.walker.get_next(self.root.?, node) orelse break;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1150,10 +1150,11 @@ pub inline fn documentGetElementsByTagName(doc: *Document, tagname: []const u8)
|
||||
}
|
||||
|
||||
// documentGetDocumentElement returns the root document element.
|
||||
pub inline fn documentGetDocumentElement(doc: *Document) !*Element {
|
||||
pub inline fn documentGetDocumentElement(doc: *Document) !?*Element {
|
||||
var elem: ?*Element = undefined;
|
||||
const err = documentVtable(doc).dom_document_get_document_element.?(doc, &elem);
|
||||
try DOMErr(err);
|
||||
if (elem == null) return null;
|
||||
return elem.?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user