diff --git a/src/dom/document.zig b/src/dom/document.zig index 8bb4577d..846c2f32 100644 --- a/src/dom/document.zig +++ b/src/dom/document.zig @@ -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,12 +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, - ); + 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( @@ -118,12 +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, - ); + 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 { @@ -164,6 +165,31 @@ pub const Document = struct { return try parser.documentCreateAttributeNS(self, ns, qname); } + // ParentNode + // https://dom.spec.whatwg.org/#parentnode + pub fn get_children(self: *parser.Document) !collection.HTMLCollection { + var elt: ?*parser.Node = null; + if (try parser.documentGetDocumentElement(self)) |root| { + elt = parser.elementToNode(root); + } + return try collection.HTMLCollectionChildren(elt, true); + } + + pub fn get_firstElementChild(self: *parser.Document) !?ElementUnion { + const elt = try parser.documentGetDocumentElement(self) orelse return null; + return try Element.toInterface(elt); + } + + pub fn get_lastElementChild(self: *parser.Document) !?ElementUnion { + const elt = try parser.documentGetDocumentElement(self) orelse return null; + return try Element.toInterface(elt); + } + + pub fn get_childElementCount(self: *parser.Document) !u32 { + _ = try parser.documentGetDocumentElement(self) orelse return 0; + return 1; + } + pub fn deinit(_: *parser.Document, _: std.mem.Allocator) void {} }; @@ -179,6 +205,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); @@ -306,6 +338,22 @@ pub fn testExecFn( }; try checkCases(js_env, &createAttr); + var parentNode = [_]Case{ + .{ .src = "document.children.length", .ex = "1" }, + .{ .src = "document.children.item(0).nodeName", .ex = "HTML" }, + .{ .src = "document.firstElementChild.nodeName", .ex = "HTML" }, + .{ .src = "document.lastElementChild.nodeName", .ex = "HTML" }, + .{ .src = "document.childElementCount", .ex = "1" }, + + .{ .src = "let nd = new Document()", .ex = "undefined" }, + .{ .src = "nd.children.length", .ex = "0" }, + .{ .src = "nd.children.item(0)", .ex = "null" }, + .{ .src = "nd.firstElementChild", .ex = "null" }, + .{ .src = "nd.lastElementChild", .ex = "null" }, + .{ .src = "nd.childElementCount", .ex = "0" }, + }; + try checkCases(js_env, &parentNode); + const tags = comptime parser.Tag.all(); comptime var createElements: [(tags.len) * 2]Case = undefined; inline for (tags, 0..) |tag, i| { diff --git a/src/dom/element.zig b/src/dom/element.zig index aa8bc2f5..1a506681 100644 --- a/src/dom/element.zig +++ b/src/dom/element.zig @@ -6,6 +6,8 @@ const jsruntime = @import("jsruntime"); const Case = jsruntime.test_utils.Case; const checkCases = jsruntime.test_utils.checkCases; +const collection = @import("html_collection.zig"); + const Node = @import("node.zig").Node; const HTMLElem = @import("../html/elements.zig"); pub const Union = @import("../html/elements.zig").Union; @@ -122,6 +124,60 @@ pub const Element = struct { // Return true. return true; } + + pub fn _getElementsByTagName( + self: *parser.Element, + alloc: std.mem.Allocator, + tag_name: []const u8, + ) !collection.HTMLCollection { + return try collection.HTMLCollectionByTagName( + alloc, + parser.elementToNode(self), + tag_name, + false, + ); + } + + pub fn _getElementsByClassName( + self: *parser.Element, + alloc: std.mem.Allocator, + classNames: []const u8, + ) !collection.HTMLCollection { + return try collection.HTMLCollectionByClassName( + alloc, + parser.elementToNode(self), + classNames, + false, + ); + } + + // ParentNode + // https://dom.spec.whatwg.org/#parentnode + pub fn get_children(self: *parser.Element) !collection.HTMLCollection { + return try collection.HTMLCollectionChildren(parser.elementToNode(self), false); + } + + pub fn get_firstElementChild(self: *parser.Element) !?Union { + var children = try get_children(self); + return try children._item(0); + } + + pub fn get_lastElementChild(self: *parser.Element) !?Union { + // TODO we could check the last child node first, if it's an element, + // we can return it directly instead of looping twice over the + // children. + var children = try get_children(self); + const ln = try children.get_length(); + if (ln == 0) return null; + return try children._item(ln - 1); + } + + pub fn get_childElementCount(self: *parser.Element) !u32 { + var children = try get_children(self); + return try children.get_length(); + } + + pub fn deinit(_: *parser.Element, _: std.mem.Allocator) void {} }; // Tests @@ -192,4 +248,13 @@ pub fn testExecFn( .{ .src = "b.hasAttribute('foo')", .ex = "false" }, }; try checkCases(js_env, &toggleAttr); + + var parentNode = [_]Case{ + .{ .src = "let c = document.getElementById('content')", .ex = "undefined" }, + .{ .src = "c.children.length", .ex = "3" }, + .{ .src = "c.firstElementChild.nodeName", .ex = "A" }, + .{ .src = "c.lastElementChild.nodeName", .ex = "P" }, + .{ .src = "c.childElementCount", .ex = "3" }, + }; + try checkCases(js_env, &parentNode); } diff --git a/src/dom/html_collection.zig b/src/dom/html_collection.zig index ec32d2a2..da4bf2f6 100644 --- a/src/dom/html_collection.zig +++ b/src/dom/html_collection.zig @@ -14,16 +14,21 @@ const Union = @import("element.zig").Union; const Matcher = union(enum) { matchByTagName: MatchByTagName, matchByClassName: MatchByClassName, + matchTrue: struct {}, pub fn match(self: Matcher, node: *parser.Node) !bool { switch (self) { - inline else => |case| return case.match(node), + inline .matchTrue => return true, + inline .matchByTagName => |case| return case.match(node), + inline .matchByClassName => |case| return case.match(node), } } pub fn deinit(self: Matcher, alloc: std.mem.Allocator) void { switch (self) { - inline else => |case| return case.deinit(alloc), + inline .matchTrue => return, + inline .matchByTagName => |case| return case.deinit(alloc), + inline .matchByClassName => |case| return case.deinit(alloc), } } }; @@ -54,14 +59,17 @@ 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 { return HTMLCollection{ .root = root, + .walker = Walker{ .walkerDepthFirst = .{} }, .matcher = Matcher{ .matchByTagName = try MatchByTagName.init(alloc, tag_name), }, + .include_root = include_root, }; } @@ -95,17 +103,108 @@ pub const MatchByClassName = struct { pub fn HTMLCollectionByClassName( alloc: std.mem.Allocator, - root: *parser.Node, + root: ?*parser.Node, classNames: []const u8, + include_root: bool, ) !HTMLCollection { return HTMLCollection{ .root = root, + .walker = Walker{ .walkerDepthFirst = .{} }, .matcher = Matcher{ .matchByClassName = try MatchByClassName.init(alloc, classNames), }, + .include_root = include_root, }; } +pub fn HTMLCollectionChildren( + root: ?*parser.Node, + include_root: bool, +) !HTMLCollection { + return HTMLCollection{ + .root = root, + .walker = Walker{ .walkerChildren = .{} }, + .matcher = Matcher{ .matchTrue = .{} }, + .include_root = include_root, + }; +} + +const Walker = union(enum) { + walkerDepthFirst: WalkerDepthFirst, + walkerChildren: WalkerChildren, + + pub fn get_next(self: Walker, root: *parser.Node, cur: ?*parser.Node) !?*parser.Node { + switch (self) { + inline else => |case| return case.get_next(root, cur), + } + } +}; + +// WalkerDepthFirst iterates over the DOM tree to return the next following +// node or null at the end. +// +// This implementation is a zig version of Netsurf code. +// http://source.netsurf-browser.org/libdom.git/tree/src/html/html_collection.c#n177 +// +// The iteration is a depth first as required by the specification. +// https://dom.spec.whatwg.org/#htmlcollection +// https://dom.spec.whatwg.org/#concept-tree-order +pub const WalkerDepthFirst = struct { + pub fn get_next(_: WalkerDepthFirst, root: *parser.Node, cur: ?*parser.Node) !?*parser.Node { + var n = cur orelse root; + + // TODO deinit next + if (try parser.nodeFirstChild(n)) |next| { + return next; + } + + // TODO deinit next + if (try parser.nodeNextSibling(n)) |next| { + return next; + } + + // TODO deinit parent + // Back to the parent of cur. + // If cur has no parent, then the iteration is over. + var parent = try parser.nodeParentNode(n) orelse return null; + + // TODO deinit lastchild + var lastchild = try parser.nodeLastChild(parent); + while (n != root and n == lastchild) { + n = parent; + + // TODO deinit parent + // Back to the prev's parent. + // If prev has no parent, then the loop must stop. + parent = try parser.nodeParentNode(n) orelse break; + + // TODO deinit lastchild + lastchild = try parser.nodeLastChild(parent); + } + + if (n == root) { + return null; + } + + return try parser.nodeNextSibling(n); + } +}; + +// WalkerChildren iterates over the root's children only. +pub const WalkerChildren = struct { + pub fn get_next(_: WalkerChildren, root: *parser.Node, cur: ?*parser.Node) !?*parser.Node { + // On walk start, we return the first root's child. + if (cur == null) return try parser.nodeFirstChild(root); + + // If cur is root, then return null. + // This is a special case, if the root is included in the walk, we + // don't want to go further to find children. + if (root == cur.?) return null; + + return try parser.nodeNextSibling(cur.?); + } +}; + // WEB IDL https://dom.spec.whatwg.org/#htmlcollection // HTMLCollection is re implemented in zig here because libdom // dom_html_collection expects a comparison function callback as arguement. @@ -114,96 +213,68 @@ pub const HTMLCollection = struct { pub const mem_guarantied = true; 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 + // itself. + include_root: bool = false, // save a state for the collection to improve the _item speed. cur_idx: ?u32 = undefined, cur_node: ?*parser.Node = undefined, - // get_next iterates over the DOM tree to return the next following node or - // null at the end. - // - // This implementation is a zig version of Netsurf code. - // http://source.netsurf-browser.org/libdom.git/tree/src/html/html_collection.c#n177 - // - // The iteration is a depth first as required by the specification. - // https://dom.spec.whatwg.org/#htmlcollection - // https://dom.spec.whatwg.org/#concept-tree-order - fn get_next(root: *parser.Node, cur: *parser.Node) !?*parser.Node { - // TODO deinit next - if (try parser.nodeFirstChild(cur)) |next| { - return next; + // 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.?; } - // TODO deinit next - if (try parser.nodeNextSibling(cur)) |next| { - return next; - } - - // TODO deinit parent - // Back to the parent of cur. - // If cur has no parent, then the iteration is over. - var parent = try parser.nodeParentNode(cur) orelse return null; - - // TODO deinit lastchild - var lastchild = try parser.nodeLastChild(parent); - var prev = cur; - while (prev != root and prev == lastchild) { - prev = parent; - - // TODO deinit parent - // Back to the prev's parent. - // If prev has no parent, then the loop must stop. - parent = try parser.nodeParentNode(prev) orelse break; - - // TODO deinit lastchild - lastchild = try parser.nodeLastChild(parent); - } - - if (prev == root) { - return null; - } - - return try parser.nodeNextSibling(prev); + 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: *parser.Node = self.root; - var ntype: parser.NodeType = undefined; + var node = try self.start() orelse return 0; while (true) { - ntype = try parser.nodeType(node); - if (ntype == .element) { + if (try parser.nodeType(node) == .element) { if (try self.matcher.match(node)) { len += 1; } } - node = try 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 = self.root; - var ntype: parser.NodeType = undefined; + var node: *parser.Node = undefined; // Use the current state to improve speed if possible. if (self.cur_idx != null and index >= self.cur_idx.?) { i = self.cur_idx.?; node = self.cur_node.?; + } else { + node = try self.start() orelse return null; } while (true) { - ntype = try parser.nodeType(node); - if (ntype == .element) { + if (try parser.nodeType(node) == .element) { if (try self.matcher.match(node)) { // check if we found the searched element. if (i == index) { @@ -219,23 +290,20 @@ pub const HTMLCollection = struct { } } - node = try 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: *parser.Node = self.root; - var ntype: parser.NodeType = undefined; + var node = try self.start() orelse return null; while (true) { - ntype = try parser.nodeType(node); - if (ntype == .element) { + if (try parser.nodeType(node) == .element) { if (try self.matcher.match(node)) { const elem = @as(*parser.Element, @ptrCast(node)); @@ -253,7 +321,7 @@ pub const HTMLCollection = struct { } } - node = try get_next(self.root, node) orelse break; + node = try self.walker.get_next(self.root.?, node) orelse break; } return null; @@ -290,6 +358,13 @@ pub fn testExecFn( .{ .src = "getElementsByTagNameAll.item(7).localName", .ex = "p" }, .{ .src = "getElementsByTagNameAll.namedItem('para-empty-child').localName", .ex = "span" }, + .{ .src = "document.getElementById('content').getElementsByTagName('*').length", .ex = "4" }, + .{ .src = "document.getElementById('content').getElementsByTagName('p').length", .ex = "2" }, + .{ .src = "document.getElementById('content').getElementsByTagName('div').length", .ex = "0" }, + + .{ .src = "document.children.length", .ex = "1" }, + .{ .src = "document.getElementById('content').children.length", .ex = "3" }, + // check liveness .{ .src = "let content = document.getElementById('content')", .ex = "undefined" }, .{ .src = "let pe = document.getElementById('para-empty')", .ex = "undefined" }, diff --git a/src/netsurf.zig b/src/netsurf.zig index 3f8336ff..2455b35a 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -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.?; } diff --git a/tests/wpt/dom/Document-getElementsByClassName.html b/tests/wpt/dom/nodes/Document-getElementsByClassName.html similarity index 100% rename from tests/wpt/dom/Document-getElementsByClassName.html rename to tests/wpt/dom/nodes/Document-getElementsByClassName.html diff --git a/tests/wpt/dom/nodes/Element-childElement-null-svg.svg b/tests/wpt/dom/nodes/Element-childElement-null-svg.svg new file mode 100644 index 00000000..38848287 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElement-null-svg.svg @@ -0,0 +1,20 @@ + + +Null test + + + +Test of firstElementChild and lastChildElement returning null +Test + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_equals(parentEl.firstElementChild, null) + assert_equals(parentEl.lastElementChild, null) +}) + + diff --git a/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml new file mode 100644 index 00000000..daedab6d --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml @@ -0,0 +1,20 @@ + + + +Null Test + + + + +

Test of firstElementChild and lastChildElement returning null

+
+

Test.

+ + + diff --git a/tests/wpt/dom/nodes/Element-childElement-null.html b/tests/wpt/dom/nodes/Element-childElement-null.html new file mode 100644 index 00000000..1863a41d --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElement-null.html @@ -0,0 +1,15 @@ + + +Null test + + +

Test of firstElementChild and lastChildElement returning null

+
+

Test.

+ diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg new file mode 100644 index 00000000..d149f1ea --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg @@ -0,0 +1,22 @@ + + +Dynamic Adding of Elements + + + +Test of Dynamic Adding of Elements +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var newChild = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + parentEl.appendChild(newChild); + assert_equals(parentEl.childElementCount, 2) +}) + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml new file mode 100644 index 00000000..c97ed196 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +Dynamic Adding of Elements + + + + +

Test of Dynamic Adding of Elements

+
+

The result of this test is +logged above.

+ + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html new file mode 100644 index 00000000..3e7490b2 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html @@ -0,0 +1,17 @@ + + +Dynamic Adding of Elements + + +

Test of Dynamic Adding of Elements

+
+

The result of this test is +logged above.

+ diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg new file mode 100644 index 00000000..bf99de65 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg @@ -0,0 +1,22 @@ + + +Dynamic Removal of Elements + + + +Test of Dynamic Removal of Elements +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var lec = parentEl.lastElementChild; + parentEl.removeChild(lec); + assert_equals(parentEl.childElementCount, 1) +}) + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml new file mode 100644 index 00000000..f0009b0a --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +Dynamic Removal of Elements + + + + +

Test of Removal Adding of Elements

+
+

The result of this test is +logged above.

+ + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html new file mode 100644 index 00000000..3f7e7c7e --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html @@ -0,0 +1,17 @@ + + +Dynamic Removal of Elements + + +

Test of Dynamic Removal of Elements

+
+

The result of this test is +unknown.

+ diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg new file mode 100644 index 00000000..8ba57436 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg @@ -0,0 +1,19 @@ + + +childElementCount + + + +Test of childElementCount with No Child Element Nodes +Test + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_equals(parentEl.childElementCount, 0) +}) + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml new file mode 100644 index 00000000..f567a20c --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml @@ -0,0 +1,19 @@ + + + +childElementCount without Child Element Nodes + + + + +

Test of childElementCount with No Child Element Nodes

+
+

Test.

+ + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild.html b/tests/wpt/dom/nodes/Element-childElementCount-nochild.html new file mode 100644 index 00000000..fb52fb20 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-nochild.html @@ -0,0 +1,14 @@ + + +childElementCount without Child Element Nodes + + +

Test of childElementCount with No Child Element Nodes

+
+

Test.

+ diff --git a/tests/wpt/dom/nodes/Element-childElementCount-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-svg.svg new file mode 100644 index 00000000..ff93eff6 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-svg.svg @@ -0,0 +1,25 @@ + + +childElementCount + + + +Test of childElementCount +The result of this test is +unknown. + + + + + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_true("childElementCount" in parentEl) + assert_equals(parentEl.childElementCount, 3) +}) + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml new file mode 100644 index 00000000..6b719ff7 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml @@ -0,0 +1,25 @@ + + + +childElementCount + + + + +

Test of childElementCount

+
+

The result of this test is +unknown. + + + +

+ + + diff --git a/tests/wpt/dom/nodes/Element-childElementCount.html b/tests/wpt/dom/nodes/Element-childElementCount.html new file mode 100644 index 00000000..8cfe567f --- /dev/null +++ b/tests/wpt/dom/nodes/Element-childElementCount.html @@ -0,0 +1,20 @@ + + +childElementCount + + +

Test of childElementCount

+
+

The result of this test is +given above. + + + +

+ diff --git a/tests/wpt/dom/nodes/Element-children.html b/tests/wpt/dom/nodes/Element-children.html new file mode 100644 index 00000000..c0210f96 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-children.html @@ -0,0 +1,58 @@ + +HTMLCollection edge cases + + +
+
+ diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml new file mode 100644 index 00000000..f28005e9 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml @@ -0,0 +1,27 @@ + +unknown."> +]> + + +Entity References + + + + +

Test of Entity References

+
+

The result of this test is &tree;

+ + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg b/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg new file mode 100644 index 00000000..3a20ea79 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg @@ -0,0 +1,26 @@ + +unknown."> +]> + +Entity References + + + +Test of Entity References +The result of this test is &tree; + + +test(function() { + var parentEl = document.getElementById("parentEl") + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") +}) + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg new file mode 100644 index 00000000..d42c0877 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg @@ -0,0 +1,26 @@ + + +firstElementChild with namespaces + + + +Test of firstElementChild with namespaces + + + + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") + assert_equals(fec.localName, "dill") +}) + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml new file mode 100644 index 00000000..29441d27 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml @@ -0,0 +1,28 @@ + + + +firstElementChild with namespaces + + + + +

Test of firstElementChild with namespaces

+
+ +
+
+

The result of this test is +logged above.

+ + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html b/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html new file mode 100644 index 00000000..629deab3 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html @@ -0,0 +1,21 @@ + + +firstElementChild with namespaces + + +

Test of firstElementChild with namespaces

+
+

The result of this test is a unknown.

+ diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg b/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg new file mode 100644 index 00000000..359c5b82 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg @@ -0,0 +1,23 @@ + + +firstElementChild + + + +Test of firstElementChild +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") +}) + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml new file mode 100644 index 00000000..302052b0 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml @@ -0,0 +1,23 @@ + + + +firstElementChild + + + + +

Test of firstElementChild

+
+

The result of this test is +logged above.

+ + + diff --git a/tests/wpt/dom/nodes/Element-firstElementChild.html b/tests/wpt/dom/nodes/Element-firstElementChild.html new file mode 100644 index 00000000..12a0c594 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-firstElementChild.html @@ -0,0 +1,18 @@ + + +firstElementChild + + +

Test of firstElementChild

+
+

The result of this test is +logged above.

+ diff --git a/tests/wpt/dom/nodes/Element-getElementsByClassName.html b/tests/wpt/dom/nodes/Element-getElementsByClassName.html new file mode 100644 index 00000000..bc87b05d --- /dev/null +++ b/tests/wpt/dom/nodes/Element-getElementsByClassName.html @@ -0,0 +1,43 @@ + +Element.getElementsByClassName + + +
+ diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml new file mode 100644 index 00000000..f3f286ea --- /dev/null +++ b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml @@ -0,0 +1 @@ + diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html new file mode 100644 index 00000000..c41ee2e8 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html @@ -0,0 +1,51 @@ + + + + + + + diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName.html b/tests/wpt/dom/nodes/Element-getElementsByTagName.html new file mode 100644 index 00000000..87c4fe93 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-getElementsByTagName.html @@ -0,0 +1,30 @@ + + +Element.getElementsByTagName + + + + +
+ diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html b/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html new file mode 100644 index 00000000..f826afc3 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html @@ -0,0 +1,37 @@ + + +Element.getElementsByTagNameNS + + + + +
+ diff --git a/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg b/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg new file mode 100644 index 00000000..1cec4a13 --- /dev/null +++ b/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg @@ -0,0 +1,22 @@ + + +lastElementChild + + + +Test of lastElementChild +The result of this test is not known. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var lec = parentEl.lastElementChild; + assert_true(!!lec) + assert_equals(lec.nodeType, 1) + assert_equals(lec.getAttribute("id"), "last_element_child") +}) + + diff --git a/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml new file mode 100644 index 00000000..3150b92a --- /dev/null +++ b/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +firstElementChild + + + + +

Test of firstElementChild

+
+

The result of this test is logged above.

+ + + diff --git a/tests/wpt/dom/nodes/Element-lastElementChild.html b/tests/wpt/dom/nodes/Element-lastElementChild.html new file mode 100644 index 00000000..de7aebdf --- /dev/null +++ b/tests/wpt/dom/nodes/Element-lastElementChild.html @@ -0,0 +1,17 @@ + + +lastElementChild + + +

Test of lastElementChild

+
+

The result of this test is logged above.

+ diff --git a/tests/wpt/dom/nodes/ParentNode-children.html b/tests/wpt/dom/nodes/ParentNode-children.html new file mode 100644 index 00000000..6621e7d9 --- /dev/null +++ b/tests/wpt/dom/nodes/ParentNode-children.html @@ -0,0 +1,27 @@ + + +ParentNode.children + + + +
+
+ +
+ +