mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-17 08:48:58 +00:00
5
Makefile
5
Makefile
@@ -46,6 +46,11 @@ shell:
|
|||||||
@printf "\e[36mBuilding shell...\e[0m\n"
|
@printf "\e[36mBuilding shell...\e[0m\n"
|
||||||
@$(ZIG) build shell -Dengine=v8 || (printf "\e[33mBuild ERROR\e[0m\n"; exit 1;)
|
@$(ZIG) build shell -Dengine=v8 || (printf "\e[33mBuild ERROR\e[0m\n"; exit 1;)
|
||||||
|
|
||||||
|
## Run WPT tests
|
||||||
|
wpt:
|
||||||
|
@printf "\e[36mBuilding wpt...\e[0m\n"
|
||||||
|
@$(ZIG) build wpt -Dengine=v8 -- $(filter-out $@,$(MAKECMDGOALS)) || (printf "\e[33mBuild ERROR\e[0m\n"; exit 1;)
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
test:
|
test:
|
||||||
@printf "\e[36mTesting...\e[0m\n"
|
@printf "\e[36mTesting...\e[0m\n"
|
||||||
|
|||||||
23
build.zig
23
build.zig
@@ -72,6 +72,29 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
// step
|
// step
|
||||||
const test_step = b.step("test", "Run unit tests");
|
const test_step = b.step("test", "Run unit tests");
|
||||||
test_step.dependOn(&run_tests.step);
|
test_step.dependOn(&run_tests.step);
|
||||||
|
|
||||||
|
// wpt
|
||||||
|
// -----
|
||||||
|
|
||||||
|
// compile and install
|
||||||
|
const wpt = b.addExecutable(.{
|
||||||
|
.name = "browsercore-wpt",
|
||||||
|
.root_source_file = .{ .path = "src/main_wpt.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = mode,
|
||||||
|
});
|
||||||
|
try common(wpt, options);
|
||||||
|
b.installArtifact(wpt);
|
||||||
|
|
||||||
|
// run
|
||||||
|
const wpt_cmd = b.addRunArtifact(wpt);
|
||||||
|
wpt_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| {
|
||||||
|
wpt_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
// step
|
||||||
|
const wpt_step = b.step("wpt", "WPT tests");
|
||||||
|
wpt_step.dependOn(&wpt_cmd.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common(
|
fn common(
|
||||||
|
|||||||
@@ -2,9 +2,16 @@ const std = @import("std");
|
|||||||
|
|
||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
const Node = @import("node.zig").Node;
|
const jsruntime = @import("jsruntime");
|
||||||
const Element = @import("element.zig").Element;
|
const Case = jsruntime.test_utils.Case;
|
||||||
|
const checkCases = jsruntime.test_utils.checkCases;
|
||||||
|
|
||||||
|
const Node = @import("node.zig").Node;
|
||||||
|
|
||||||
|
const Element = @import("element.zig").Element;
|
||||||
|
const ElementUnion = @import("element.zig").Union;
|
||||||
|
|
||||||
|
// WEB IDL https://dom.spec.whatwg.org/#document
|
||||||
pub const Document = struct {
|
pub const Document = struct {
|
||||||
pub const Self = parser.Document;
|
pub const Self = parser.Document;
|
||||||
pub const prototype = *Node;
|
pub const prototype = *Node;
|
||||||
@@ -15,20 +22,62 @@ pub const Document = struct {
|
|||||||
// return .{};
|
// return .{};
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn getElementById(self: *parser.Document, id: []const u8) ?*parser.Element {
|
|
||||||
return parser.documentGetElementById(self, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
pub fn get_body(_: *parser.Document) ?*parser.Body {
|
pub fn _getElementById(self: *parser.Document, id: []const u8) ?ElementUnion {
|
||||||
// TODO
|
const e = parser.documentGetElementById(self, id) orelse return null;
|
||||||
return null;
|
return Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _getElementById(_: *parser.Document, _: []u8) ?*parser.Element {
|
pub fn _createElement(self: *parser.Document, tag_name: []const u8) ElementUnion {
|
||||||
// TODO
|
const e = parser.documentCreateElement(self, tag_name);
|
||||||
return null;
|
return Element.toInterface(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Tests
|
||||||
|
// -----
|
||||||
|
|
||||||
|
pub fn testExecFn(
|
||||||
|
_: std.mem.Allocator,
|
||||||
|
js_env: *jsruntime.Env,
|
||||||
|
comptime _: []jsruntime.API,
|
||||||
|
) !void {
|
||||||
|
var constructor = [_]Case{
|
||||||
|
.{ .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" },
|
||||||
|
};
|
||||||
|
try checkCases(js_env, &constructor);
|
||||||
|
|
||||||
|
var getElementById = [_]Case{
|
||||||
|
.{ .src = "let getElementById = document.getElementById('content')", .ex = "undefined" },
|
||||||
|
.{ .src = "getElementById.constructor.name", .ex = "HTMLDivElement" },
|
||||||
|
.{ .src = "getElementById.localName", .ex = "div" },
|
||||||
|
};
|
||||||
|
try checkCases(js_env, &getElementById);
|
||||||
|
|
||||||
|
const tags = comptime parser.Tag.all();
|
||||||
|
const elements = comptime parser.Tag.allElements();
|
||||||
|
comptime var createElements: [(tags.len) * 3]Case = undefined;
|
||||||
|
inline for (tags, elements, 0..) |tag, element_name, i| {
|
||||||
|
// if (tag == .undef) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
const tag_name = @tagName(tag);
|
||||||
|
createElements[i * 3] = Case{
|
||||||
|
.src = "var " ++ tag_name ++ "Elem = document.createElement('" ++ tag_name ++ "')",
|
||||||
|
.ex = "undefined",
|
||||||
|
};
|
||||||
|
createElements[(i * 3) + 1] = Case{
|
||||||
|
.src = tag_name ++ "Elem.constructor.name",
|
||||||
|
.ex = "HTML" ++ element_name ++ "Element",
|
||||||
|
};
|
||||||
|
createElements[(i * 3) + 2] = Case{
|
||||||
|
.src = tag_name ++ "Elem.localName",
|
||||||
|
.ex = tag_name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
try checkCases(js_env, &createElements);
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,19 @@ const std = @import("std");
|
|||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
|
|
||||||
const Node = @import("node.zig").Node;
|
const Node = @import("node.zig").Node;
|
||||||
|
const HTMLElem = @import("../html/elements.zig");
|
||||||
|
pub const Union = @import("../html/elements.zig").Union;
|
||||||
|
|
||||||
|
// WEB IDL https://dom.spec.whatwg.org/#element
|
||||||
pub const Element = struct {
|
pub const Element = struct {
|
||||||
pub const Self = parser.Element;
|
pub const Self = parser.Element;
|
||||||
pub const prototype = *Node;
|
pub const prototype = *Node;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
|
pub fn toInterface(e: *parser.Element) Union {
|
||||||
|
return HTMLElem.toInterface(Union, e);
|
||||||
|
}
|
||||||
|
|
||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const checkCases = jsruntime.test_utils.checkCases;
|
|||||||
const Document = @import("../dom/document.zig").Document;
|
const Document = @import("../dom/document.zig").Document;
|
||||||
const HTMLElem = @import("elements.zig");
|
const HTMLElem = @import("elements.zig");
|
||||||
|
|
||||||
|
// WEB IDL https://html.spec.whatwg.org/#the-document-object
|
||||||
pub const HTMLDocument = struct {
|
pub const HTMLDocument = struct {
|
||||||
pub const Self = parser.DocumentHTML;
|
pub const Self = parser.DocumentHTML;
|
||||||
pub const prototype = *Document;
|
pub const prototype = *Document;
|
||||||
@@ -20,21 +21,6 @@ pub const HTMLDocument = struct {
|
|||||||
pub fn get_body(self: *parser.DocumentHTML) ?*parser.Body {
|
pub fn get_body(self: *parser.DocumentHTML) ?*parser.Body {
|
||||||
return parser.documentHTMLBody(self);
|
return parser.documentHTMLBody(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _getElementById(self: *parser.DocumentHTML, id: []u8) ?HTMLElem.Union {
|
|
||||||
const doc = parser.documentHTMLToDocument(self);
|
|
||||||
const elem_dom = parser.documentGetElementById(doc, id);
|
|
||||||
if (elem_dom) |elem| {
|
|
||||||
return HTMLElem.toInterface(HTMLElem.Union, elem);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _createElement(self: *parser.DocumentHTML, tag_name: []const u8) HTMLElem.Union {
|
|
||||||
const doc_dom = parser.documentHTMLToDocument(self);
|
|
||||||
const base = parser.documentCreateElement(doc_dom, tag_name);
|
|
||||||
return HTMLElem.toInterface(HTMLElem.Union, base);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
@@ -48,39 +34,7 @@ pub fn testExecFn(
|
|||||||
var constructor = [_]Case{
|
var constructor = [_]Case{
|
||||||
.{ .src = "document.__proto__.constructor.name", .ex = "HTMLDocument" },
|
.{ .src = "document.__proto__.constructor.name", .ex = "HTMLDocument" },
|
||||||
.{ .src = "document.__proto__.__proto__.constructor.name", .ex = "Document" },
|
.{ .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 = "document.body.localName == 'body'", .ex = "true" },
|
.{ .src = "document.body.localName == 'body'", .ex = "true" },
|
||||||
};
|
};
|
||||||
try checkCases(js_env, &constructor);
|
try checkCases(js_env, &constructor);
|
||||||
|
|
||||||
var getElementById = [_]Case{
|
|
||||||
.{ .src = "let getElementById = document.getElementById('content')", .ex = "undefined" },
|
|
||||||
.{ .src = "getElementById.constructor.name", .ex = "HTMLDivElement" },
|
|
||||||
.{ .src = "getElementById.localName", .ex = "div" },
|
|
||||||
};
|
|
||||||
try checkCases(js_env, &getElementById);
|
|
||||||
|
|
||||||
const tags = comptime parser.Tag.all();
|
|
||||||
const elements = comptime parser.Tag.allElements();
|
|
||||||
comptime var createElements: [(tags.len) * 3]Case = undefined;
|
|
||||||
inline for (tags, elements, 0..) |tag, element_name, i| {
|
|
||||||
// if (tag == .undef) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
const tag_name = @tagName(tag);
|
|
||||||
createElements[i * 3] = Case{
|
|
||||||
.src = "var " ++ tag_name ++ "Elem = document.createElement('" ++ tag_name ++ "')",
|
|
||||||
.ex = "undefined",
|
|
||||||
};
|
|
||||||
createElements[(i * 3) + 1] = Case{
|
|
||||||
.src = tag_name ++ "Elem.constructor.name",
|
|
||||||
.ex = "HTML" ++ element_name ++ "Element",
|
|
||||||
};
|
|
||||||
createElements[(i * 3) + 2] = Case{
|
|
||||||
.src = tag_name ++ "Elem.localName",
|
|
||||||
.ex = tag_name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
try checkCases(js_env, &createElements);
|
|
||||||
}
|
}
|
||||||
|
|||||||
279
src/main_wpt.zig
Normal file
279
src/main_wpt.zig
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const parser = @import("netsurf.zig");
|
||||||
|
const jsruntime = @import("jsruntime");
|
||||||
|
|
||||||
|
const TPL = jsruntime.TPL;
|
||||||
|
const Env = jsruntime.Env;
|
||||||
|
const Loop = jsruntime.Loop;
|
||||||
|
|
||||||
|
const DOM = @import("dom.zig");
|
||||||
|
const HTMLElem = @import("html/elements.zig");
|
||||||
|
|
||||||
|
const wpt_dir = "tests/wpt";
|
||||||
|
|
||||||
|
// generate APIs
|
||||||
|
const apis = jsruntime.compile(DOM.Interfaces);
|
||||||
|
|
||||||
|
// FileLoader loads files content from the filesystem.
|
||||||
|
const FileLoader = struct {
|
||||||
|
const FilesMap = std.StringHashMap([]const u8);
|
||||||
|
|
||||||
|
files: FilesMap,
|
||||||
|
path: []const u8,
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
|
||||||
|
fn init(alloc: std.mem.Allocator, path: []const u8) FileLoader {
|
||||||
|
const files = FilesMap.init(alloc);
|
||||||
|
|
||||||
|
return FileLoader{
|
||||||
|
.path = path,
|
||||||
|
.alloc = alloc,
|
||||||
|
.files = files,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn get(self: *FileLoader, name: []const u8) ![]const u8 {
|
||||||
|
if (!self.files.contains(name)) {
|
||||||
|
try self.load(name);
|
||||||
|
}
|
||||||
|
return self.files.get(name).?;
|
||||||
|
}
|
||||||
|
fn load(self: *FileLoader, name: []const u8) !void {
|
||||||
|
const filename = try std.mem.concat(self.alloc, u8, &.{ self.path, name });
|
||||||
|
defer self.alloc.free(filename);
|
||||||
|
var file = try std.fs.cwd().openFile(filename, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const file_size = try file.getEndPos();
|
||||||
|
const content = try file.readToEndAlloc(self.alloc, file_size);
|
||||||
|
const namedup = try self.alloc.dupe(u8, name);
|
||||||
|
try self.files.put(namedup, content);
|
||||||
|
}
|
||||||
|
fn deinit(self: *FileLoader) void {
|
||||||
|
var iter = self.files.iterator();
|
||||||
|
while (iter.next()) |entry| {
|
||||||
|
self.alloc.free(entry.key_ptr.*);
|
||||||
|
self.alloc.free(entry.value_ptr.*);
|
||||||
|
}
|
||||||
|
self.files.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO For now the WPT tests run is specific to WPT.
|
||||||
|
// It manually load js framwork libs, and run the first script w/ js content in
|
||||||
|
// the HTML page.
|
||||||
|
// Once browsercore will have the html loader, it would be useful to refacto
|
||||||
|
// this test to use it.
|
||||||
|
pub fn main() !void {
|
||||||
|
std.debug.print("Running WPT test suite\n", .{});
|
||||||
|
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
|
||||||
|
const args = try std.process.argsAlloc(alloc);
|
||||||
|
defer std.process.argsFree(alloc, args);
|
||||||
|
|
||||||
|
const filter = args[1..];
|
||||||
|
|
||||||
|
// initialize VM JS lib.
|
||||||
|
const vm = jsruntime.VM.init();
|
||||||
|
defer vm.deinit();
|
||||||
|
|
||||||
|
// prepare libraries to load on each test case.
|
||||||
|
var loader = FileLoader.init(alloc, "tests/wpt");
|
||||||
|
defer loader.deinit();
|
||||||
|
|
||||||
|
// browse the dir to get the tests dynamically.
|
||||||
|
var list = std.ArrayList([]const u8).init(alloc);
|
||||||
|
try findWPTTests(alloc, wpt_dir, &list);
|
||||||
|
defer {
|
||||||
|
for (list.items) |tc| {
|
||||||
|
alloc.free(tc);
|
||||||
|
}
|
||||||
|
list.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
var run: usize = 0;
|
||||||
|
var failures: usize = 0;
|
||||||
|
for (list.items) |tc| {
|
||||||
|
if (filter.len > 0) {
|
||||||
|
var match = false;
|
||||||
|
for (filter) |f| {
|
||||||
|
if (std.mem.startsWith(u8, tc, f)) {
|
||||||
|
match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (std.mem.endsWith(u8, tc, f)) {
|
||||||
|
match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run += 1;
|
||||||
|
|
||||||
|
// create an arena and deinit it for each test case.
|
||||||
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
// TODO I don't use testing.expect here b/c I want to execute all the
|
||||||
|
// tests. And testing.expect stops running test in the first failure.
|
||||||
|
const res = runWPT(&arena, tc, &loader) catch |err| {
|
||||||
|
std.debug.print("FAIL\t{s}\n{any}\n", .{ tc, err });
|
||||||
|
failures += 1;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// no need to call res.deinit() thanks to the arena allocator.
|
||||||
|
|
||||||
|
if (!res.success) {
|
||||||
|
std.debug.print("FAIL\t{s}\n{s}\n", .{ tc, res.stack orelse res.result });
|
||||||
|
failures += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!std.mem.eql(u8, res.result, "Pass")) {
|
||||||
|
std.debug.print("FAIL\t{s}\n{s}\n", .{ tc, res.stack orelse res.result });
|
||||||
|
failures += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print("PASS\t{s}\n", .{tc});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures > 0) {
|
||||||
|
std.debug.print("{d}/{d} tests failures\n", .{ failures, run });
|
||||||
|
std.os.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runWPT parses the given HTML file, starts a js env and run the first script
|
||||||
|
// tags containing javascript sources.
|
||||||
|
// It loads first the js libs files.
|
||||||
|
fn runWPT(arena: *std.heap.ArenaAllocator, f: []const u8, loader: *FileLoader) !jsruntime.JSResult {
|
||||||
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
|
// document
|
||||||
|
const html_doc = try parser.documentHTMLParseFromFileAlloc(alloc, f);
|
||||||
|
const doc = parser.documentHTMLToDocument(html_doc);
|
||||||
|
|
||||||
|
// create JS env
|
||||||
|
var loop = try Loop.init(alloc);
|
||||||
|
defer loop.deinit();
|
||||||
|
var js_env = try Env.init(arena, &loop);
|
||||||
|
defer js_env.deinit();
|
||||||
|
|
||||||
|
// load APIs in JS env
|
||||||
|
var tpls: [apis.len]TPL = undefined;
|
||||||
|
try js_env.load(apis, &tpls);
|
||||||
|
|
||||||
|
// start JS env
|
||||||
|
js_env.start(apis);
|
||||||
|
defer js_env.stop();
|
||||||
|
|
||||||
|
// add document object
|
||||||
|
try js_env.addObject(apis, html_doc, "document");
|
||||||
|
|
||||||
|
// alias global as self and window
|
||||||
|
try js_env.attachObject(try js_env.getGlobal(), "self", null);
|
||||||
|
try js_env.attachObject(try js_env.getGlobal(), "window", null);
|
||||||
|
|
||||||
|
// thanks to the arena, we don't need to deinit res.
|
||||||
|
var res: jsruntime.JSResult = undefined;
|
||||||
|
|
||||||
|
const init =
|
||||||
|
\\window.listeners = [];
|
||||||
|
\\window.document = document;
|
||||||
|
\\window.parent = window;
|
||||||
|
\\window.addEventListener = function (type, listener, options) {
|
||||||
|
\\ window.listeners.push({type: type, listener: listener, options: options});
|
||||||
|
\\};
|
||||||
|
\\window.dispatchEvent = function (event) {
|
||||||
|
\\ len = window.listeners.length;
|
||||||
|
\\ for (var i = 0; i < len; i++) {
|
||||||
|
\\ if (window.listeners[i].type == event.target) {
|
||||||
|
\\ window.listeners[i].listener(event);
|
||||||
|
\\ }
|
||||||
|
\\ }
|
||||||
|
\\ return true;
|
||||||
|
\\};
|
||||||
|
\\window.removeEventListener = function () {};
|
||||||
|
;
|
||||||
|
res = try evalJS(js_env, alloc, init, "init");
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO load <script src> attributes instead of the static list.
|
||||||
|
res = try evalJS(js_env, alloc, try loader.get("/resources/testharness.js"), "testharness.js");
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = try evalJS(js_env, alloc, try loader.get("/resources/testharnessreport.js"), "testharnessreport.js");
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop hover the scripts.
|
||||||
|
const scripts = parser.documentGetElementsByTagName(doc, "script");
|
||||||
|
const slen = parser.nodeListLength(scripts);
|
||||||
|
for (0..slen) |i| {
|
||||||
|
const s = parser.nodeListItem(scripts, @intCast(i)).?;
|
||||||
|
|
||||||
|
const src = parser.nodeTextContent(s).?;
|
||||||
|
res = try evalJS(js_env, alloc, src, "");
|
||||||
|
|
||||||
|
// return the first failure.
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark tests as ready to run.
|
||||||
|
res = try evalJS(js_env, alloc, "window.dispatchEvent({target: 'load'});", "ready");
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the final test status.
|
||||||
|
res = try evalJS(js_env, alloc, "report.status;", "teststatus");
|
||||||
|
if (!res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the test failed, return detailed logs intead of the simple status.
|
||||||
|
if (!std.mem.eql(u8, res.result, "Pass")) {
|
||||||
|
return try evalJS(js_env, alloc, "report.log", "teststatus");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the final result.
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evalJS(env: jsruntime.Env, alloc: std.mem.Allocator, script: []const u8, name: ?[]const u8) !jsruntime.JSResult {
|
||||||
|
var res = jsruntime.JSResult{};
|
||||||
|
try env.run(alloc, script, name, &res, null);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// browse the path to find the tests list.
|
||||||
|
fn findWPTTests(allocator: std.mem.Allocator, path: []const u8, list: *std.ArrayList([]const u8)) !void {
|
||||||
|
var dir = try std.fs.cwd().openIterableDir(path, .{ .no_follow = true });
|
||||||
|
defer dir.close();
|
||||||
|
|
||||||
|
var walker = try dir.walk(allocator);
|
||||||
|
defer walker.deinit();
|
||||||
|
|
||||||
|
while (try walker.next()) |entry| {
|
||||||
|
if (entry.kind != .file) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!std.mem.endsWith(u8, entry.basename, ".html")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try list.append(try std.fs.path.join(allocator, &.{ path, entry.path }));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -228,6 +228,27 @@ pub const NodeType = enum(u4) {
|
|||||||
notation = c.DOM_NOTATION_NODE, // historical
|
notation = c.DOM_NOTATION_NODE, // historical
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NodeList
|
||||||
|
pub const NodeList = c.dom_nodelist;
|
||||||
|
|
||||||
|
pub fn nodeListLength(nodeList: *NodeList) u32 {
|
||||||
|
var ln: u32 = undefined;
|
||||||
|
_ = c.dom_nodelist_get_length(nodeList, &ln);
|
||||||
|
return ln;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nodeListItem(nodeList: *NodeList, index: u32) ?*Node {
|
||||||
|
var n: [*c]c.dom_node = undefined;
|
||||||
|
_ = c._dom_nodelist_item(nodeList, index, &n);
|
||||||
|
|
||||||
|
if (n == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cast [*c]c.dom_node into *Node
|
||||||
|
return @as(*Node, @ptrCast(n));
|
||||||
|
}
|
||||||
|
|
||||||
// Node
|
// Node
|
||||||
pub const Node = c.dom_node_internal;
|
pub const Node = c.dom_node_internal;
|
||||||
|
|
||||||
@@ -636,6 +657,12 @@ pub inline fn documentGetElementById(doc: *Document, id: []const u8) ?*Element {
|
|||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn documentGetElementsByTagName(doc: *Document, tagname: []const u8) *NodeList {
|
||||||
|
var nlist: ?*NodeList = undefined;
|
||||||
|
_ = documentVtable(doc).dom_document_get_elements_by_tag_name.?(doc, stringFromData(tagname), &nlist);
|
||||||
|
return nlist.?;
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn documentCreateElement(doc: *Document, tag_name: []const u8) *Element {
|
pub inline fn documentCreateElement(doc: *Document, tag_name: []const u8) *Element {
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
_ = documentVtable(doc).dom_document_create_element.?(doc, stringFromData(tag_name), &elem);
|
_ = documentVtable(doc).dom_document_create_element.?(doc, stringFromData(tag_name), &elem);
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ const generate = @import("generate.zig");
|
|||||||
const parser = @import("netsurf.zig");
|
const parser = @import("netsurf.zig");
|
||||||
const DOM = @import("dom.zig");
|
const DOM = @import("dom.zig");
|
||||||
|
|
||||||
const docTestExecFn = @import("html/document.zig").testExecFn;
|
const documentTestExecFn = @import("dom/document.zig").testExecFn;
|
||||||
|
const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn;
|
||||||
const nodeTestExecFn = @import("dom/node.zig").testExecFn;
|
const nodeTestExecFn = @import("dom/node.zig").testExecFn;
|
||||||
const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn;
|
const characterDataTestExecFn = @import("dom/character_data.zig").testExecFn;
|
||||||
const textTestExecFn = @import("dom/text.zig").testExecFn;
|
const textTestExecFn = @import("dom/text.zig").testExecFn;
|
||||||
@@ -45,7 +46,8 @@ fn testsAllExecFn(
|
|||||||
comptime apis: []jsruntime.API,
|
comptime apis: []jsruntime.API,
|
||||||
) !void {
|
) !void {
|
||||||
const testFns = [_]jsruntime.ContextExecFn{
|
const testFns = [_]jsruntime.ContextExecFn{
|
||||||
docTestExecFn,
|
documentTestExecFn,
|
||||||
|
HTMLDocumentTestExecFn,
|
||||||
nodeTestExecFn,
|
nodeTestExecFn,
|
||||||
characterDataTestExecFn,
|
characterDataTestExecFn,
|
||||||
textTestExecFn,
|
textTestExecFn,
|
||||||
|
|||||||
166
tests/wpt/dom/nodes/ChildNode-after.html
Normal file
166
tests/wpt/dom/nodes/ChildNode-after.html
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>ChildNode.after</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-after">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function test_after(child, nodeName, innerHTML) {
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after();
|
||||||
|
assert_equals(parent.innerHTML, innerHTML);
|
||||||
|
}, nodeName + '.after() without any argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(null);
|
||||||
|
var expected = innerHTML + 'null';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with null as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(undefined);
|
||||||
|
var expected = innerHTML + 'undefined';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with undefined as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('');
|
||||||
|
assert_equals(parent.lastChild.data, '');
|
||||||
|
}, nodeName + '.after() with the empty string as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('text');
|
||||||
|
var expected = innerHTML + 'text';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with only text as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(x);
|
||||||
|
var expected = innerHTML + '<x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with only one element as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(x, 'text');
|
||||||
|
var expected = innerHTML + '<x></x>text';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with one element and text as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('text', child);
|
||||||
|
var expected = 'text' + innerHTML;
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with context object itself as the argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(child, x);
|
||||||
|
var expected = innerHTML + '<x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with context object itself and node as the arguments, switching positions.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
child.after(x, y, z);
|
||||||
|
var expected = innerHTML + '<x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with all siblings of child as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(z);
|
||||||
|
child.after(x, y);
|
||||||
|
var expected = innerHTML + '<x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.before() with some siblings of child as arguments; no changes in tree; viable sibling is first child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var v = document.createElement('v');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(v);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(z);
|
||||||
|
child.after(v, x);
|
||||||
|
var expected = innerHTML + '<v></v><x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with some siblings of child as arguments; no changes in tree.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
child.after(y, x);
|
||||||
|
var expected = innerHTML + '<y></y><x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() when pre-insert behaves like append.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(document.createTextNode('1'));
|
||||||
|
parent.appendChild(y);
|
||||||
|
child.after(x, '2');
|
||||||
|
var expected = innerHTML + '<x></x>21<y></y>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with one sibling of child and text as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
x.after(y);
|
||||||
|
assert_equals(x.nextSibling, null);
|
||||||
|
}, nodeName + '.after() on a child without any parent.');
|
||||||
|
}
|
||||||
|
|
||||||
|
test_after(document.createComment('test'), 'Comment', '<!--test-->');
|
||||||
|
test_after(document.createElement('test'), 'Element', '<test></test>');
|
||||||
|
test_after(document.createTextNode('test'), 'Text', 'test');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
158
tests/wpt/dom/nodes/Document-createElement.html
Normal file
158
tests/wpt/dom/nodes/Document-createElement.html
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Document.createElement</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-createelement">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-localname">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-tagname">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-prefix">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-namespaceuri">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<iframe src="/common/dummy.xml"></iframe>
|
||||||
|
<iframe src="/common/dummy.xhtml"></iframe>
|
||||||
|
<script>
|
||||||
|
function toASCIIUppercase(str) {
|
||||||
|
var diff = "a".charCodeAt(0) - "A".charCodeAt(0);
|
||||||
|
var res = "";
|
||||||
|
for (var i = 0; i < str.length; ++i) {
|
||||||
|
if ("a" <= str[i] && str[i] <= "z") {
|
||||||
|
res += String.fromCharCode(str.charCodeAt(i) - diff);
|
||||||
|
} else {
|
||||||
|
res += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
function toASCIILowercase(str) {
|
||||||
|
var diff = "a".charCodeAt(0) - "A".charCodeAt(0);
|
||||||
|
var res = "";
|
||||||
|
for (var i = 0; i < str.length; ++i) {
|
||||||
|
if ("A" <= str[i] && str[i] <= "Z") {
|
||||||
|
res += String.fromCharCode(str.charCodeAt(i) + diff);
|
||||||
|
} else {
|
||||||
|
res += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
var HTMLNS = "http://www.w3.org/1999/xhtml",
|
||||||
|
valid = [
|
||||||
|
undefined,
|
||||||
|
null,
|
||||||
|
"foo",
|
||||||
|
"f1oo",
|
||||||
|
"foo1",
|
||||||
|
"f\u0BC6",
|
||||||
|
"foo\u0BC6",
|
||||||
|
":",
|
||||||
|
":foo",
|
||||||
|
"f:oo",
|
||||||
|
"foo:",
|
||||||
|
"f:o:o",
|
||||||
|
"f::oo",
|
||||||
|
"f::oo:",
|
||||||
|
"foo:0",
|
||||||
|
"foo:_",
|
||||||
|
// combining char after :, invalid QName but valid Name
|
||||||
|
"foo:\u0BC6",
|
||||||
|
"foo:foo\u0BC6",
|
||||||
|
"foo\u0BC6:foo",
|
||||||
|
"xml",
|
||||||
|
"xmlns",
|
||||||
|
"xmlfoo",
|
||||||
|
"xml:foo",
|
||||||
|
"xmlns:foo",
|
||||||
|
"xmlfoo:bar",
|
||||||
|
"svg",
|
||||||
|
"math",
|
||||||
|
"FOO",
|
||||||
|
// Test that non-ASCII chars don't get uppercased/lowercased
|
||||||
|
"mar\u212a",
|
||||||
|
"\u0130nput",
|
||||||
|
"\u0131nput",
|
||||||
|
],
|
||||||
|
invalid = [
|
||||||
|
"",
|
||||||
|
"1foo",
|
||||||
|
"1:foo",
|
||||||
|
"fo o",
|
||||||
|
"\u0300foo",
|
||||||
|
"}foo",
|
||||||
|
"f}oo",
|
||||||
|
"foo}",
|
||||||
|
"\ufffffoo",
|
||||||
|
"f\uffffoo",
|
||||||
|
"foo\uffff",
|
||||||
|
"<foo",
|
||||||
|
"foo>",
|
||||||
|
"<foo>",
|
||||||
|
"f<oo",
|
||||||
|
"-foo",
|
||||||
|
".foo",
|
||||||
|
"\u0300",
|
||||||
|
]
|
||||||
|
|
||||||
|
var xmlIframe = document.querySelector('[src="/common/dummy.xml"]');
|
||||||
|
var xhtmlIframe = document.querySelector('[src="/common/dummy.xhtml"]');
|
||||||
|
|
||||||
|
function getWin(desc) {
|
||||||
|
if (desc == "HTML document") {
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
if (desc == "XML document") {
|
||||||
|
assert_equals(xmlIframe.contentDocument.documentElement.textContent,
|
||||||
|
"Dummy XML document", "XML document didn't load");
|
||||||
|
return xmlIframe.contentWindow;
|
||||||
|
}
|
||||||
|
if (desc == "XHTML document") {
|
||||||
|
assert_equals(xhtmlIframe.contentDocument.documentElement.textContent,
|
||||||
|
"Dummy XHTML document", "XHTML document didn't load");
|
||||||
|
return xhtmlIframe.contentWindow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
valid.forEach(function(t) {
|
||||||
|
["HTML document", "XML document", "XHTML document"].forEach(function(desc) {
|
||||||
|
async_test(function(testObj) {
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
testObj.step(function() {
|
||||||
|
var win = getWin(desc);
|
||||||
|
var doc = win.document;
|
||||||
|
var elt = doc.createElement(t)
|
||||||
|
assert_true(elt instanceof win.Element, "instanceof Element")
|
||||||
|
assert_true(elt instanceof win.Node, "instanceof Node")
|
||||||
|
assert_equals(elt.localName,
|
||||||
|
desc == "HTML document" ? toASCIILowercase(String(t))
|
||||||
|
: String(t),
|
||||||
|
"localName")
|
||||||
|
assert_equals(elt.tagName,
|
||||||
|
desc == "HTML document" ? toASCIIUppercase(String(t))
|
||||||
|
: String(t),
|
||||||
|
"tagName")
|
||||||
|
assert_equals(elt.prefix, null, "prefix")
|
||||||
|
assert_equals(elt.namespaceURI,
|
||||||
|
desc == "XML document" ? null : HTMLNS, "namespaceURI")
|
||||||
|
});
|
||||||
|
testObj.done();
|
||||||
|
});
|
||||||
|
}, "createElement(" + format_value(t) + ") in " + desc);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
invalid.forEach(function(arg) {
|
||||||
|
["HTML document", "XML document", "XHTML document"].forEach(function(desc) {
|
||||||
|
async_test(function(testObj) {
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
testObj.step(function() {
|
||||||
|
let win = getWin(desc);
|
||||||
|
let doc = win.document;
|
||||||
|
assert_throws_dom("InvalidCharacterError", win.DOMException,
|
||||||
|
function() { doc.createElement(arg) })
|
||||||
|
});
|
||||||
|
testObj.done();
|
||||||
|
});
|
||||||
|
}, "createElement(" + format_value(arg) + ") in " + desc);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
const results = [];
|
||||||
|
test(() => {
|
||||||
|
class Script1 extends HTMLScriptElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
results.push("ce connected s1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Script2 extends HTMLScriptElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
results.push("ce connected s2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define("script-1", Script1, { extends: "script" });
|
||||||
|
customElements.define("script-2", Script2, { extends: "script" });
|
||||||
|
const s1 = new Script1();
|
||||||
|
s1.textContent = "results.push('s1')";
|
||||||
|
const s2 = new Script2();
|
||||||
|
s2.textContent = "results.push('s2')";
|
||||||
|
document.body.append(s1, s2);
|
||||||
|
assert_array_equals(results, ["s1", "s2", "ce connected s1", "ce connected s2"]);
|
||||||
|
}, "Custom element reactions follow script execution");
|
||||||
59
tests/wpt/dom/nodes/Node-appendChild.html
Normal file
59
tests/wpt/dom/nodes/Node-appendChild.html
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.appendChild</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-appendchild">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<iframe src=about:blank></iframe>
|
||||||
|
<script>
|
||||||
|
// TODO: Exhaustive tests
|
||||||
|
function testLeaf(node, desc) {
|
||||||
|
// WebIDL.
|
||||||
|
test(function() {
|
||||||
|
assert_throws_js(TypeError, function() { node.appendChild(null) })
|
||||||
|
}, "Appending null to a " + desc)
|
||||||
|
|
||||||
|
// Pre-insert step 1.
|
||||||
|
test(function() {
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { node.appendChild(document.createTextNode("fail")) })
|
||||||
|
}, "Appending to a " + desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebIDL.
|
||||||
|
test(function() {
|
||||||
|
assert_throws_js(TypeError, function() { document.body.appendChild(null) })
|
||||||
|
assert_throws_js(TypeError, function() { document.body.appendChild({'a':'b'}) })
|
||||||
|
}, "WebIDL tests")
|
||||||
|
|
||||||
|
// WebIDL and pre-insert step 1.
|
||||||
|
test(function() {
|
||||||
|
testLeaf(document.createTextNode("Foo"), "text node")
|
||||||
|
testLeaf(document.createComment("Foo"), "comment")
|
||||||
|
testLeaf(document.doctype, "doctype")
|
||||||
|
}, "Appending to a leaf node.")
|
||||||
|
|
||||||
|
// Pre-insert step 5.
|
||||||
|
test(function() {
|
||||||
|
var frameDoc = frames[0].document
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { document.body.appendChild(frameDoc) })
|
||||||
|
}, "Appending a document")
|
||||||
|
|
||||||
|
// Pre-insert step 8.
|
||||||
|
test(function() {
|
||||||
|
var frameDoc = frames[0].document
|
||||||
|
var s = frameDoc.createElement("a")
|
||||||
|
assert_equals(s.ownerDocument, frameDoc)
|
||||||
|
document.body.appendChild(s)
|
||||||
|
assert_equals(s.ownerDocument, document)
|
||||||
|
}, "Adopting an orphan")
|
||||||
|
test(function() {
|
||||||
|
var frameDoc = frames[0].document
|
||||||
|
var s = frameDoc.createElement("b")
|
||||||
|
assert_equals(s.ownerDocument, frameDoc)
|
||||||
|
frameDoc.body.appendChild(s)
|
||||||
|
assert_equals(s.ownerDocument, frameDoc)
|
||||||
|
document.body.appendChild(s)
|
||||||
|
assert_equals(s.ownerDocument, document)
|
||||||
|
}, "Adopting a non-orphan")
|
||||||
|
</script>
|
||||||
62
tests/wpt/dom/nodes/Node-baseURI.html
Normal file
62
tests/wpt/dom/nodes/Node-baseURI.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.baseURI</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
const elementTests = [
|
||||||
|
{
|
||||||
|
name: "elements belonging to document",
|
||||||
|
creator: () => {
|
||||||
|
const element = document.createElement("div");
|
||||||
|
document.body.appendChild(element);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "elements unassigned to document",
|
||||||
|
creator: () => document.createElement("div")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "elements belonging to document fragments",
|
||||||
|
creator: () => {
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
const element = document.createElement("div");
|
||||||
|
fragment.appendChild(element);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "elements belonging to document fragments in document",
|
||||||
|
creator: () => {
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
const element = document.createElement("div");
|
||||||
|
fragment.appendChild(element);
|
||||||
|
document.body.appendChild(fragment);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const attributeTests = [
|
||||||
|
{
|
||||||
|
name: "attributes unassigned to element",
|
||||||
|
creator: () => document.createAttribute("class")
|
||||||
|
},
|
||||||
|
...elementTests.map(({ name, creator }) => ({
|
||||||
|
name: "attributes in " + name,
|
||||||
|
creator: () => {
|
||||||
|
const element = creator();
|
||||||
|
element.setAttribute("class", "abc");
|
||||||
|
return element.getAttributeNode("class");
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { name, creator } of [...elementTests, ...attributeTests]) {
|
||||||
|
test(function() {
|
||||||
|
const node = creator();
|
||||||
|
assert_equals(node.baseURI, document.URL);
|
||||||
|
}, `For ${name}, baseURI should be document URL`)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
117
tests/wpt/dom/nodes/Node-childNodes.html
Normal file
117
tests/wpt/dom/nodes/Node-childNodes.html
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.childNodes</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-childnodes">
|
||||||
|
<link rel=author title="Tim Taubert" href="mailto:ttaubert@mozilla.com">
|
||||||
|
<link rel=author title="Ms2ger" href="mailto:Ms2ger@gmail.com">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<div style="display: none">
|
||||||
|
<ul id='test'><li>1</li><li>2</li><li>3</li><li>4</li></ul>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
var element = document.createElement("p");
|
||||||
|
assert_equals(element.childNodes, element.childNodes);
|
||||||
|
}, "Caching of Node.childNodes");
|
||||||
|
|
||||||
|
var check_parent_node = function(node) {
|
||||||
|
assert_array_equals(node.childNodes, []);
|
||||||
|
|
||||||
|
var children = node.childNodes;
|
||||||
|
var child = document.createElement("p");
|
||||||
|
node.appendChild(child);
|
||||||
|
assert_equals(node.childNodes, children);
|
||||||
|
assert_array_equals(children, [child]);
|
||||||
|
assert_equals(children.item(0), child);
|
||||||
|
|
||||||
|
var child2 = document.createComment("comment");
|
||||||
|
node.appendChild(child2);
|
||||||
|
assert_array_equals(children, [child, child2]);
|
||||||
|
assert_equals(children.item(0), child);
|
||||||
|
assert_equals(children.item(1), child2);
|
||||||
|
|
||||||
|
assert_false(2 in children);
|
||||||
|
assert_equals(children[2], undefined);
|
||||||
|
assert_equals(children.item(2), null);
|
||||||
|
};
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
check_parent_node(document.createElement("p"));
|
||||||
|
}, "Node.childNodes on an Element.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
check_parent_node(document.createDocumentFragment());
|
||||||
|
}, "Node.childNodes on a DocumentFragment.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
check_parent_node(new Document());
|
||||||
|
}, "Node.childNodes on a Document.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var node = document.createElement("div");
|
||||||
|
var kid1 = document.createElement("p");
|
||||||
|
var kid2 = document.createTextNode("hey");
|
||||||
|
var kid3 = document.createElement("span");
|
||||||
|
node.appendChild(kid1);
|
||||||
|
node.appendChild(kid2);
|
||||||
|
node.appendChild(kid3);
|
||||||
|
|
||||||
|
var list = node.childNodes;
|
||||||
|
assert_array_equals([...list], [kid1, kid2, kid3]);
|
||||||
|
|
||||||
|
var keys = list.keys();
|
||||||
|
assert_false(keys instanceof Array);
|
||||||
|
keys = [...keys];
|
||||||
|
assert_array_equals(keys, [0, 1, 2]);
|
||||||
|
|
||||||
|
var values = list.values();
|
||||||
|
assert_false(values instanceof Array);
|
||||||
|
values = [...values];
|
||||||
|
assert_array_equals(values, [kid1, kid2, kid3]);
|
||||||
|
|
||||||
|
var entries = list.entries();
|
||||||
|
assert_false(entries instanceof Array);
|
||||||
|
entries = [...entries];
|
||||||
|
assert_equals(entries.length, keys.length);
|
||||||
|
assert_equals(entries.length, values.length);
|
||||||
|
for (var i = 0; i < entries.length; ++i) {
|
||||||
|
assert_array_equals(entries[i], [keys[i], values[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cur = 0;
|
||||||
|
var thisObj = {};
|
||||||
|
list.forEach(function(value, key, listObj) {
|
||||||
|
assert_equals(listObj, list);
|
||||||
|
assert_equals(this, thisObj);
|
||||||
|
assert_equals(value, values[cur]);
|
||||||
|
assert_equals(key, keys[cur]);
|
||||||
|
cur++;
|
||||||
|
}, thisObj);
|
||||||
|
assert_equals(cur, entries.length);
|
||||||
|
|
||||||
|
assert_equals(list[Symbol.iterator], Array.prototype[Symbol.iterator]);
|
||||||
|
assert_equals(list.keys, Array.prototype.keys);
|
||||||
|
if (Array.prototype.values) {
|
||||||
|
assert_equals(list.values, Array.prototype.values);
|
||||||
|
}
|
||||||
|
assert_equals(list.entries, Array.prototype.entries);
|
||||||
|
assert_equals(list.forEach, Array.prototype.forEach);
|
||||||
|
}, "Iterator behavior of Node.childNodes");
|
||||||
|
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var node = document.getElementById("test");
|
||||||
|
var children = node.childNodes;
|
||||||
|
assert_true(children instanceof NodeList);
|
||||||
|
var li = document.createElement("li");
|
||||||
|
assert_equals(children.length, 4);
|
||||||
|
|
||||||
|
node.appendChild(li);
|
||||||
|
assert_equals(children.length, 5);
|
||||||
|
|
||||||
|
node.removeChild(li);
|
||||||
|
assert_equals(children.length, 4);
|
||||||
|
}, "Node.childNodes should be a live collection");
|
||||||
|
</script>
|
||||||
28
tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html
Normal file
28
tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Cloning of an XMLDocument</title>
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
|
||||||
|
|
||||||
|
<!-- This is testing in particular "that implements the same interfaces as node" -->
|
||||||
|
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const doc = document.implementation.createDocument("namespace", "");
|
||||||
|
|
||||||
|
assert_equals(
|
||||||
|
doc.constructor, XMLDocument,
|
||||||
|
"Precondition check: document.implementation.createDocument() creates an XMLDocument"
|
||||||
|
);
|
||||||
|
|
||||||
|
const clone = doc.cloneNode(true);
|
||||||
|
|
||||||
|
assert_equals(clone.constructor, XMLDocument);
|
||||||
|
}, "Created with createDocument");
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Cloning of a document with a doctype</title>
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
|
||||||
|
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const doctype = document.implementation.createDocumentType("name", "publicId", "systemId");
|
||||||
|
const doc = document.implementation.createDocument("namespace", "", doctype);
|
||||||
|
|
||||||
|
const clone = doc.cloneNode(true);
|
||||||
|
|
||||||
|
assert_equals(clone.childNodes.length, 1, "Only one child node");
|
||||||
|
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
|
||||||
|
assert_equals(clone.childNodes[0].name, "name");
|
||||||
|
assert_equals(clone.childNodes[0].publicId, "publicId");
|
||||||
|
assert_equals(clone.childNodes[0].systemId, "systemId");
|
||||||
|
}, "Created with the createDocument/createDocumentType");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const doc = document.implementation.createHTMLDocument();
|
||||||
|
|
||||||
|
const clone = doc.cloneNode(true);
|
||||||
|
|
||||||
|
assert_equals(clone.childNodes.length, 2, "Two child nodes");
|
||||||
|
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
|
||||||
|
assert_equals(clone.childNodes[0].name, "html");
|
||||||
|
assert_equals(clone.childNodes[0].publicId, "");
|
||||||
|
assert_equals(clone.childNodes[0].systemId, "");
|
||||||
|
}, "Created with the createHTMLDocument");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const parser = new window.DOMParser();
|
||||||
|
const doc = parser.parseFromString("<!DOCTYPE html><html></html>", "text/html");
|
||||||
|
|
||||||
|
const clone = doc.cloneNode(true);
|
||||||
|
|
||||||
|
assert_equals(clone.childNodes.length, 2, "Two child nodes");
|
||||||
|
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
|
||||||
|
assert_equals(clone.childNodes[0].name, "html");
|
||||||
|
assert_equals(clone.childNodes[0].publicId, "");
|
||||||
|
assert_equals(clone.childNodes[0].systemId, "");
|
||||||
|
}, "Created with DOMParser");
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>cloneNode on a stylesheet link in a browsing-context-less document</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<!-- Regression test for https://github.com/jsdom/jsdom/issues/2497 -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
setup({ single_test: true });
|
||||||
|
|
||||||
|
const doc = document.implementation.createHTMLDocument();
|
||||||
|
|
||||||
|
// Bug was only triggered by absolute URLs, for some reason...
|
||||||
|
const absoluteURL = new URL("/common/canvas-frame.css", location.href);
|
||||||
|
doc.head.innerHTML = `<link rel="stylesheet" href="${absoluteURL}">`;
|
||||||
|
|
||||||
|
// Test passes if this does not throw/crash
|
||||||
|
doc.cloneNode(true);
|
||||||
|
|
||||||
|
done();
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<iframe id="i"></iframe>
|
||||||
|
<script>
|
||||||
|
var doc = i.contentDocument;
|
||||||
|
i.remove();
|
||||||
|
doc.cloneNode();
|
||||||
|
</script>
|
||||||
63
tests/wpt/dom/nodes/Node-cloneNode-svg.html
Normal file
63
tests/wpt/dom/nodes/Node-cloneNode-svg.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Cloning of SVG elements and attributes</title>
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
|
||||||
|
<!-- regression test for https://github.com/jsdom/jsdom/issues/1601 -->
|
||||||
|
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<svg xmlns:xlink='http://www.w3.org/1999/xlink'><use xlink:href='#test'></use></svg>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const svg = document.querySelector("svg");
|
||||||
|
const clone = svg.cloneNode(true);
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
assert_equals(clone.namespaceURI, "http://www.w3.org/2000/svg");
|
||||||
|
assert_equals(clone.prefix, null);
|
||||||
|
assert_equals(clone.localName, "svg");
|
||||||
|
assert_equals(clone.tagName, "svg");
|
||||||
|
|
||||||
|
}, "cloned <svg> should have the right properties");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
const attr = clone.attributes[0];
|
||||||
|
|
||||||
|
assert_equals(attr.namespaceURI, "http://www.w3.org/2000/xmlns/");
|
||||||
|
assert_equals(attr.prefix, "xmlns");
|
||||||
|
assert_equals(attr.localName, "xlink");
|
||||||
|
assert_equals(attr.name, "xmlns:xlink");
|
||||||
|
assert_equals(attr.value, "http://www.w3.org/1999/xlink");
|
||||||
|
|
||||||
|
}, "cloned <svg>'s xmlns:xlink attribute should have the right properties");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
const use = clone.firstElementChild;
|
||||||
|
assert_equals(use.namespaceURI, "http://www.w3.org/2000/svg");
|
||||||
|
assert_equals(use.prefix, null);
|
||||||
|
assert_equals(use.localName, "use");
|
||||||
|
assert_equals(use.tagName, "use");
|
||||||
|
|
||||||
|
}, "cloned <use> should have the right properties");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
const use = clone.firstElementChild;
|
||||||
|
const attr = use.attributes[0];
|
||||||
|
|
||||||
|
assert_equals(attr.namespaceURI, "http://www.w3.org/1999/xlink");
|
||||||
|
assert_equals(attr.prefix, "xlink");
|
||||||
|
assert_equals(attr.localName, "href");
|
||||||
|
assert_equals(attr.name, "xlink:href");
|
||||||
|
assert_equals(attr.value, "#test");
|
||||||
|
|
||||||
|
}, "cloned <use>'s xlink:href attribute should have the right properties");
|
||||||
|
|
||||||
|
</script>
|
||||||
346
tests/wpt/dom/nodes/Node-cloneNode.html
Normal file
346
tests/wpt/dom/nodes/Node-cloneNode.html
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.cloneNode</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-clonenode">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
function assert_equal_node(nodeA, nodeB) {
|
||||||
|
assert_equals(nodeB.nodeType, nodeA.nodeType, "nodeType");
|
||||||
|
assert_equals(nodeB.nodeName, nodeA.nodeName, "nodeName");
|
||||||
|
|
||||||
|
if (nodeA.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
assert_equals(nodeB.prefix, nodeA.prefix, "prefix");
|
||||||
|
assert_equals(nodeB.namespaceURI, nodeA.namespaceURI, "namespaceURI");
|
||||||
|
assert_equals(nodeB.localName, nodeA.localName, "localName");
|
||||||
|
assert_equals(nodeB.tagName, nodeA.tagName, "tagName");
|
||||||
|
assert_not_equals(nodeB.attributes != nodeA.attributes, "attributes");
|
||||||
|
assert_equals(nodeB.attributes.length, nodeA.attributes.length,
|
||||||
|
"attributes.length");
|
||||||
|
for (var i = 0, il = nodeA.attributes.length; i < il; ++i) {
|
||||||
|
assert_not_equals(nodeB.attributes[i], nodeA.attributes[i],
|
||||||
|
"attributes[" + i + "]");
|
||||||
|
assert_equals(nodeB.attributes[i].name, nodeA.attributes[i].name,
|
||||||
|
"attributes[" + i + "].name");
|
||||||
|
assert_equals(nodeB.attributes[i].prefix, nodeA.attributes[i].prefix,
|
||||||
|
"attributes[" + i + "].prefix");
|
||||||
|
assert_equals(nodeB.attributes[i].namespaceURI, nodeA.attributes[i].namespaceURI,
|
||||||
|
"attributes[" + i + "].namespaceURI");
|
||||||
|
assert_equals(nodeB.attributes[i].value, nodeA.attributes[i].value,
|
||||||
|
"attributes[" + i + "].value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_copy(orig, copy, type) {
|
||||||
|
assert_not_equals(orig, copy, "Object equality");
|
||||||
|
assert_equal_node(orig, copy, "Node equality");
|
||||||
|
assert_true(orig instanceof type, "original instanceof " + type);
|
||||||
|
assert_true(copy instanceof type, "copy instanceof " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_element_and_check(localName, typeName) {
|
||||||
|
test(function() {
|
||||||
|
assert_true(typeName in window, typeName + " is not supported");
|
||||||
|
var element = document.createElement(localName);
|
||||||
|
var copy = element.cloneNode();
|
||||||
|
check_copy(element, copy, window[typeName]);
|
||||||
|
}, "createElement(" + localName + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test1: createElement
|
||||||
|
create_element_and_check("a", "HTMLAnchorElement");
|
||||||
|
create_element_and_check("abbr", "HTMLElement");
|
||||||
|
create_element_and_check("acronym", "HTMLElement");
|
||||||
|
create_element_and_check("address", "HTMLElement");
|
||||||
|
create_element_and_check("area", "HTMLAreaElement");
|
||||||
|
create_element_and_check("article", "HTMLElement");
|
||||||
|
create_element_and_check("aside", "HTMLElement");
|
||||||
|
create_element_and_check("audio", "HTMLAudioElement");
|
||||||
|
create_element_and_check("b", "HTMLElement");
|
||||||
|
create_element_and_check("base", "HTMLBaseElement");
|
||||||
|
create_element_and_check("bdi", "HTMLElement");
|
||||||
|
create_element_and_check("bdo", "HTMLElement");
|
||||||
|
create_element_and_check("bgsound", "HTMLElement");
|
||||||
|
create_element_and_check("big", "HTMLElement");
|
||||||
|
create_element_and_check("blockquote","HTMLElement");
|
||||||
|
create_element_and_check("body", "HTMLBodyElement");
|
||||||
|
create_element_and_check("br", "HTMLBRElement");
|
||||||
|
create_element_and_check("button", "HTMLButtonElement");
|
||||||
|
create_element_and_check("canvas", "HTMLCanvasElement");
|
||||||
|
create_element_and_check("caption", "HTMLTableCaptionElement");
|
||||||
|
create_element_and_check("center", "HTMLElement");
|
||||||
|
create_element_and_check("cite", "HTMLElement");
|
||||||
|
create_element_and_check("code", "HTMLElement");
|
||||||
|
create_element_and_check("col", "HTMLTableColElement");
|
||||||
|
create_element_and_check("colgroup", "HTMLTableColElement");
|
||||||
|
create_element_and_check("data", "HTMLDataElement");
|
||||||
|
create_element_and_check("datalist", "HTMLDataListElement");
|
||||||
|
create_element_and_check("dialog", "HTMLDialogElement");
|
||||||
|
create_element_and_check("dd", "HTMLElement");
|
||||||
|
create_element_and_check("del", "HTMLModElement");
|
||||||
|
create_element_and_check("details", "HTMLElement");
|
||||||
|
create_element_and_check("dfn", "HTMLElement");
|
||||||
|
create_element_and_check("dir", "HTMLDirectoryElement");
|
||||||
|
create_element_and_check("div", "HTMLDivElement");
|
||||||
|
create_element_and_check("dl", "HTMLDListElement");
|
||||||
|
create_element_and_check("dt", "HTMLElement");
|
||||||
|
create_element_and_check("embed", "HTMLEmbedElement");
|
||||||
|
create_element_and_check("fieldset", "HTMLFieldSetElement");
|
||||||
|
create_element_and_check("figcaption","HTMLElement");
|
||||||
|
create_element_and_check("figure", "HTMLElement");
|
||||||
|
create_element_and_check("font", "HTMLFontElement");
|
||||||
|
create_element_and_check("footer", "HTMLElement");
|
||||||
|
create_element_and_check("form", "HTMLFormElement");
|
||||||
|
create_element_and_check("frame", "HTMLFrameElement");
|
||||||
|
create_element_and_check("frameset", "HTMLFrameSetElement");
|
||||||
|
create_element_and_check("h1", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("h2", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("h3", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("h4", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("h5", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("h6", "HTMLHeadingElement");
|
||||||
|
create_element_and_check("head", "HTMLHeadElement");
|
||||||
|
create_element_and_check("header", "HTMLElement");
|
||||||
|
create_element_and_check("hgroup", "HTMLElement");
|
||||||
|
create_element_and_check("hr", "HTMLHRElement");
|
||||||
|
create_element_and_check("html", "HTMLHtmlElement");
|
||||||
|
create_element_and_check("i", "HTMLElement");
|
||||||
|
create_element_and_check("iframe", "HTMLIFrameElement");
|
||||||
|
create_element_and_check("img", "HTMLImageElement");
|
||||||
|
create_element_and_check("input", "HTMLInputElement");
|
||||||
|
create_element_and_check("ins", "HTMLModElement");
|
||||||
|
create_element_and_check("isindex", "HTMLElement");
|
||||||
|
create_element_and_check("kbd", "HTMLElement");
|
||||||
|
create_element_and_check("label", "HTMLLabelElement");
|
||||||
|
create_element_and_check("legend", "HTMLLegendElement");
|
||||||
|
create_element_and_check("li", "HTMLLIElement");
|
||||||
|
create_element_and_check("link", "HTMLLinkElement");
|
||||||
|
create_element_and_check("main", "HTMLElement");
|
||||||
|
create_element_and_check("map", "HTMLMapElement");
|
||||||
|
create_element_and_check("mark", "HTMLElement");
|
||||||
|
create_element_and_check("marquee", "HTMLElement");
|
||||||
|
create_element_and_check("meta", "HTMLMetaElement");
|
||||||
|
create_element_and_check("meter", "HTMLMeterElement");
|
||||||
|
create_element_and_check("nav", "HTMLElement");
|
||||||
|
create_element_and_check("nobr", "HTMLElement");
|
||||||
|
create_element_and_check("noframes", "HTMLElement");
|
||||||
|
create_element_and_check("noscript", "HTMLElement");
|
||||||
|
create_element_and_check("object", "HTMLObjectElement");
|
||||||
|
create_element_and_check("ol", "HTMLOListElement");
|
||||||
|
create_element_and_check("optgroup", "HTMLOptGroupElement");
|
||||||
|
create_element_and_check("option", "HTMLOptionElement");
|
||||||
|
create_element_and_check("output", "HTMLOutputElement");
|
||||||
|
create_element_and_check("p", "HTMLParagraphElement");
|
||||||
|
create_element_and_check("param", "HTMLParamElement");
|
||||||
|
create_element_and_check("pre", "HTMLPreElement");
|
||||||
|
create_element_and_check("progress", "HTMLProgressElement");
|
||||||
|
create_element_and_check("q", "HTMLQuoteElement");
|
||||||
|
create_element_and_check("rp", "HTMLElement");
|
||||||
|
create_element_and_check("rt", "HTMLElement");
|
||||||
|
create_element_and_check("ruby", "HTMLElement");
|
||||||
|
create_element_and_check("s", "HTMLElement");
|
||||||
|
create_element_and_check("samp", "HTMLElement");
|
||||||
|
create_element_and_check("script", "HTMLScriptElement");
|
||||||
|
create_element_and_check("section", "HTMLElement");
|
||||||
|
create_element_and_check("select", "HTMLSelectElement");
|
||||||
|
create_element_and_check("small", "HTMLElement");
|
||||||
|
create_element_and_check("source", "HTMLSourceElement");
|
||||||
|
create_element_and_check("spacer", "HTMLElement");
|
||||||
|
create_element_and_check("span", "HTMLSpanElement");
|
||||||
|
create_element_and_check("strike", "HTMLElement");
|
||||||
|
create_element_and_check("style", "HTMLStyleElement");
|
||||||
|
create_element_and_check("sub", "HTMLElement");
|
||||||
|
create_element_and_check("summary", "HTMLElement");
|
||||||
|
create_element_and_check("sup", "HTMLElement");
|
||||||
|
create_element_and_check("table", "HTMLTableElement");
|
||||||
|
create_element_and_check("tbody", "HTMLTableSectionElement");
|
||||||
|
create_element_and_check("td", "HTMLTableCellElement");
|
||||||
|
create_element_and_check("template", "HTMLTemplateElement");
|
||||||
|
create_element_and_check("textarea", "HTMLTextAreaElement");
|
||||||
|
create_element_and_check("th", "HTMLTableCellElement");
|
||||||
|
create_element_and_check("time", "HTMLTimeElement");
|
||||||
|
create_element_and_check("title", "HTMLTitleElement");
|
||||||
|
create_element_and_check("tr", "HTMLTableRowElement");
|
||||||
|
create_element_and_check("tt", "HTMLElement");
|
||||||
|
create_element_and_check("track", "HTMLTrackElement");
|
||||||
|
create_element_and_check("u", "HTMLElement");
|
||||||
|
create_element_and_check("ul", "HTMLUListElement");
|
||||||
|
create_element_and_check("var", "HTMLElement");
|
||||||
|
create_element_and_check("video", "HTMLVideoElement");
|
||||||
|
create_element_and_check("unknown", "HTMLUnknownElement");
|
||||||
|
create_element_and_check("wbr", "HTMLElement");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var fragment = document.createDocumentFragment();
|
||||||
|
var copy = fragment.cloneNode();
|
||||||
|
check_copy(fragment, copy, DocumentFragment);
|
||||||
|
}, "createDocumentFragment");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var text = document.createTextNode("hello world");
|
||||||
|
var copy = text.cloneNode();
|
||||||
|
check_copy(text, copy, Text);
|
||||||
|
assert_equals(text.data, copy.data);
|
||||||
|
assert_equals(text.wholeText, copy.wholeText);
|
||||||
|
}, "createTextNode");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var comment = document.createComment("a comment");
|
||||||
|
var copy = comment.cloneNode();
|
||||||
|
check_copy(comment, copy, Comment);
|
||||||
|
assert_equals(comment.data, copy.data);
|
||||||
|
}, "createComment");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("foo");
|
||||||
|
el.setAttribute("a", "b");
|
||||||
|
el.setAttribute("c", "d");
|
||||||
|
var c = el.cloneNode();
|
||||||
|
check_copy(el, c, Element);
|
||||||
|
}, "createElement with attributes")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:div");
|
||||||
|
var c = el.cloneNode();
|
||||||
|
check_copy(el, c, HTMLDivElement);
|
||||||
|
}, "createElementNS HTML")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElementNS("http://www.example.com/", "foo:div");
|
||||||
|
var c = el.cloneNode();
|
||||||
|
check_copy(el, c, Element);
|
||||||
|
}, "createElementNS non-HTML")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var pi = document.createProcessingInstruction("target", "data");
|
||||||
|
var copy = pi.cloneNode();
|
||||||
|
check_copy(pi, copy, ProcessingInstruction);
|
||||||
|
assert_equals(pi.data, copy.data, "data");
|
||||||
|
assert_equals(pi.target, pi.target, "target");
|
||||||
|
}, "createProcessingInstruction");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var attr = document.createAttribute("class");
|
||||||
|
var copy = attr.cloneNode();
|
||||||
|
check_copy(attr, copy, Attr);
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy.localName);
|
||||||
|
assert_equals(attr.value, copy.value);
|
||||||
|
|
||||||
|
attr.value = "abc";
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy.localName);
|
||||||
|
assert_not_equals(attr.value, copy.value);
|
||||||
|
|
||||||
|
var copy2 = attr.cloneNode();
|
||||||
|
check_copy(attr, copy2, Attr);
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy2.localName);
|
||||||
|
assert_equals(attr.value, copy2.value);
|
||||||
|
}, "createAttribute");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var attr = document.createAttributeNS("http://www.w3.org/1999/xhtml", "foo:class");
|
||||||
|
var copy = attr.cloneNode();
|
||||||
|
check_copy(attr, copy, Attr);
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy.localName);
|
||||||
|
assert_equals(attr.value, copy.value);
|
||||||
|
|
||||||
|
attr.value = "abc";
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy.localName);
|
||||||
|
assert_not_equals(attr.value, copy.value);
|
||||||
|
|
||||||
|
var copy2 = attr.cloneNode();
|
||||||
|
check_copy(attr, copy2, Attr);
|
||||||
|
assert_equals(attr.namespaceURI, copy.namespaceURI);
|
||||||
|
assert_equals(attr.prefix, copy.prefix);
|
||||||
|
assert_equals(attr.localName, copy2.localName);
|
||||||
|
assert_equals(attr.value, copy2.value);
|
||||||
|
}, "createAttributeNS");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "public", "system");
|
||||||
|
var copy = doctype.cloneNode();
|
||||||
|
check_copy(doctype, copy, DocumentType);
|
||||||
|
assert_equals(doctype.name, copy.name, "name");
|
||||||
|
assert_equals(doctype.publicId, copy.publicId, "publicId");
|
||||||
|
assert_equals(doctype.systemId, copy.systemId, "systemId");
|
||||||
|
}, "implementation.createDocumentType");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createDocument(null, null);
|
||||||
|
var copy = doc.cloneNode();
|
||||||
|
check_copy(doc, copy, Document);
|
||||||
|
assert_equals(doc.charset, "UTF-8", "charset value");
|
||||||
|
assert_equals(doc.charset, copy.charset, "charset equality");
|
||||||
|
assert_equals(doc.contentType, "application/xml", "contentType value");
|
||||||
|
assert_equals(doc.contentType, copy.contentType, "contentType equality");
|
||||||
|
assert_equals(doc.URL, "about:blank", "URL value")
|
||||||
|
assert_equals(doc.URL, copy.URL, "URL equality");
|
||||||
|
assert_equals(doc.compatMode, "CSS1Compat", "compatMode value");
|
||||||
|
assert_equals(doc.compatMode, copy.compatMode, "compatMode equality");
|
||||||
|
}, "implementation.createDocument");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var html = document.implementation.createHTMLDocument("title");
|
||||||
|
var copy = html.cloneNode();
|
||||||
|
check_copy(html, copy, Document);
|
||||||
|
assert_equals(copy.title, "", "title value");
|
||||||
|
}, "implementation.createHTMLDocument");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement("div");
|
||||||
|
var child1 = document.createElement("div");
|
||||||
|
var child2 = document.createElement("div");
|
||||||
|
var grandChild = document.createElement("div");
|
||||||
|
|
||||||
|
child2.appendChild(grandChild);
|
||||||
|
parent.appendChild(child1);
|
||||||
|
parent.appendChild(child2);
|
||||||
|
|
||||||
|
var deep = true;
|
||||||
|
var copy = parent.cloneNode(deep);
|
||||||
|
|
||||||
|
check_copy(parent, copy, HTMLDivElement);
|
||||||
|
assert_equals(copy.childNodes.length, 2,
|
||||||
|
"copy.childNodes.length with deep copy");
|
||||||
|
|
||||||
|
check_copy(child1, copy.childNodes[0], HTMLDivElement);
|
||||||
|
assert_equals(copy.childNodes[0].childNodes.length, 0,
|
||||||
|
"copy.childNodes[0].childNodes.length");
|
||||||
|
|
||||||
|
check_copy(child2, copy.childNodes[1], HTMLDivElement);
|
||||||
|
assert_equals(copy.childNodes[1].childNodes.length, 1,
|
||||||
|
"copy.childNodes[1].childNodes.length");
|
||||||
|
check_copy(grandChild, copy.childNodes[1].childNodes[0], HTMLDivElement);
|
||||||
|
|
||||||
|
deep = false;
|
||||||
|
copy = parent.cloneNode(deep);
|
||||||
|
|
||||||
|
check_copy(parent, copy, HTMLDivElement);
|
||||||
|
assert_equals(copy.childNodes.length, 0,
|
||||||
|
"copy.childNodes.length with non-deep copy");
|
||||||
|
}, "node with children");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const proto = Object.create(HTMLElement.prototype),
|
||||||
|
node = document.createElement("hi");
|
||||||
|
Object.setPrototypeOf(node, proto);
|
||||||
|
assert_true(proto.isPrototypeOf(node));
|
||||||
|
const clone = node.cloneNode();
|
||||||
|
assert_false(proto.isPrototypeOf(clone));
|
||||||
|
assert_true(HTMLUnknownElement.prototype.isPrototypeOf(clone));
|
||||||
|
const deepClone = node.cloneNode(true);
|
||||||
|
assert_false(proto.isPrototypeOf(deepClone));
|
||||||
|
assert_true(HTMLUnknownElement.prototype.isPrototypeOf(deepClone));
|
||||||
|
}, "Node with custom prototype")
|
||||||
|
</script>
|
||||||
87
tests/wpt/dom/nodes/Node-compareDocumentPosition.html
Normal file
87
tests/wpt/dom/nodes/Node-compareDocumentPosition.html
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<title>Node.compareDocumentPosition() tests</title>
|
||||||
|
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
||||||
|
<div id=log></div>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<script src=../common.js></script>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
testNodes.forEach(function(referenceName) {
|
||||||
|
var reference = eval(referenceName);
|
||||||
|
testNodes.forEach(function(otherName) {
|
||||||
|
var other = eval(otherName);
|
||||||
|
test(function() {
|
||||||
|
var result = reference.compareDocumentPosition(other);
|
||||||
|
|
||||||
|
// "If other and reference are the same object, return zero and
|
||||||
|
// terminate these steps."
|
||||||
|
if (other === reference) {
|
||||||
|
assert_equals(result, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "If other and reference are not in the same tree, return the result of
|
||||||
|
// adding DOCUMENT_POSITION_DISCONNECTED,
|
||||||
|
// DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either
|
||||||
|
// DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING, with the
|
||||||
|
// constraint that this is to be consistent, together and terminate these
|
||||||
|
// steps."
|
||||||
|
if (furthestAncestor(reference) !== furthestAncestor(other)) {
|
||||||
|
// TODO: Test that it's consistent.
|
||||||
|
assert_in_array(result, [Node.DOCUMENT_POSITION_DISCONNECTED +
|
||||||
|
Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC +
|
||||||
|
Node.DOCUMENT_POSITION_PRECEDING,
|
||||||
|
Node.DOCUMENT_POSITION_DISCONNECTED +
|
||||||
|
Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC +
|
||||||
|
Node.DOCUMENT_POSITION_FOLLOWING]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "If other is an ancestor of reference, return the result of
|
||||||
|
// adding DOCUMENT_POSITION_CONTAINS to DOCUMENT_POSITION_PRECEDING
|
||||||
|
// and terminate these steps."
|
||||||
|
var ancestor = reference.parentNode;
|
||||||
|
while (ancestor && ancestor !== other) {
|
||||||
|
ancestor = ancestor.parentNode;
|
||||||
|
}
|
||||||
|
if (ancestor === other) {
|
||||||
|
assert_equals(result, Node.DOCUMENT_POSITION_CONTAINS +
|
||||||
|
Node.DOCUMENT_POSITION_PRECEDING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "If other is a descendant of reference, return the result of adding
|
||||||
|
// DOCUMENT_POSITION_CONTAINED_BY to DOCUMENT_POSITION_FOLLOWING and
|
||||||
|
// terminate these steps."
|
||||||
|
ancestor = other.parentNode;
|
||||||
|
while (ancestor && ancestor !== reference) {
|
||||||
|
ancestor = ancestor.parentNode;
|
||||||
|
}
|
||||||
|
if (ancestor === reference) {
|
||||||
|
assert_equals(result, Node.DOCUMENT_POSITION_CONTAINED_BY +
|
||||||
|
Node.DOCUMENT_POSITION_FOLLOWING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "If other is preceding reference return DOCUMENT_POSITION_PRECEDING
|
||||||
|
// and terminate these steps."
|
||||||
|
var prev = previousNode(reference);
|
||||||
|
while (prev && prev !== other) {
|
||||||
|
prev = previousNode(prev);
|
||||||
|
}
|
||||||
|
if (prev === other) {
|
||||||
|
assert_equals(result, Node.DOCUMENT_POSITION_PRECEDING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Return DOCUMENT_POSITION_FOLLOWING."
|
||||||
|
assert_equals(result, Node.DOCUMENT_POSITION_FOLLOWING);
|
||||||
|
}, referenceName + ".compareDocumentPosition(" + otherName + ")");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testDiv.parentNode.removeChild(testDiv);
|
||||||
|
</script>
|
||||||
|
<!-- vim: set expandtab tabstop=2 shiftwidth=2: -->
|
||||||
39
tests/wpt/dom/nodes/Node-constants.html
Normal file
39
tests/wpt/dom/nodes/Node-constants.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<title>Node constants</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="../constants.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
var objects;
|
||||||
|
setup(function() {
|
||||||
|
objects = [
|
||||||
|
[Node, "Node interface object"],
|
||||||
|
[Node.prototype, "Node prototype object"],
|
||||||
|
[document.createElement("foo"), "Element object"],
|
||||||
|
[document.createTextNode("bar"), "Text object"]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
testConstants(objects, [
|
||||||
|
["ELEMENT_NODE", 1],
|
||||||
|
["ATTRIBUTE_NODE", 2],
|
||||||
|
["TEXT_NODE", 3],
|
||||||
|
["CDATA_SECTION_NODE", 4],
|
||||||
|
["ENTITY_REFERENCE_NODE", 5],
|
||||||
|
["ENTITY_NODE", 6],
|
||||||
|
["PROCESSING_INSTRUCTION_NODE", 7],
|
||||||
|
["COMMENT_NODE", 8],
|
||||||
|
["DOCUMENT_NODE", 9],
|
||||||
|
["DOCUMENT_TYPE_NODE", 10],
|
||||||
|
["DOCUMENT_FRAGMENT_NODE", 11],
|
||||||
|
["NOTATION_NODE", 12]
|
||||||
|
], "nodeType")
|
||||||
|
testConstants(objects, [
|
||||||
|
["DOCUMENT_POSITION_DISCONNECTED", 0x01],
|
||||||
|
["DOCUMENT_POSITION_PRECEDING", 0x02],
|
||||||
|
["DOCUMENT_POSITION_FOLLOWING", 0x04],
|
||||||
|
["DOCUMENT_POSITION_CONTAINS", 0x08],
|
||||||
|
["DOCUMENT_POSITION_CONTAINED_BY", 0x10],
|
||||||
|
["DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 0x20]
|
||||||
|
], "createDocumentPosition")
|
||||||
|
</script>
|
||||||
83
tests/wpt/dom/nodes/Node-contains-xml.xml
Normal file
83
tests/wpt/dom/nodes/Node-contains-xml.xml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Node.nodeName</title>
|
||||||
|
<link rel="author" title="Olli Pettay" href="mailto:Olli@Pettay.fi"/>
|
||||||
|
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com"/>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<div id="test">
|
||||||
|
<input type="button" id="testbutton"/>
|
||||||
|
<a id="link">Link text</a>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
<![CDATA[
|
||||||
|
test(function() {
|
||||||
|
assert_throws_js(TypeError, function() {
|
||||||
|
document.contains();
|
||||||
|
});
|
||||||
|
assert_throws_js(TypeError, function() {
|
||||||
|
document.contains(9);
|
||||||
|
});
|
||||||
|
}, "Should throw TypeError if the arguments are wrong.");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.contains(null), false, "Document shouldn't contain null.");
|
||||||
|
}, "contains(null) should be false");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.contains(document), true, "Document should contain itself!");
|
||||||
|
assert_equals(document.contains(document.createElement("foo")), false, "Document shouldn't contain element which is't in the document");
|
||||||
|
assert_equals(document.contains(document.createTextNode("foo")), false, "Document shouldn't contain text node which is't in the document");
|
||||||
|
}, "document.contains");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var tb = document.getElementById("testbutton");
|
||||||
|
assert_equals(tb.contains(tb), true, "Element should contain itself.")
|
||||||
|
assert_equals(document.contains(tb), true, "Document should contain element in it!");
|
||||||
|
assert_equals(document.documentElement.contains(tb), true, "Element should contain element in it!");
|
||||||
|
}, "contains with a button");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var link = document.getElementById("link");
|
||||||
|
var text = link.firstChild;
|
||||||
|
assert_equals(document.contains(text), true, "Document should contain a text node in it.");
|
||||||
|
assert_equals(link.contains(text), true, "Element should contain a text node in it.");
|
||||||
|
assert_equals(text.contains(text), true, "Text node should contain itself.");
|
||||||
|
assert_equals(text.contains(link), false, "text node shouldn't contain its parent.");
|
||||||
|
}, "contains with a text node");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var pi = document.createProcessingInstruction("adf", "asd");
|
||||||
|
assert_equals(pi.contains(document), false, "Processing instruction shouldn't contain document");
|
||||||
|
assert_equals(document.contains(pi), false, "Document shouldn't contain newly created processing instruction");
|
||||||
|
document.documentElement.appendChild(pi);
|
||||||
|
assert_equals(document.contains(pi), true, "Document should contain processing instruction");
|
||||||
|
}, "contains with a processing instruction");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
if ("createContextualFragment" in document.createRange()) {
|
||||||
|
var df = document.createRange().createContextualFragment("<div>foo</div>");
|
||||||
|
assert_equals(df.contains(df.firstChild), true, "Document fragment should contain its child");
|
||||||
|
assert_equals(df.contains(df.firstChild.firstChild), true,
|
||||||
|
"Document fragment should contain its descendant");
|
||||||
|
assert_equals(df.contains(df), true, "Document fragment should contain itself.");
|
||||||
|
}
|
||||||
|
}, "contains with a document fragment");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var d = document.implementation.createHTMLDocument("");
|
||||||
|
assert_equals(document.contains(d), false,
|
||||||
|
"Document shouldn't contain another document.");
|
||||||
|
assert_equals(document.contains(d.createElement("div")), false,
|
||||||
|
"Document shouldn't contain an element from another document.");
|
||||||
|
assert_equals(document.contains(d.documentElement), false,
|
||||||
|
"Document shouldn't contain an element from another document.");
|
||||||
|
}, "contaibs with another document");
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
36
tests/wpt/dom/nodes/Node-contains.html
Normal file
36
tests/wpt/dom/nodes/Node-contains.html
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<title>Node.contains() tests</title>
|
||||||
|
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
||||||
|
<div id=log></div>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<script src=../common.js></script>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
testNodes.forEach(function(referenceName) {
|
||||||
|
var reference = eval(referenceName);
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_false(reference.contains(null));
|
||||||
|
}, referenceName + ".contains(null)");
|
||||||
|
|
||||||
|
testNodes.forEach(function(otherName) {
|
||||||
|
var other = eval(otherName);
|
||||||
|
test(function() {
|
||||||
|
var ancestor = other;
|
||||||
|
while (ancestor && ancestor !== reference) {
|
||||||
|
ancestor = ancestor.parentNode;
|
||||||
|
}
|
||||||
|
if (ancestor === reference) {
|
||||||
|
assert_true(reference.contains(other));
|
||||||
|
} else {
|
||||||
|
assert_false(reference.contains(other));
|
||||||
|
}
|
||||||
|
}, referenceName + ".contains(" + otherName + ")");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testDiv.parentNode.removeChild(testDiv);
|
||||||
|
</script>
|
||||||
|
<!-- vim: set expandtab tabstop=2 shiftwidth=2: -->
|
||||||
297
tests/wpt/dom/nodes/Node-insertBefore.html
Normal file
297
tests/wpt/dom/nodes/Node-insertBefore.html
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.insertBefore</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<!-- First test shared pre-insertion checks that work similarly for replaceChild
|
||||||
|
and insertBefore -->
|
||||||
|
<script>
|
||||||
|
var insertFunc = Node.prototype.insertBefore;
|
||||||
|
</script>
|
||||||
|
<script src="pre-insertion-validation-notfound.js"></script>
|
||||||
|
<script src="pre-insertion-validation-hierarchy.js"></script>
|
||||||
|
<script>
|
||||||
|
preInsertionValidateHierarchy("insertBefore");
|
||||||
|
|
||||||
|
function testLeafNode(nodeName, createNodeFunction) {
|
||||||
|
test(function() {
|
||||||
|
var node = createNodeFunction();
|
||||||
|
assert_throws_js(TypeError, function() { node.insertBefore(null, null) })
|
||||||
|
}, "Calling insertBefore with a non-Node first argument on a leaf node " + nodeName + " must throw TypeError.")
|
||||||
|
test(function() {
|
||||||
|
var node = createNodeFunction();
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(document.createTextNode("fail"), null) })
|
||||||
|
// Would be step 2.
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(node, null) })
|
||||||
|
// Would be step 3.
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(node, document.createTextNode("child")) })
|
||||||
|
}, "Calling insertBefore an a leaf node " + nodeName + " must throw HIERARCHY_REQUEST_ERR.")
|
||||||
|
}
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
// WebIDL: first argument.
|
||||||
|
assert_throws_js(TypeError, function() { document.body.insertBefore(null, null) })
|
||||||
|
assert_throws_js(TypeError, function() { document.body.insertBefore(null, document.body.firstChild) })
|
||||||
|
assert_throws_js(TypeError, function() { document.body.insertBefore({'a':'b'}, document.body.firstChild) })
|
||||||
|
}, "Calling insertBefore with a non-Node first argument must throw TypeError.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
// WebIDL: second argument.
|
||||||
|
assert_throws_js(TypeError, function() { document.body.insertBefore(document.createTextNode("child")) })
|
||||||
|
assert_throws_js(TypeError, function() { document.body.insertBefore(document.createTextNode("child"), {'a':'b'}) })
|
||||||
|
}, "Calling insertBefore with second argument missing, or other than Node, null, or undefined, must throw TypeError.")
|
||||||
|
|
||||||
|
testLeafNode("DocumentType", function () { return document.doctype; } )
|
||||||
|
testLeafNode("Text", function () { return document.createTextNode("Foo") })
|
||||||
|
testLeafNode("Comment", function () { return document.createComment("Foo") })
|
||||||
|
testLeafNode("ProcessingInstruction", function () { return document.createProcessingInstruction("foo", "bar") })
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
// Step 2.
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.body, document.getElementById("log")) })
|
||||||
|
assert_throws_dom("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.documentElement, document.getElementById("log")) })
|
||||||
|
}, "Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY_REQUEST_ERR.")
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
assert_throws_dom("NotFoundError", function() {
|
||||||
|
a.insertBefore(b, c);
|
||||||
|
});
|
||||||
|
}, "Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError.")
|
||||||
|
|
||||||
|
// Step 4.1.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var doc2 = document.implementation.createHTMLDocument("title2");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doc2, doc.documentElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doc.createTextNode("text"), doc.documentElement);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 4.2.1.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
df.appendChild(doc.createElement("b"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.firstChild);
|
||||||
|
});
|
||||||
|
|
||||||
|
df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createTextNode("text"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.firstChild);
|
||||||
|
});
|
||||||
|
|
||||||
|
df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createComment("comment"));
|
||||||
|
df.appendChild(doc.createTextNode("text"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.firstChild);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 4.2.2.
|
||||||
|
test(function() {
|
||||||
|
// The context node has an element child.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.doctype);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.documentElement);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
// /child/ is a doctype.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, doc.doctype);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document and a doctype is following the reference child, inserting a DocumentFragment with an element should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
// /child/ is not null and a doctype is following /child/.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(df, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 4.3.
|
||||||
|
test(function() {
|
||||||
|
// The context node has an element child.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, doc.doctype);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, doc.documentElement);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
// /child/ is a doctype.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, doc.doctype);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
// /child/ is not null and a doctype is following /child/.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(a, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document and a doctype is following the reference child, inserting an element should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 4.4.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, doc.doctype);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, doc.documentElement);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
doc.removeChild(doc.doctype);
|
||||||
|
assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
doc.removeChild(doc.doctype);
|
||||||
|
assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.insertBefore(doctype, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document with and element child, appending a doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 5.
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment();
|
||||||
|
var a = df.appendChild(document.createElement("a"));
|
||||||
|
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.insertBefore(doc, a);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.insertBefore(doc, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.insertBefore(doctype, a);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.insertBefore(doctype, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div");
|
||||||
|
var a = el.appendChild(document.createElement("a"));
|
||||||
|
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.insertBefore(doc, a);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.insertBefore(doc, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.insertBefore(doctype, a);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.insertBefore(doctype, null);
|
||||||
|
});
|
||||||
|
}, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 7.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
a.appendChild(b);
|
||||||
|
a.appendChild(c);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
assert_equals(a.insertBefore(b, b), b);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
assert_equals(a.insertBefore(c, c), c);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
}, "Inserting a node before itself should not move the node");
|
||||||
|
</script>
|
||||||
29
tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html
Normal file
29
tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test of Node.isConnected in a shadow tree</title>
|
||||||
|
<link rel="help" href="https://dom.spec.whatwg.org/#connected">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function testIsConnected(mode) {
|
||||||
|
test(() => {
|
||||||
|
const host = document.createElement("div");
|
||||||
|
document.body.appendChild(host);
|
||||||
|
|
||||||
|
const root = host.attachShadow({ mode });
|
||||||
|
|
||||||
|
const node = document.createElement("div");
|
||||||
|
root.appendChild(node);
|
||||||
|
|
||||||
|
assert_true(node.isConnected);
|
||||||
|
}, `Node.isConnected in a ${mode} shadow tree`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const mode of ["closed", "open"]) {
|
||||||
|
testIsConnected(mode);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
95
tests/wpt/dom/nodes/Node-isConnected.html
Normal file
95
tests/wpt/dom/nodes/Node-isConnected.html
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<head>
|
||||||
|
<title>Node.prototype.isConnected</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-isconnected">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var nodes = [document.createElement("div"),
|
||||||
|
document.createElement("div"),
|
||||||
|
document.createElement("div")];
|
||||||
|
checkNodes([], nodes);
|
||||||
|
|
||||||
|
// Append nodes[0].
|
||||||
|
document.body.appendChild(nodes[0]);
|
||||||
|
checkNodes([nodes[0]],
|
||||||
|
[nodes[1], nodes[2]]);
|
||||||
|
|
||||||
|
// Append nodes[1] and nodes[2] together.
|
||||||
|
nodes[1].appendChild(nodes[2]);
|
||||||
|
checkNodes([nodes[0]],
|
||||||
|
[nodes[1], nodes[2]]);
|
||||||
|
|
||||||
|
nodes[0].appendChild(nodes[1]);
|
||||||
|
checkNodes(nodes, []);
|
||||||
|
|
||||||
|
// Remove nodes[2].
|
||||||
|
nodes[2].remove();
|
||||||
|
checkNodes([nodes[0], nodes[1]],
|
||||||
|
[nodes[2]]);
|
||||||
|
|
||||||
|
// Remove nodes[0] and nodes[1] together.
|
||||||
|
nodes[0].remove();
|
||||||
|
checkNodes([], nodes);
|
||||||
|
}, "Test with ordinary child nodes");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var nodes = [document.createElement("iframe"),
|
||||||
|
document.createElement("iframe"),
|
||||||
|
document.createElement("iframe"),
|
||||||
|
document.createElement("iframe"),
|
||||||
|
document.createElement("div")];
|
||||||
|
var frames = [nodes[0],
|
||||||
|
nodes[1],
|
||||||
|
nodes[2],
|
||||||
|
nodes[3]];
|
||||||
|
checkNodes([], nodes);
|
||||||
|
|
||||||
|
// Since we cannot append anything to the contentWindow of an iframe before it
|
||||||
|
// is appended to the main DOM tree, we append the iframes one after another.
|
||||||
|
document.body.appendChild(nodes[0]);
|
||||||
|
checkNodes([nodes[0]],
|
||||||
|
[nodes[1], nodes[2], nodes[3], nodes[4]]);
|
||||||
|
|
||||||
|
frames[0].contentDocument.body.appendChild(nodes[1]);
|
||||||
|
checkNodes([nodes[0], nodes[1]],
|
||||||
|
[nodes[2], nodes[3], nodes[4]]);
|
||||||
|
|
||||||
|
frames[1].contentDocument.body.appendChild(nodes[2]);
|
||||||
|
checkNodes([nodes[0], nodes[1], nodes[2]],
|
||||||
|
[nodes[3], nodes[4]]);
|
||||||
|
|
||||||
|
frames[2].contentDocument.body.appendChild(nodes[3]);
|
||||||
|
checkNodes([nodes[0], nodes[1], nodes[2], nodes[3]],
|
||||||
|
[nodes[4]]);
|
||||||
|
|
||||||
|
frames[3].contentDocument.body.appendChild(nodes[4]);
|
||||||
|
checkNodes(nodes, []);
|
||||||
|
|
||||||
|
frames[3].remove();
|
||||||
|
// Since node[4] is still under the doument of frame[3], it's still connected.
|
||||||
|
checkNodes([nodes[0], nodes[1], nodes[2], nodes[4]],
|
||||||
|
[nodes[3]]);
|
||||||
|
|
||||||
|
frames[0].remove();
|
||||||
|
// Since node[1] and node[2] are still under the doument of frame[0], they are
|
||||||
|
// still connected.
|
||||||
|
checkNodes([nodes[1], nodes[2], nodes[4]],
|
||||||
|
[nodes[0], nodes[3]]);
|
||||||
|
}, "Test with iframes");
|
||||||
|
|
||||||
|
// This helper function is used to check whether nodes should be connected.
|
||||||
|
function checkNodes(aConnectedNodes, aDisconnectedNodes) {
|
||||||
|
aConnectedNodes.forEach(node => assert_true(node.isConnected));
|
||||||
|
aDisconnectedNodes.forEach(node => assert_false(node.isConnected));
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
1
tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml
Normal file
1
tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<!DOCTYPE foo [ <!ELEMENT foo (#PCDATA)> ]><foo/>
|
||||||
1
tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml
Normal file
1
tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<!DOCTYPE foo [ <!ELEMENT foo EMPTY> ]><foo/>
|
||||||
84
tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml
Normal file
84
tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Node.isEqualNode</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
function testNullHandling(node) {
|
||||||
|
test(function() {
|
||||||
|
assert_false(node.isEqualNode(null))
|
||||||
|
assert_false(node.isEqualNode(undefined))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
[
|
||||||
|
document.createElement("foo"),
|
||||||
|
document.createTextNode("foo"),
|
||||||
|
document.createProcessingInstruction("foo", "bar"),
|
||||||
|
document.createComment("foo"),
|
||||||
|
document,
|
||||||
|
document.implementation.createDocumentType("html", "", ""),
|
||||||
|
document.createDocumentFragment()
|
||||||
|
].forEach(testNullHandling)
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("foo")
|
||||||
|
a.setAttribute("a", "bar")
|
||||||
|
a.setAttribute("b", "baz")
|
||||||
|
var b = document.createElement("foo")
|
||||||
|
b.setAttribute("b", "baz")
|
||||||
|
b.setAttribute("a", "bar")
|
||||||
|
assert_true(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return true when the attributes are in a different order")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElementNS("ns", "prefix:foo")
|
||||||
|
var b = document.createElementNS("ns", "prefix:foo")
|
||||||
|
assert_true(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return true if elements have same namespace, prefix, and local name")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElementNS("ns1", "prefix:foo")
|
||||||
|
var b = document.createElementNS("ns2", "prefix:foo")
|
||||||
|
assert_false(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return false if elements have different namespace")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElementNS("ns", "prefix1:foo")
|
||||||
|
var b = document.createElementNS("ns", "prefix2:foo")
|
||||||
|
assert_false(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return false if elements have different prefix")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElementNS("ns", "prefix:foo1")
|
||||||
|
var b = document.createElementNS("ns", "prefix:foo2")
|
||||||
|
assert_false(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return false if elements have different local name")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("foo")
|
||||||
|
a.setAttributeNS("ns", "x:a", "bar")
|
||||||
|
var b = document.createElement("foo")
|
||||||
|
b.setAttributeNS("ns", "y:a", "bar")
|
||||||
|
assert_true(a.isEqualNode(b))
|
||||||
|
}, "isEqualNode should return true when the attributes have different prefixes")
|
||||||
|
var internalSubset = async_test("isEqualNode should return true when only the internal subsets of DocumentTypes differ.")
|
||||||
|
var wait = 2;
|
||||||
|
function iframeLoaded() {
|
||||||
|
if (!--wait) {
|
||||||
|
internalSubset.step(function() {
|
||||||
|
var doc1 = document.getElementById("subset1").contentDocument
|
||||||
|
var doc2 = document.getElementById("subset2").contentDocument
|
||||||
|
assert_true(doc1.doctype.isEqualNode(doc2.doctype), "doc1.doctype.isEqualNode(doc2.doctype)")
|
||||||
|
assert_true(doc1.isEqualNode(doc2), "doc1.isEqualNode(doc2)")
|
||||||
|
})
|
||||||
|
internalSubset.done()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<iframe id="subset1" onload="iframeLoaded()" src="Node-isEqualNode-iframe1.xml" />
|
||||||
|
<iframe id="subset2" onload="iframeLoaded()" src="Node-isEqualNode-iframe2.xml" />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
161
tests/wpt/dom/nodes/Node-isEqualNode.html
Normal file
161
tests/wpt/dom/nodes/Node-isEqualNode.html
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Node.prototype.isEqualNode</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-isequalnode">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var doctype1 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
|
||||||
|
var doctype2 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
|
||||||
|
var doctype3 = document.implementation.createDocumentType("qualifiedName2", "publicId", "systemId");
|
||||||
|
var doctype4 = document.implementation.createDocumentType("qualifiedName", "publicId2", "systemId");
|
||||||
|
var doctype5 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId3");
|
||||||
|
|
||||||
|
assert_true(doctype1.isEqualNode(doctype1), "self-comparison");
|
||||||
|
assert_true(doctype1.isEqualNode(doctype2), "same properties");
|
||||||
|
assert_false(doctype1.isEqualNode(doctype3), "different name");
|
||||||
|
assert_false(doctype1.isEqualNode(doctype4), "different public ID");
|
||||||
|
assert_false(doctype1.isEqualNode(doctype5), "different system ID");
|
||||||
|
|
||||||
|
}, "doctypes should be compared on name, public ID, and system ID");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var element1 = document.createElementNS("namespace", "prefix:localName");
|
||||||
|
var element2 = document.createElementNS("namespace", "prefix:localName");
|
||||||
|
var element3 = document.createElementNS("namespace2", "prefix:localName");
|
||||||
|
var element4 = document.createElementNS("namespace", "prefix2:localName");
|
||||||
|
var element5 = document.createElementNS("namespace", "prefix:localName2");
|
||||||
|
|
||||||
|
var element6 = document.createElementNS("namespace", "prefix:localName");
|
||||||
|
element6.setAttribute("foo", "bar");
|
||||||
|
|
||||||
|
assert_true(element1.isEqualNode(element1), "self-comparison");
|
||||||
|
assert_true(element1.isEqualNode(element2), "same properties");
|
||||||
|
assert_false(element1.isEqualNode(element3), "different namespace");
|
||||||
|
assert_false(element1.isEqualNode(element4), "different prefix");
|
||||||
|
assert_false(element1.isEqualNode(element5), "different local name");
|
||||||
|
assert_false(element1.isEqualNode(element6), "different number of attributes");
|
||||||
|
|
||||||
|
}, "elements should be compared on namespace, namespace prefix, local name, and number of attributes");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var element1 = document.createElement("element");
|
||||||
|
element1.setAttributeNS("namespace", "prefix:localName", "value");
|
||||||
|
|
||||||
|
var element2 = document.createElement("element");
|
||||||
|
element2.setAttributeNS("namespace", "prefix:localName", "value");
|
||||||
|
|
||||||
|
var element3 = document.createElement("element");
|
||||||
|
element3.setAttributeNS("namespace2", "prefix:localName", "value");
|
||||||
|
|
||||||
|
var element4 = document.createElement("element");
|
||||||
|
element4.setAttributeNS("namespace", "prefix2:localName", "value");
|
||||||
|
|
||||||
|
var element5 = document.createElement("element");
|
||||||
|
element5.setAttributeNS("namespace", "prefix:localName2", "value");
|
||||||
|
|
||||||
|
var element6 = document.createElement("element");
|
||||||
|
element6.setAttributeNS("namespace", "prefix:localName", "value2");
|
||||||
|
|
||||||
|
assert_true(element1.isEqualNode(element1), "self-comparison");
|
||||||
|
assert_true(element1.isEqualNode(element2), "attribute with same properties");
|
||||||
|
assert_false(element1.isEqualNode(element3), "attribute with different namespace");
|
||||||
|
assert_true(element1.isEqualNode(element4), "attribute with different prefix");
|
||||||
|
assert_false(element1.isEqualNode(element5), "attribute with different local name");
|
||||||
|
assert_false(element1.isEqualNode(element6), "attribute with different value");
|
||||||
|
|
||||||
|
}, "elements should be compared on attribute namespace, local name, and value");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var pi1 = document.createProcessingInstruction("target", "data");
|
||||||
|
var pi2 = document.createProcessingInstruction("target", "data");
|
||||||
|
var pi3 = document.createProcessingInstruction("target2", "data");
|
||||||
|
var pi4 = document.createProcessingInstruction("target", "data2");
|
||||||
|
|
||||||
|
assert_true(pi1.isEqualNode(pi1), "self-comparison");
|
||||||
|
assert_true(pi1.isEqualNode(pi2), "same properties");
|
||||||
|
assert_false(pi1.isEqualNode(pi3), "different target");
|
||||||
|
assert_false(pi1.isEqualNode(pi4), "different data");
|
||||||
|
|
||||||
|
}, "processing instructions should be compared on target and data");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var text1 = document.createTextNode("data");
|
||||||
|
var text2 = document.createTextNode("data");
|
||||||
|
var text3 = document.createTextNode("data2");
|
||||||
|
|
||||||
|
assert_true(text1.isEqualNode(text1), "self-comparison");
|
||||||
|
assert_true(text1.isEqualNode(text2), "same properties");
|
||||||
|
assert_false(text1.isEqualNode(text3), "different data");
|
||||||
|
|
||||||
|
}, "text nodes should be compared on data");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var comment1 = document.createComment("data");
|
||||||
|
var comment2 = document.createComment("data");
|
||||||
|
var comment3 = document.createComment("data2");
|
||||||
|
|
||||||
|
assert_true(comment1.isEqualNode(comment1), "self-comparison");
|
||||||
|
assert_true(comment1.isEqualNode(comment2), "same properties");
|
||||||
|
assert_false(comment1.isEqualNode(comment3), "different data");
|
||||||
|
|
||||||
|
}, "comments should be compared on data");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var documentFragment1 = document.createDocumentFragment();
|
||||||
|
var documentFragment2 = document.createDocumentFragment();
|
||||||
|
|
||||||
|
assert_true(documentFragment1.isEqualNode(documentFragment1), "self-comparison");
|
||||||
|
assert_true(documentFragment1.isEqualNode(documentFragment2), "same properties");
|
||||||
|
|
||||||
|
}, "document fragments should not be compared based on properties");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var document1 = document.implementation.createDocument("", "");
|
||||||
|
var document2 = document.implementation.createDocument("", "");
|
||||||
|
|
||||||
|
assert_true(document1.isEqualNode(document1), "self-comparison");
|
||||||
|
assert_true(document1.isEqualNode(document2), "another empty XML document");
|
||||||
|
|
||||||
|
var htmlDoctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
var document3 = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", htmlDoctype);
|
||||||
|
document3.documentElement.appendChild(document3.createElement("head"));
|
||||||
|
document3.documentElement.appendChild(document3.createElement("body"));
|
||||||
|
var document4 = document.implementation.createHTMLDocument();
|
||||||
|
assert_true(document3.isEqualNode(document4), "default HTML documents, created different ways");
|
||||||
|
|
||||||
|
}, "documents should not be compared based on properties");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
testDeepEquality(function() { return document.createElement("foo") });
|
||||||
|
testDeepEquality(function() { return document.createDocumentFragment() });
|
||||||
|
testDeepEquality(function() { return document.implementation.createDocument("", "") });
|
||||||
|
testDeepEquality(function() { return document.implementation.createHTMLDocument() });
|
||||||
|
|
||||||
|
function testDeepEquality(parentFactory) {
|
||||||
|
// Some ad-hoc tests of deep equality
|
||||||
|
|
||||||
|
var parentA = parentFactory();
|
||||||
|
var parentB = parentFactory();
|
||||||
|
|
||||||
|
parentA.appendChild(document.createComment("data"));
|
||||||
|
assert_false(parentA.isEqualNode(parentB));
|
||||||
|
parentB.appendChild(document.createComment("data"));
|
||||||
|
assert_true(parentA.isEqualNode(parentB));
|
||||||
|
}
|
||||||
|
|
||||||
|
}, "node equality testing should test descendant equality too");
|
||||||
|
</script>
|
||||||
111
tests/wpt/dom/nodes/Node-isSameNode.html
Normal file
111
tests/wpt/dom/nodes/Node-isSameNode.html
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Node.prototype.isSameNode</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-issamenode">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var doctype1 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
|
||||||
|
var doctype2 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
|
||||||
|
|
||||||
|
assert_true(doctype1.isSameNode(doctype1), "self-comparison");
|
||||||
|
assert_false(doctype1.isSameNode(doctype2), "same properties");
|
||||||
|
assert_false(doctype1.isSameNode(null), "with null other node");
|
||||||
|
}, "doctypes should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var element1 = document.createElementNS("namespace", "prefix:localName");
|
||||||
|
var element2 = document.createElementNS("namespace", "prefix:localName");
|
||||||
|
|
||||||
|
assert_true(element1.isSameNode(element1), "self-comparison");
|
||||||
|
assert_false(element1.isSameNode(element2), "same properties");
|
||||||
|
assert_false(element1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "elements should be compared on reference (namespaced element)");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var element1 = document.createElement("element");
|
||||||
|
element1.setAttributeNS("namespace", "prefix:localName", "value");
|
||||||
|
|
||||||
|
var element2 = document.createElement("element");
|
||||||
|
element2.setAttributeNS("namespace", "prefix:localName", "value");
|
||||||
|
|
||||||
|
assert_true(element1.isSameNode(element1), "self-comparison");
|
||||||
|
assert_false(element1.isSameNode(element2), "same properties");
|
||||||
|
assert_false(element1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "elements should be compared on reference (namespaced attribute)");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var pi1 = document.createProcessingInstruction("target", "data");
|
||||||
|
var pi2 = document.createProcessingInstruction("target", "data");
|
||||||
|
|
||||||
|
assert_true(pi1.isSameNode(pi1), "self-comparison");
|
||||||
|
assert_false(pi1.isSameNode(pi2), "different target");
|
||||||
|
assert_false(pi1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "processing instructions should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var text1 = document.createTextNode("data");
|
||||||
|
var text2 = document.createTextNode("data");
|
||||||
|
|
||||||
|
assert_true(text1.isSameNode(text1), "self-comparison");
|
||||||
|
assert_false(text1.isSameNode(text2), "same properties");
|
||||||
|
assert_false(text1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "text nodes should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var comment1 = document.createComment("data");
|
||||||
|
var comment2 = document.createComment("data");
|
||||||
|
|
||||||
|
assert_true(comment1.isSameNode(comment1), "self-comparison");
|
||||||
|
assert_false(comment1.isSameNode(comment2), "same properties");
|
||||||
|
assert_false(comment1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "comments should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var documentFragment1 = document.createDocumentFragment();
|
||||||
|
var documentFragment2 = document.createDocumentFragment();
|
||||||
|
|
||||||
|
assert_true(documentFragment1.isSameNode(documentFragment1), "self-comparison");
|
||||||
|
assert_false(documentFragment1.isSameNode(documentFragment2), "same properties");
|
||||||
|
assert_false(documentFragment1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "document fragments should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var document1 = document.implementation.createDocument("", "");
|
||||||
|
var document2 = document.implementation.createDocument("", "");
|
||||||
|
|
||||||
|
assert_true(document1.isSameNode(document1), "self-comparison");
|
||||||
|
assert_false(document1.isSameNode(document2), "another empty XML document");
|
||||||
|
assert_false(document1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "documents should be compared on reference");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
|
||||||
|
var attr1 = document.createAttribute('href');
|
||||||
|
var attr2 = document.createAttribute('href');
|
||||||
|
|
||||||
|
assert_true(attr1.isSameNode(attr1), "self-comparison");
|
||||||
|
assert_false(attr1.isSameNode(attr2), "same name");
|
||||||
|
assert_false(attr1.isSameNode(null), "with null other node");
|
||||||
|
|
||||||
|
}, "attributes should be compared on reference");
|
||||||
|
|
||||||
|
</script>
|
||||||
139
tests/wpt/dom/nodes/Node-lookupNamespaceURI.html
Normal file
139
tests/wpt/dom/nodes/Node-lookupNamespaceURI.html
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>LookupNamespaceURI and IsDefaultNamespace tests</title>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>LookupNamespaceURI and IsDefaultNamespace</h1>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
function lookupNamespaceURI(node, prefix, expected, name) {
|
||||||
|
test(function() {
|
||||||
|
assert_equals(node.lookupNamespaceURI(prefix), expected);
|
||||||
|
}, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDefaultNamespace(node, namespace, expected, name) {
|
||||||
|
test(function() {
|
||||||
|
assert_equals(node.isDefaultNamespace(namespace), expected);
|
||||||
|
}, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var frag = document.createDocumentFragment();
|
||||||
|
lookupNamespaceURI(frag, null, null, 'DocumentFragment should have null namespace, prefix null');
|
||||||
|
lookupNamespaceURI(frag, '', null, 'DocumentFragment should have null namespace, prefix ""');
|
||||||
|
lookupNamespaceURI(frag, 'foo', null, 'DocumentFragment should have null namespace, prefix "foo"');
|
||||||
|
lookupNamespaceURI(frag, 'xml', null, 'DocumentFragment should have null namespace, prefix "xml"');
|
||||||
|
lookupNamespaceURI(frag, 'xmlns', null, 'DocumentFragment should have null namespace, prefix "xmlns"');
|
||||||
|
isDefaultNamespace(frag, null, true, 'DocumentFragment is in default namespace, prefix null');
|
||||||
|
isDefaultNamespace(frag, '', true, 'DocumentFragment is in default namespace, prefix ""');
|
||||||
|
isDefaultNamespace(frag, 'foo', false, 'DocumentFragment is in default namespace, prefix "foo"');
|
||||||
|
isDefaultNamespace(frag, 'xmlns', false, 'DocumentFragment is in default namespace, prefix "xmlns"');
|
||||||
|
|
||||||
|
var docType = document.doctype;
|
||||||
|
lookupNamespaceURI(docType, null, null, 'DocumentType should have null namespace, prefix null');
|
||||||
|
lookupNamespaceURI(docType, '', null, 'DocumentType should have null namespace, prefix ""');
|
||||||
|
lookupNamespaceURI(docType, 'foo', null, 'DocumentType should have null namespace, prefix "foo"');
|
||||||
|
lookupNamespaceURI(docType, 'xml', null, 'DocumentType should have null namespace, prefix "xml"');
|
||||||
|
lookupNamespaceURI(docType, 'xmlns', null, 'DocumentType should have null namespace, prefix "xmlns"');
|
||||||
|
isDefaultNamespace(docType, null, true, 'DocumentType is in default namespace, prefix null');
|
||||||
|
isDefaultNamespace(docType, '', true, 'DocumentType is in default namespace, prefix ""');
|
||||||
|
isDefaultNamespace(docType, 'foo', false, 'DocumentType is in default namespace, prefix "foo"');
|
||||||
|
isDefaultNamespace(docType, 'xmlns', false, 'DocumentType is in default namespace, prefix "xmlns"');
|
||||||
|
|
||||||
|
var fooElem = document.createElementNS('fooNamespace', 'prefix:elem');
|
||||||
|
fooElem.setAttribute('bar', 'value');
|
||||||
|
const XMLNS_NS = 'http://www.w3.org/2000/xmlns/';
|
||||||
|
const XML_NS = 'http://www.w3.org/XML/1998/namespace';
|
||||||
|
lookupNamespaceURI(fooElem, null, null, 'Element should have null namespace, prefix null');
|
||||||
|
lookupNamespaceURI(fooElem, '', null, 'Element should have null namespace, prefix ""');
|
||||||
|
lookupNamespaceURI(fooElem, 'fooNamespace', null, 'Element should not have namespace matching prefix with namespaceURI value');
|
||||||
|
lookupNamespaceURI(fooElem, 'xml', XML_NS, 'Element should have XML namespace');
|
||||||
|
lookupNamespaceURI(fooElem, 'xmlns', XMLNS_NS, 'Element should have XMLNS namespace');
|
||||||
|
lookupNamespaceURI(fooElem, 'prefix', 'fooNamespace', 'Element has namespace URI matching prefix');
|
||||||
|
isDefaultNamespace(fooElem, null, true, 'Empty namespace is not default, prefix null');
|
||||||
|
isDefaultNamespace(fooElem, '', true, 'Empty namespace is not default, prefix ""');
|
||||||
|
isDefaultNamespace(fooElem, 'fooNamespace', false, 'fooNamespace is not default');
|
||||||
|
isDefaultNamespace(fooElem, XMLNS_NS, false, 'xmlns namespace is not default');
|
||||||
|
|
||||||
|
fooElem.setAttributeNS(XMLNS_NS, 'xmlns:bar', 'barURI');
|
||||||
|
fooElem.setAttributeNS(XMLNS_NS, 'xmlns', 'bazURI');
|
||||||
|
|
||||||
|
lookupNamespaceURI(fooElem, null, 'bazURI', 'Element should have baz namespace, prefix null');
|
||||||
|
lookupNamespaceURI(fooElem, '', 'bazURI', 'Element should have baz namespace, prefix ""');
|
||||||
|
lookupNamespaceURI(fooElem, 'xmlns', XMLNS_NS, 'Element should have namespace with xmlns prefix');
|
||||||
|
lookupNamespaceURI(fooElem, 'bar', 'barURI', 'Element has bar namespace');
|
||||||
|
|
||||||
|
isDefaultNamespace(fooElem, null, false, 'Empty namespace is not default on fooElem, prefix null');
|
||||||
|
isDefaultNamespace(fooElem, '', false, 'Empty namespace is not default on fooElem, prefix ""');
|
||||||
|
isDefaultNamespace(fooElem, 'barURI', false, 'bar namespace is not default');
|
||||||
|
isDefaultNamespace(fooElem, 'bazURI', true, 'baz namespace is default');
|
||||||
|
|
||||||
|
var comment = document.createComment('comment');
|
||||||
|
fooElem.appendChild(comment);
|
||||||
|
|
||||||
|
lookupNamespaceURI(comment, null, 'bazURI', 'Comment should inherit baz namespace');
|
||||||
|
lookupNamespaceURI(comment, '', 'bazURI', 'Comment should inherit baz namespace');
|
||||||
|
lookupNamespaceURI(comment, 'prefix', 'fooNamespace', 'Comment should inherit namespace URI matching prefix');
|
||||||
|
lookupNamespaceURI(comment, 'bar', 'barURI', 'Comment should inherit bar namespace');
|
||||||
|
|
||||||
|
isDefaultNamespace(comment, null, false, 'For comment, empty namespace is not default, prefix null');
|
||||||
|
isDefaultNamespace(comment, '', false, 'For comment, empty namespace is not default, prefix ""');
|
||||||
|
isDefaultNamespace(comment, 'fooNamespace', false, 'For comment, fooNamespace is not default');
|
||||||
|
isDefaultNamespace(comment, XMLNS_NS, false, 'For comment, xmlns namespace is not default');
|
||||||
|
isDefaultNamespace(comment, 'barURI', false, 'For comment, inherited bar namespace is not default');
|
||||||
|
isDefaultNamespace(comment, 'bazURI', true, 'For comment, inherited baz namespace is default');
|
||||||
|
|
||||||
|
var fooChild = document.createElementNS('childNamespace', 'childElem');
|
||||||
|
fooElem.appendChild(fooChild);
|
||||||
|
|
||||||
|
lookupNamespaceURI(fooChild, null, 'childNamespace', 'Child element should inherit baz namespace');
|
||||||
|
lookupNamespaceURI(fooChild, '', 'childNamespace', 'Child element should have null namespace');
|
||||||
|
lookupNamespaceURI(fooChild, 'xmlns', XMLNS_NS, 'Child element should have XMLNS namespace');
|
||||||
|
lookupNamespaceURI(fooChild, 'prefix', 'fooNamespace', 'Child element has namespace URI matching prefix');
|
||||||
|
|
||||||
|
isDefaultNamespace(fooChild, null, false, 'Empty namespace is not default for child, prefix null');
|
||||||
|
isDefaultNamespace(fooChild, '', false, 'Empty namespace is not default for child, prefix ""');
|
||||||
|
isDefaultNamespace(fooChild, 'fooNamespace', false, 'fooNamespace is not default for child');
|
||||||
|
isDefaultNamespace(fooChild, XMLNS_NS, false, 'xmlns namespace is not default for child');
|
||||||
|
isDefaultNamespace(fooChild, 'barURI', false, 'bar namespace is not default for child');
|
||||||
|
isDefaultNamespace(fooChild, 'bazURI', false, 'baz namespace is default for child');
|
||||||
|
isDefaultNamespace(fooChild, 'childNamespace', true, 'childNamespace is default for child');
|
||||||
|
|
||||||
|
document.documentElement.setAttributeNS(XMLNS_NS, 'xmlns:bar', 'barURI');
|
||||||
|
document.documentElement.setAttributeNS(XMLNS_NS, 'xmlns', 'bazURI');
|
||||||
|
|
||||||
|
lookupNamespaceURI(document, null, 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace, prefix null');
|
||||||
|
lookupNamespaceURI(document, '', 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace, prefix ""');
|
||||||
|
lookupNamespaceURI(document, 'prefix', null, 'Document has no namespace URI matching prefix');
|
||||||
|
lookupNamespaceURI(document, 'bar', 'barURI', 'Document has bar namespace');
|
||||||
|
|
||||||
|
isDefaultNamespace(document, null, false, 'For document, empty namespace is not default, prefix null');
|
||||||
|
isDefaultNamespace(document, '', false, 'For document, empty namespace is not default, prefix ""');
|
||||||
|
isDefaultNamespace(document, 'fooNamespace', false, 'For document, fooNamespace is not default');
|
||||||
|
isDefaultNamespace(document, XMLNS_NS, false, 'For document, xmlns namespace is not default');
|
||||||
|
isDefaultNamespace(document, 'barURI', false, 'For document, bar namespace is not default');
|
||||||
|
isDefaultNamespace(document, 'bazURI', false, 'For document, baz namespace is not default');
|
||||||
|
isDefaultNamespace(document, 'http://www.w3.org/1999/xhtml', true, 'For document, xhtml namespace is default');
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
lookupNamespaceURI(doc, 'xml', null, 'Document without documentElement has no namespace URI matching "xml"');
|
||||||
|
lookupNamespaceURI(doc, 'xmlns', null, 'Document without documentElement has no namespace URI matching "xmlns"');
|
||||||
|
|
||||||
|
const attr = document.createAttribute('foo');
|
||||||
|
lookupNamespaceURI(attr, 'xml', null, 'Disconnected Attr has no namespace URI matching "xml"');
|
||||||
|
lookupNamespaceURI(attr, 'xmlns', null, 'Disconnected Attr has no namespace URI matching "xmlns"');
|
||||||
|
document.body.setAttributeNode(attr);
|
||||||
|
lookupNamespaceURI(attr, 'xml', XML_NS, 'Connected Attr has namespace URI matching "xml"');
|
||||||
|
lookupNamespaceURI(attr, 'xmlns', XMLNS_NS, 'Connected Attr no namespace URI matching "xmlns"');
|
||||||
|
|
||||||
|
var comment = document.createComment('comment');
|
||||||
|
document.appendChild(comment);
|
||||||
|
lookupNamespaceURI(comment, 'bar', null, 'Comment does not have bar namespace');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
tests/wpt/dom/nodes/Node-lookupPrefix.xhtml
Normal file
31
tests/wpt/dom/nodes/Node-lookupPrefix.xhtml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:x="test">
|
||||||
|
<head>
|
||||||
|
<title>Node.lookupPrefix</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body xmlns:s="test">
|
||||||
|
<div id="log"/>
|
||||||
|
<x xmlns:t="test"><!--comment--><?test test?>TEST<x/></x>
|
||||||
|
<script>
|
||||||
|
function lookupPrefix(node, ns, prefix) {
|
||||||
|
test(function() {
|
||||||
|
assert_equals(node.lookupPrefix(ns), prefix)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var x = document.getElementsByTagName("x")[0];
|
||||||
|
lookupPrefix(document, "test", "x") // XXX add test for when there is no documentElement
|
||||||
|
lookupPrefix(document, null, null)
|
||||||
|
lookupPrefix(x, "http://www.w3.org/1999/xhtml", null)
|
||||||
|
lookupPrefix(x, "something", null)
|
||||||
|
lookupPrefix(x, null, null)
|
||||||
|
lookupPrefix(x, "test", "t")
|
||||||
|
lookupPrefix(x.parentNode, "test", "s")
|
||||||
|
lookupPrefix(x.firstChild, "test", "t")
|
||||||
|
lookupPrefix(x.childNodes[1], "test", "t")
|
||||||
|
lookupPrefix(x.childNodes[2], "test", "t")
|
||||||
|
lookupPrefix(x.lastChild, "test", "t")
|
||||||
|
x.parentNode.removeChild(x)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
23
tests/wpt/dom/nodes/Node-mutation-adoptNode.html
Normal file
23
tests/wpt/dom/nodes/Node-mutation-adoptNode.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node-manipulation-adopted</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#mutation-algorithms">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const old = document.implementation.createHTMLDocument("");
|
||||||
|
const div = old.createElement("div");
|
||||||
|
div.appendChild(old.createTextNode("text"));
|
||||||
|
assert_equals(div.ownerDocument, old);
|
||||||
|
assert_equals(div.firstChild.ownerDocument, old);
|
||||||
|
document.body.appendChild(div);
|
||||||
|
assert_equals(div.ownerDocument, document);
|
||||||
|
assert_equals(div.firstChild.ownerDocument, document);
|
||||||
|
}, "simple append of foreign div with text");
|
||||||
|
|
||||||
|
</script>
|
||||||
42
tests/wpt/dom/nodes/Node-nodeName-xhtml.xhtml
Normal file
42
tests/wpt/dom/nodes/Node-nodeName-xhtml.xhtml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Node.nodeName</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
var HTMLNS = "http://www.w3.org/1999/xhtml",
|
||||||
|
SVGNS = "http://www.w3.org/2000/svg"
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "I").nodeName, "I")
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "i").nodeName, "i")
|
||||||
|
assert_equals(document.createElementNS(SVGNS, "svg").nodeName, "svg")
|
||||||
|
assert_equals(document.createElementNS(SVGNS, "SVG").nodeName, "SVG")
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "x:b").nodeName, "x:b")
|
||||||
|
}, "For Element nodes, nodeName should return the same as tagName.")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createTextNode("foo").nodeName, "#text")
|
||||||
|
}, "For Text nodes, nodeName should return \"#text\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createProcessingInstruction("foo", "bar").nodeName,
|
||||||
|
"foo")
|
||||||
|
}, "For ProcessingInstruction nodes, nodeName should return the target.")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createComment("foo").nodeName, "#comment")
|
||||||
|
}, "For Comment nodes, nodeName should return \"#comment\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.nodeName, "#document")
|
||||||
|
}, "For Document nodes, nodeName should return \"#document\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.doctype.nodeName, "html")
|
||||||
|
}, "For DocumentType nodes, nodeName should return the name.")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createDocumentFragment().nodeName,
|
||||||
|
"#document-fragment")
|
||||||
|
}, "For DocumentFragment nodes, nodeName should return \"#document-fragment\".")
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
32
tests/wpt/dom/nodes/Node-nodeName.html
Normal file
32
tests/wpt/dom/nodes/Node-nodeName.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.nodeName</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
var HTMLNS = "http://www.w3.org/1999/xhtml",
|
||||||
|
SVGNS = "http://www.w3.org/2000/svg"
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "I").nodeName, "I")
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "i").nodeName, "I")
|
||||||
|
assert_equals(document.createElementNS(SVGNS, "svg").nodeName, "svg")
|
||||||
|
assert_equals(document.createElementNS(SVGNS, "SVG").nodeName, "SVG")
|
||||||
|
assert_equals(document.createElementNS(HTMLNS, "x:b").nodeName, "X:B")
|
||||||
|
}, "For Element nodes, nodeName should return the same as tagName.")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createTextNode("foo").nodeName, "#text")
|
||||||
|
}, "For Text nodes, nodeName should return \"#text\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createComment("foo").nodeName, "#comment")
|
||||||
|
}, "For Comment nodes, nodeName should return \"#comment\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.nodeName, "#document")
|
||||||
|
}, "For Document nodes, nodeName should return \"#document\".")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.doctype.nodeName, "html")
|
||||||
|
}, "For DocumentType nodes, nodeName should return the name.")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createDocumentFragment().nodeName,
|
||||||
|
"#document-fragment")
|
||||||
|
}, "For DocumentFragment nodes, nodeName should return \"#document-fragment\".")
|
||||||
|
</script>
|
||||||
71
tests/wpt/dom/nodes/Node-nodeValue.html
Normal file
71
tests/wpt/dom/nodes/Node-nodeValue.html
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.nodeValue</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-nodevalue">
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
var the_text = document.createTextNode("A span!");
|
||||||
|
assert_equals(the_text.nodeValue, "A span!");
|
||||||
|
assert_equals(the_text.data, "A span!");
|
||||||
|
the_text.nodeValue = "test again";
|
||||||
|
assert_equals(the_text.nodeValue, "test again");
|
||||||
|
assert_equals(the_text.data, "test again");
|
||||||
|
the_text.nodeValue = null;
|
||||||
|
assert_equals(the_text.nodeValue, "");
|
||||||
|
assert_equals(the_text.data, "");
|
||||||
|
}, "Text.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var the_comment = document.createComment("A comment!");
|
||||||
|
assert_equals(the_comment.nodeValue, "A comment!");
|
||||||
|
assert_equals(the_comment.data, "A comment!");
|
||||||
|
the_comment.nodeValue = "test again";
|
||||||
|
assert_equals(the_comment.nodeValue, "test again");
|
||||||
|
assert_equals(the_comment.data, "test again");
|
||||||
|
the_comment.nodeValue = null;
|
||||||
|
assert_equals(the_comment.nodeValue, "");
|
||||||
|
assert_equals(the_comment.data, "");
|
||||||
|
}, "Comment.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var the_pi = document.createProcessingInstruction("pi", "A PI!");
|
||||||
|
assert_equals(the_pi.nodeValue, "A PI!");
|
||||||
|
assert_equals(the_pi.data, "A PI!");
|
||||||
|
the_pi.nodeValue = "test again";
|
||||||
|
assert_equals(the_pi.nodeValue, "test again");
|
||||||
|
assert_equals(the_pi.data, "test again");
|
||||||
|
the_pi.nodeValue = null;
|
||||||
|
assert_equals(the_pi.nodeValue, "");
|
||||||
|
assert_equals(the_pi.data, "");
|
||||||
|
}, "ProcessingInstruction.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var the_link = document.createElement("a");
|
||||||
|
assert_equals(the_link.nodeValue, null);
|
||||||
|
the_link.nodeValue = "foo";
|
||||||
|
assert_equals(the_link.nodeValue, null);
|
||||||
|
}, "Element.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.nodeValue, null);
|
||||||
|
document.nodeValue = "foo";
|
||||||
|
assert_equals(document.nodeValue, null);
|
||||||
|
}, "Document.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var the_frag = document.createDocumentFragment();
|
||||||
|
assert_equals(the_frag.nodeValue, null);
|
||||||
|
the_frag.nodeValue = "foo";
|
||||||
|
assert_equals(the_frag.nodeValue, null);
|
||||||
|
}, "DocumentFragment.nodeValue");
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var the_doctype = document.doctype;
|
||||||
|
assert_equals(the_doctype.nodeValue, null);
|
||||||
|
the_doctype.nodeValue = "foo";
|
||||||
|
assert_equals(the_doctype.nodeValue, null);
|
||||||
|
}, "DocumentType.nodeValue");
|
||||||
|
</script>
|
||||||
83
tests/wpt/dom/nodes/Node-normalize.html
Normal file
83
tests/wpt/dom/nodes/Node-normalize.html
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.normalize()</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment(),
|
||||||
|
t1 = document.createTextNode("1"),
|
||||||
|
t2 = document.createTextNode("2"),
|
||||||
|
t3 = document.createTextNode("3"),
|
||||||
|
t4 = document.createTextNode("4")
|
||||||
|
df.appendChild(t1)
|
||||||
|
df.appendChild(t2)
|
||||||
|
assert_equals(df.childNodes.length, 2)
|
||||||
|
assert_equals(df.textContent, "12")
|
||||||
|
var el = document.createElement('x')
|
||||||
|
df.appendChild(el)
|
||||||
|
el.appendChild(t3)
|
||||||
|
el.appendChild(t4)
|
||||||
|
document.normalize()
|
||||||
|
assert_equals(el.childNodes.length, 2)
|
||||||
|
assert_equals(el.textContent, "34")
|
||||||
|
assert_equals(df.childNodes.length, 3)
|
||||||
|
assert_equals(t1.data, "1")
|
||||||
|
df.normalize()
|
||||||
|
assert_equals(df.childNodes.length, 2)
|
||||||
|
assert_equals(df.firstChild, t1)
|
||||||
|
assert_equals(t1.data, "12")
|
||||||
|
assert_equals(t2.data, "2")
|
||||||
|
assert_equals(el.firstChild, t3)
|
||||||
|
assert_equals(t3.data, "34")
|
||||||
|
assert_equals(t4.data, "4")
|
||||||
|
})
|
||||||
|
|
||||||
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=19837
|
||||||
|
test(function() {
|
||||||
|
var div = document.createElement("div")
|
||||||
|
var t1 = div.appendChild(document.createTextNode(""))
|
||||||
|
var t2 = div.appendChild(document.createTextNode("a"))
|
||||||
|
var t3 = div.appendChild(document.createTextNode(""))
|
||||||
|
assert_array_equals(div.childNodes, [t1, t2, t3])
|
||||||
|
div.normalize();
|
||||||
|
assert_array_equals(div.childNodes, [t2])
|
||||||
|
}, "Empty text nodes separated by a non-empty text node")
|
||||||
|
test(function() {
|
||||||
|
var div = document.createElement("div")
|
||||||
|
var t1 = div.appendChild(document.createTextNode(""))
|
||||||
|
var t2 = div.appendChild(document.createTextNode(""))
|
||||||
|
assert_array_equals(div.childNodes, [t1, t2])
|
||||||
|
div.normalize();
|
||||||
|
assert_array_equals(div.childNodes, [])
|
||||||
|
}, "Empty text nodes")
|
||||||
|
|
||||||
|
// The specification for normalize is clear that only "exclusive Text
|
||||||
|
// nodes" are to be modified. This excludes CDATASection nodes, which
|
||||||
|
// derive from Text. Naïve implementations may fail to skip
|
||||||
|
// CDATASection nodes, or even worse, try to test textContent or
|
||||||
|
// nodeValue without taking care to check the node type. They will
|
||||||
|
// fail this test.
|
||||||
|
test(function() {
|
||||||
|
// We create an XML document so that we can create CDATASection.
|
||||||
|
// Except for the CDATASection the result should be the same for
|
||||||
|
// an HTML document. (No non-Text node should be touched.)
|
||||||
|
var doc = new DOMParser().parseFromString("<div/>", "text/xml")
|
||||||
|
var div = doc.documentElement
|
||||||
|
var t1 = div.appendChild(doc.createTextNode("a"))
|
||||||
|
// The first parameter is the "target" of the processing
|
||||||
|
// instruction, and the 2nd is the text content.
|
||||||
|
var t2 = div.appendChild(doc.createProcessingInstruction("pi", ""))
|
||||||
|
var t3 = div.appendChild(doc.createTextNode("b"))
|
||||||
|
var t4 = div.appendChild(doc.createCDATASection(""))
|
||||||
|
var t5 = div.appendChild(doc.createTextNode("c"))
|
||||||
|
var t6 = div.appendChild(doc.createComment(""))
|
||||||
|
var t7 = div.appendChild(doc.createTextNode("d"))
|
||||||
|
var t8 = div.appendChild(doc.createElement("el"))
|
||||||
|
var t9 = div.appendChild(doc.createTextNode("e"))
|
||||||
|
var expected = [t1, t2, t3, t4, t5, t6, t7, t8, t9]
|
||||||
|
assert_array_equals(div.childNodes, expected)
|
||||||
|
div.normalize()
|
||||||
|
assert_array_equals(div.childNodes, expected)
|
||||||
|
}, "Non-text nodes with empty textContent values.")
|
||||||
|
</script>
|
||||||
82
tests/wpt/dom/nodes/Node-parentElement.html
Normal file
82
tests/wpt/dom/nodes/Node-parentElement.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.parentElement</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.parentElement, null)
|
||||||
|
}, "When the parent is null, parentElement should be null")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.doctype.parentElement, null)
|
||||||
|
}, "When the parent is a document, parentElement should be null (doctype)")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.documentElement.parentElement, null)
|
||||||
|
}, "When the parent is a document, parentElement should be null (element)")
|
||||||
|
test(function() {
|
||||||
|
var comment = document.appendChild(document.createComment("foo"))
|
||||||
|
assert_equals(comment.parentElement, null)
|
||||||
|
}, "When the parent is a document, parentElement should be null (comment)")
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
assert_equals(df.parentElement, null)
|
||||||
|
var el = document.createElement("div")
|
||||||
|
assert_equals(el.parentElement, null)
|
||||||
|
df.appendChild(el)
|
||||||
|
assert_equals(el.parentNode, df)
|
||||||
|
assert_equals(el.parentElement, null)
|
||||||
|
}, "parentElement should return null for children of DocumentFragments (element)")
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
assert_equals(df.parentElement, null)
|
||||||
|
var text = document.createTextNode("bar")
|
||||||
|
assert_equals(text.parentElement, null)
|
||||||
|
df.appendChild(text)
|
||||||
|
assert_equals(text.parentNode, df)
|
||||||
|
assert_equals(text.parentElement, null)
|
||||||
|
}, "parentElement should return null for children of DocumentFragments (text)")
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
var parent = document.createElement("div")
|
||||||
|
df.appendChild(parent)
|
||||||
|
var el = document.createElement("div")
|
||||||
|
assert_equals(el.parentElement, null)
|
||||||
|
parent.appendChild(el)
|
||||||
|
assert_equals(el.parentElement, parent)
|
||||||
|
}, "parentElement should work correctly with DocumentFragments (element)")
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
var parent = document.createElement("div")
|
||||||
|
df.appendChild(parent)
|
||||||
|
var text = document.createTextNode("bar")
|
||||||
|
assert_equals(text.parentElement, null)
|
||||||
|
parent.appendChild(text)
|
||||||
|
assert_equals(text.parentElement, parent)
|
||||||
|
}, "parentElement should work correctly with DocumentFragments (text)")
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement("div")
|
||||||
|
var el = document.createElement("div")
|
||||||
|
assert_equals(el.parentElement, null)
|
||||||
|
parent.appendChild(el)
|
||||||
|
assert_equals(el.parentElement, parent)
|
||||||
|
}, "parentElement should work correctly in disconnected subtrees (element)")
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement("div")
|
||||||
|
var text = document.createTextNode("bar")
|
||||||
|
assert_equals(text.parentElement, null)
|
||||||
|
parent.appendChild(text)
|
||||||
|
assert_equals(text.parentElement, parent)
|
||||||
|
}, "parentElement should work correctly in disconnected subtrees (text)")
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
assert_equals(el.parentElement, null)
|
||||||
|
document.body.appendChild(el)
|
||||||
|
assert_equals(el.parentElement, document.body)
|
||||||
|
}, "parentElement should work correctly in a document (element)")
|
||||||
|
test(function() {
|
||||||
|
var text = document.createElement("div")
|
||||||
|
assert_equals(text.parentElement, null)
|
||||||
|
document.body.appendChild(text)
|
||||||
|
assert_equals(text.parentElement, document.body)
|
||||||
|
}, "parentElement should work correctly in a document (text)")
|
||||||
|
</script>
|
||||||
1
tests/wpt/dom/nodes/Node-parentNode-iframe.html
Normal file
1
tests/wpt/dom/nodes/Node-parentNode-iframe.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<a name='c'>c</a>
|
||||||
33
tests/wpt/dom/nodes/Node-parentNode.html
Normal file
33
tests/wpt/dom/nodes/Node-parentNode.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.parentNode</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
// XXX need to test for more node types
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.parentNode, null)
|
||||||
|
}, "Document")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.doctype.parentNode, document)
|
||||||
|
}, "Doctype")
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.documentElement.parentNode, document)
|
||||||
|
}, "Root element")
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
assert_equals(el.parentNode, null)
|
||||||
|
document.body.appendChild(el)
|
||||||
|
assert_equals(el.parentNode, document.body)
|
||||||
|
}, "Element")
|
||||||
|
var t = async_test("Removed iframe");
|
||||||
|
function testIframe(iframe) {
|
||||||
|
t.step(function() {
|
||||||
|
var doc = iframe.contentDocument;
|
||||||
|
iframe.parentNode.removeChild(iframe);
|
||||||
|
assert_equals(doc.firstChild.parentNode, doc);
|
||||||
|
});
|
||||||
|
t.done();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<iframe id=a src="Node-parentNode-iframe.html" onload="testIframe(this)"></iframe>
|
||||||
688
tests/wpt/dom/nodes/Node-properties.html
Normal file
688
tests/wpt/dom/nodes/Node-properties.html
Normal file
@@ -0,0 +1,688 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<title>Node assorted property tests</title>
|
||||||
|
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<div id=log></div>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<script src=../common.js></script>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
/**
|
||||||
|
* First we define a data structure to tell us what tests to run. The keys
|
||||||
|
* will be eval()ed, and are mostly global variables defined in common.js. The
|
||||||
|
* values are objects, which maps properties to expected values. So
|
||||||
|
*
|
||||||
|
* foo: {
|
||||||
|
* bar: "baz",
|
||||||
|
* quz: 7,
|
||||||
|
* },
|
||||||
|
*
|
||||||
|
* will test that eval("foo.bar") === "baz" and eval("foo.quz") === 7. "foo"
|
||||||
|
* and "bar" could thus be expressions, like "document.documentElement" and
|
||||||
|
* "childNodes[4]" respectively.
|
||||||
|
*
|
||||||
|
* To avoid repetition, some values are automatically added based on others.
|
||||||
|
* For instance, if we specify nodeType: Node.TEXT_NODE, we'll automatically
|
||||||
|
* also test nodeName: "#text". This is handled by code after this variable is
|
||||||
|
* defined.
|
||||||
|
*/
|
||||||
|
var expected = {
|
||||||
|
testDiv: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: document.body,
|
||||||
|
parentElement: document.body,
|
||||||
|
"childNodes.length": 6,
|
||||||
|
"childNodes[0]": paras[0],
|
||||||
|
"childNodes[1]": paras[1],
|
||||||
|
"childNodes[2]": paras[2],
|
||||||
|
"childNodes[3]": paras[3],
|
||||||
|
"childNodes[4]": paras[4],
|
||||||
|
"childNodes[5]": comment,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: document.getElementById("log"),
|
||||||
|
textContent: "A\u0308b\u0308c\u0308d\u0308e\u0308f\u0308g\u0308h\u0308\nIjklmnop\nQrstuvwxYzabcdefGhijklmn",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "div",
|
||||||
|
tagName: "DIV",
|
||||||
|
id: "test",
|
||||||
|
"children[0]": paras[0],
|
||||||
|
"children[1]": paras[1],
|
||||||
|
"children[2]": paras[2],
|
||||||
|
"children[3]": paras[3],
|
||||||
|
"children[4]": paras[4],
|
||||||
|
previousElementSibling: null,
|
||||||
|
// nextSibling isn't explicitly set
|
||||||
|
//nextElementSibling: ,
|
||||||
|
childElementCount: 5,
|
||||||
|
},
|
||||||
|
detachedDiv: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
"childNodes.length": 2,
|
||||||
|
"childNodes[0]": detachedPara1,
|
||||||
|
"childNodes[1]": detachedPara2,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
textContent: "OpqrstuvWxyzabcd",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "div",
|
||||||
|
tagName: "DIV",
|
||||||
|
"children[0]": detachedPara1,
|
||||||
|
"children[1]": detachedPara2,
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 2,
|
||||||
|
},
|
||||||
|
detachedPara1: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: detachedDiv,
|
||||||
|
parentElement: detachedDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: detachedPara2,
|
||||||
|
textContent: "Opqrstuv",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: detachedPara2,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
detachedPara2: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: detachedDiv,
|
||||||
|
parentElement: detachedDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: detachedPara1,
|
||||||
|
nextSibling: null,
|
||||||
|
textContent: "Wxyzabcd",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
previousElementSibling: detachedPara1,
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
document: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_NODE,
|
||||||
|
"childNodes.length": 2,
|
||||||
|
"childNodes[0]": document.doctype,
|
||||||
|
"childNodes[1]": document.documentElement,
|
||||||
|
|
||||||
|
// Document
|
||||||
|
URL: String(location),
|
||||||
|
compatMode: "CSS1Compat",
|
||||||
|
characterSet: "UTF-8",
|
||||||
|
contentType: "text/html",
|
||||||
|
doctype: doctype,
|
||||||
|
//documentElement: ,
|
||||||
|
},
|
||||||
|
foreignDoc: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_NODE,
|
||||||
|
"childNodes.length": 3,
|
||||||
|
"childNodes[0]": foreignDoc.doctype,
|
||||||
|
"childNodes[1]": foreignDoc.documentElement,
|
||||||
|
"childNodes[2]": foreignComment,
|
||||||
|
|
||||||
|
// Document
|
||||||
|
URL: "about:blank",
|
||||||
|
compatMode: "CSS1Compat",
|
||||||
|
characterSet: "UTF-8",
|
||||||
|
contentType: "text/html",
|
||||||
|
//doctype: ,
|
||||||
|
//documentElement: ,
|
||||||
|
},
|
||||||
|
foreignPara1: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: foreignDoc.body,
|
||||||
|
parentElement: foreignDoc.body,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: foreignPara2,
|
||||||
|
textContent: "Efghijkl",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: foreignPara2,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
foreignPara2: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: foreignDoc.body,
|
||||||
|
parentElement: foreignDoc.body,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: foreignPara1,
|
||||||
|
nextSibling: foreignTextNode,
|
||||||
|
textContent: "Mnopqrst",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
previousElementSibling: foreignPara1,
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
xmlDoc: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_NODE,
|
||||||
|
"childNodes.length": 4,
|
||||||
|
"childNodes[0]": xmlDoctype,
|
||||||
|
"childNodes[1]": xmlElement,
|
||||||
|
"childNodes[2]": processingInstruction,
|
||||||
|
"childNodes[3]": xmlComment,
|
||||||
|
|
||||||
|
// Document
|
||||||
|
URL: "about:blank",
|
||||||
|
compatMode: "CSS1Compat",
|
||||||
|
characterSet: "UTF-8",
|
||||||
|
contentType: "application/xml",
|
||||||
|
//doctype: ,
|
||||||
|
//documentElement: ,
|
||||||
|
},
|
||||||
|
xmlElement: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: xmlDoc,
|
||||||
|
parentElement: null,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
"childNodes[0]": xmlTextNode,
|
||||||
|
previousSibling: xmlDoctype,
|
||||||
|
nextSibling: processingInstruction,
|
||||||
|
textContent: "do re mi fa so la ti",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: null,
|
||||||
|
prefix: null,
|
||||||
|
localName: "igiveuponcreativenames",
|
||||||
|
tagName: "igiveuponcreativenames",
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
detachedXmlElement: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
"childNodes.length": 0,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
textContent: "",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: null,
|
||||||
|
prefix: null,
|
||||||
|
localName: "everyone-hates-hyphenated-element-names",
|
||||||
|
tagName: "everyone-hates-hyphenated-element-names",
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
detachedTextNode: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.TEXT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "Uvwxyzab",
|
||||||
|
|
||||||
|
// Text
|
||||||
|
wholeText: "Uvwxyzab",
|
||||||
|
},
|
||||||
|
foreignTextNode: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.TEXT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: foreignDoc.body,
|
||||||
|
parentElement: foreignDoc.body,
|
||||||
|
previousSibling: foreignPara2,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "I admit that I harbor doubts about whether we really need so many things to test, but it's too late to stop now.",
|
||||||
|
|
||||||
|
// Text
|
||||||
|
wholeText: "I admit that I harbor doubts about whether we really need so many things to test, but it's too late to stop now.",
|
||||||
|
},
|
||||||
|
detachedForeignTextNode: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.TEXT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "Cdefghij",
|
||||||
|
|
||||||
|
// Text
|
||||||
|
wholeText: "Cdefghij",
|
||||||
|
},
|
||||||
|
xmlTextNode: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.TEXT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: xmlElement,
|
||||||
|
parentElement: xmlElement,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "do re mi fa so la ti",
|
||||||
|
|
||||||
|
// Text
|
||||||
|
wholeText: "do re mi fa so la ti",
|
||||||
|
},
|
||||||
|
detachedXmlTextNode: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.TEXT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "Klmnopqr",
|
||||||
|
|
||||||
|
// Text
|
||||||
|
wholeText: "Klmnopqr",
|
||||||
|
},
|
||||||
|
processingInstruction: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.PROCESSING_INSTRUCTION_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: xmlDoc,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: xmlElement,
|
||||||
|
nextSibling: xmlComment,
|
||||||
|
nodeValue: 'Did you know that ":syn sync fromstart" is very useful when using vim to edit large amounts of JavaScript embedded in HTML?',
|
||||||
|
|
||||||
|
// ProcessingInstruction
|
||||||
|
target: "somePI",
|
||||||
|
},
|
||||||
|
detachedProcessingInstruction: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.PROCESSING_INSTRUCTION_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "chirp chirp chirp",
|
||||||
|
|
||||||
|
// ProcessingInstruction
|
||||||
|
target: "whippoorwill",
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
previousSibling: paras[4],
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "Alphabet soup?",
|
||||||
|
},
|
||||||
|
detachedComment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "Stuvwxyz",
|
||||||
|
},
|
||||||
|
foreignComment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: foreignDoc,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: foreignDoc.documentElement,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: '"Commenter" and "commentator" mean different things. I\'ve seen non-native speakers trip up on this.',
|
||||||
|
},
|
||||||
|
detachedForeignComment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "אריה יהודה",
|
||||||
|
},
|
||||||
|
xmlComment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: xmlDoc,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: processingInstruction,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "I maliciously created a comment that will break incautious XML serializers, but Firefox threw an exception, so all I got was this lousy T-shirt",
|
||||||
|
},
|
||||||
|
detachedXmlComment: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.COMMENT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: null,
|
||||||
|
parentElement: null,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: null,
|
||||||
|
nodeValue: "בן חיים אליעזר",
|
||||||
|
},
|
||||||
|
docfrag: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_FRAGMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
"childNodes.length": 0,
|
||||||
|
textContent: "",
|
||||||
|
},
|
||||||
|
foreignDocfrag: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_FRAGMENT_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
"childNodes.length": 0,
|
||||||
|
textContent: "",
|
||||||
|
},
|
||||||
|
xmlDocfrag: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_FRAGMENT_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
"childNodes.length": 0,
|
||||||
|
textContent: "",
|
||||||
|
},
|
||||||
|
doctype: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_TYPE_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: document,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: document.documentElement,
|
||||||
|
|
||||||
|
// DocumentType
|
||||||
|
name: "html",
|
||||||
|
publicId: "",
|
||||||
|
systemId: "",
|
||||||
|
},
|
||||||
|
foreignDoctype: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_TYPE_NODE,
|
||||||
|
ownerDocument: foreignDoc,
|
||||||
|
parentNode: foreignDoc,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: foreignDoc.documentElement,
|
||||||
|
|
||||||
|
// DocumentType
|
||||||
|
name: "html",
|
||||||
|
publicId: "",
|
||||||
|
systemId: "",
|
||||||
|
},
|
||||||
|
xmlDoctype: {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.DOCUMENT_TYPE_NODE,
|
||||||
|
ownerDocument: xmlDoc,
|
||||||
|
parentNode: xmlDoc,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: xmlElement,
|
||||||
|
|
||||||
|
// DocumentType
|
||||||
|
name: "qorflesnorf",
|
||||||
|
publicId: "abcde",
|
||||||
|
systemId: "x\"'y",
|
||||||
|
},
|
||||||
|
"paras[0]": {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: null,
|
||||||
|
nextSibling: paras[1],
|
||||||
|
textContent: "A\u0308b\u0308c\u0308d\u0308e\u0308f\u0308g\u0308h\u0308\n",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
id: "a",
|
||||||
|
previousElementSibling: null,
|
||||||
|
nextElementSibling: paras[1],
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
"paras[1]": {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: paras[0],
|
||||||
|
nextSibling: paras[2],
|
||||||
|
textContent: "Ijklmnop\n",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
id: "b",
|
||||||
|
previousElementSibling: paras[0],
|
||||||
|
nextElementSibling: paras[2],
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
"paras[2]": {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: paras[1],
|
||||||
|
nextSibling: paras[3],
|
||||||
|
textContent: "Qrstuvwx",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
id: "c",
|
||||||
|
previousElementSibling: paras[1],
|
||||||
|
nextElementSibling: paras[3],
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
"paras[3]": {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: paras[2],
|
||||||
|
nextSibling: paras[4],
|
||||||
|
textContent: "Yzabcdef",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
id: "d",
|
||||||
|
previousElementSibling: paras[2],
|
||||||
|
nextElementSibling: paras[4],
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
"paras[4]": {
|
||||||
|
// Node
|
||||||
|
nodeType: Node.ELEMENT_NODE,
|
||||||
|
ownerDocument: document,
|
||||||
|
parentNode: testDiv,
|
||||||
|
parentElement: testDiv,
|
||||||
|
"childNodes.length": 1,
|
||||||
|
previousSibling: paras[3],
|
||||||
|
nextSibling: comment,
|
||||||
|
textContent: "Ghijklmn",
|
||||||
|
|
||||||
|
// Element
|
||||||
|
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||||
|
prefix: null,
|
||||||
|
localName: "p",
|
||||||
|
tagName: "P",
|
||||||
|
id: "e",
|
||||||
|
previousElementSibling: paras[3],
|
||||||
|
nextElementSibling: null,
|
||||||
|
childElementCount: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var node in expected) {
|
||||||
|
// Now we set various default values by node type.
|
||||||
|
switch (expected[node].nodeType) {
|
||||||
|
case Node.ELEMENT_NODE:
|
||||||
|
expected[node].nodeName = expected[node].tagName;
|
||||||
|
expected[node].nodeValue = null;
|
||||||
|
expected[node]["children.length"] = expected[node].childElementCount;
|
||||||
|
|
||||||
|
if (expected[node].id === undefined) {
|
||||||
|
expected[node].id = "";
|
||||||
|
}
|
||||||
|
if (expected[node].className === undefined) {
|
||||||
|
expected[node].className = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
var len = expected[node].childElementCount;
|
||||||
|
if (len === 0) {
|
||||||
|
expected[node].firstElementChild =
|
||||||
|
expected[node].lastElementChild = null;
|
||||||
|
} else {
|
||||||
|
// If we have expectations for the first/last child in children,
|
||||||
|
// use those. Otherwise, at least check that .firstElementChild ==
|
||||||
|
// .children[0] and .lastElementChild == .children[len - 1], even
|
||||||
|
// if we aren't sure what they should be.
|
||||||
|
expected[node].firstElementChild = expected[node]["children[0]"]
|
||||||
|
? expected[node]["children[0]"]
|
||||||
|
: eval(node).children[0];
|
||||||
|
expected[node].lastElementChild =
|
||||||
|
expected[node]["children[" + (len - 1) + "]"]
|
||||||
|
? expected[node]["children[" + (len - 1) + "]"]
|
||||||
|
: eval(node).children[len - 1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
expected[node].nodeName = "#text";
|
||||||
|
expected[node]["childNodes.length"] = 0;
|
||||||
|
expected[node].textContent = expected[node].data =
|
||||||
|
expected[node].nodeValue;
|
||||||
|
expected[node].length = expected[node].nodeValue.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||||
|
expected[node].nodeName = expected[node].target;
|
||||||
|
expected[node]["childNodes.length"] = 0;
|
||||||
|
expected[node].textContent = expected[node].data =
|
||||||
|
expected[node].nodeValue;
|
||||||
|
expected[node].length = expected[node].nodeValue.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.COMMENT_NODE:
|
||||||
|
expected[node].nodeName = "#comment";
|
||||||
|
expected[node]["childNodes.length"] = 0;
|
||||||
|
expected[node].textContent = expected[node].data =
|
||||||
|
expected[node].nodeValue;
|
||||||
|
expected[node].length = expected[node].nodeValue.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.DOCUMENT_NODE:
|
||||||
|
expected[node].nodeName = "#document";
|
||||||
|
expected[node].ownerDocument = expected[node].parentNode =
|
||||||
|
expected[node].parentElement = expected[node].previousSibling =
|
||||||
|
expected[node].nextSibling = expected[node].nodeValue =
|
||||||
|
expected[node].textContent = null;
|
||||||
|
expected[node].documentURI = expected[node].URL;
|
||||||
|
expected[node].charset = expected[node].inputEncoding =
|
||||||
|
expected[node].characterSet;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.DOCUMENT_TYPE_NODE:
|
||||||
|
expected[node].nodeName = expected[node].name;
|
||||||
|
expected[node]["childNodes.length"] = 0;
|
||||||
|
expected[node].parentElement = expected[node].nodeValue =
|
||||||
|
expected[node].textContent = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Node.DOCUMENT_FRAGMENT_NODE:
|
||||||
|
expected[node].nodeName = "#document-fragment";
|
||||||
|
expected[node].parentNode = expected[node].parentElement =
|
||||||
|
expected[node].previousSibling = expected[node].nextSibling =
|
||||||
|
expected[node].nodeValue = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we set some further default values that are independent of node
|
||||||
|
// type.
|
||||||
|
var len = expected[node]["childNodes.length"];
|
||||||
|
if (len === 0) {
|
||||||
|
expected[node].firstChild = expected[node].lastChild = null;
|
||||||
|
} else {
|
||||||
|
// If we have expectations for the first/last child in childNodes, use
|
||||||
|
// those. Otherwise, at least check that .firstChild == .childNodes[0]
|
||||||
|
// and .lastChild == .childNodes[len - 1], even if we aren't sure what
|
||||||
|
// they should be.
|
||||||
|
expected[node].firstChild = expected[node]["childNodes[0]"]
|
||||||
|
? expected[node]["childNodes[0]"]
|
||||||
|
: eval(node).childNodes[0];
|
||||||
|
expected[node].lastChild =
|
||||||
|
expected[node]["childNodes[" + (len - 1) + "]"]
|
||||||
|
? expected[node]["childNodes[" + (len - 1) + "]"]
|
||||||
|
: eval(node).childNodes[len - 1];
|
||||||
|
}
|
||||||
|
expected[node]["hasChildNodes()"] = !!expected[node]["childNodes.length"];
|
||||||
|
|
||||||
|
// Finally, we test!
|
||||||
|
for (var prop in expected[node]) {
|
||||||
|
test(function() {
|
||||||
|
assert_equals(eval(node + "." + prop), expected[node][prop]);
|
||||||
|
}, node + "." + prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testDiv.parentNode.removeChild(testDiv);
|
||||||
|
</script>
|
||||||
58
tests/wpt/dom/nodes/Node-removeChild.html.skip
Normal file
58
tests/wpt/dom/nodes/Node-removeChild.html.skip
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Node.removeChild</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="creators.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<iframe src=about:blank></iframe>
|
||||||
|
<script>
|
||||||
|
var documents = [
|
||||||
|
[function() { return document }, "the main document"],
|
||||||
|
[function() { return frames[0].document }, "a frame document"],
|
||||||
|
[function() { return document.implementation.createHTMLDocument() },
|
||||||
|
"a synthetic document"],
|
||||||
|
];
|
||||||
|
|
||||||
|
documents.forEach(function(d) {
|
||||||
|
var get = d[0], description = d[1]
|
||||||
|
for (var p in creators) {
|
||||||
|
var creator = creators[p];
|
||||||
|
test(function() {
|
||||||
|
var doc = get();
|
||||||
|
var s = doc[creator]("a")
|
||||||
|
assert_equals(s.ownerDocument, doc)
|
||||||
|
assert_throws_dom("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
|
||||||
|
assert_equals(s.ownerDocument, doc)
|
||||||
|
}, "Passing a detached " + p + " from " + description +
|
||||||
|
" to removeChild should not affect it.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var doc = get();
|
||||||
|
var s = doc[creator]("b")
|
||||||
|
doc.documentElement.appendChild(s)
|
||||||
|
assert_equals(s.ownerDocument, doc)
|
||||||
|
assert_throws_dom("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
|
||||||
|
assert_equals(s.ownerDocument, doc)
|
||||||
|
}, "Passing a non-detached " + p + " from " + description +
|
||||||
|
" to removeChild should not affect it.")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var doc = get();
|
||||||
|
var s = doc[creator]("test")
|
||||||
|
doc.body.appendChild(s)
|
||||||
|
assert_equals(s.ownerDocument, doc)
|
||||||
|
assert_throws_dom(
|
||||||
|
"NOT_FOUND_ERR",
|
||||||
|
(doc.defaultView || self).DOMException,
|
||||||
|
function() { s.removeChild(doc) }
|
||||||
|
);
|
||||||
|
}, "Calling removeChild on a " + p + " from " + description +
|
||||||
|
" with no children should throw NOT_FOUND_ERR.")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_throws_js(TypeError, function() { document.body.removeChild(null) })
|
||||||
|
assert_throws_js(TypeError, function() { document.body.removeChild({'a':'b'}) })
|
||||||
|
}, "Passing a value that is not a Node reference to removeChild should throw TypeError.")
|
||||||
|
</script>
|
||||||
349
tests/wpt/dom/nodes/Node-replaceChild.html
Normal file
349
tests/wpt/dom/nodes/Node-replaceChild.html
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.replaceChild</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<body><a><b></b><c></c></a>
|
||||||
|
<div id="log"></div>
|
||||||
|
<!-- First test shared pre-insertion checks that work similarly for replaceChild
|
||||||
|
and insertBefore -->
|
||||||
|
<script>
|
||||||
|
var insertFunc = Node.prototype.replaceChild;
|
||||||
|
</script>
|
||||||
|
<script src="pre-insertion-validation-notfound.js"></script>
|
||||||
|
<script>
|
||||||
|
// IDL.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
assert_throws_js(TypeError, function() {
|
||||||
|
a.replaceChild(null, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = document.createElement("div");
|
||||||
|
assert_throws_js(TypeError, function() {
|
||||||
|
a.replaceChild(b, null);
|
||||||
|
});
|
||||||
|
assert_throws_js(TypeError, function() {
|
||||||
|
a.replaceChild(null, b);
|
||||||
|
});
|
||||||
|
}, "Passing null to replaceChild should throw a TypeError.")
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
assert_throws_dom("NotFoundError", function() {
|
||||||
|
a.replaceChild(b, c);
|
||||||
|
});
|
||||||
|
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.appendChild(b);
|
||||||
|
assert_throws_dom("NotFoundError", function() {
|
||||||
|
a.replaceChild(b, c);
|
||||||
|
});
|
||||||
|
assert_throws_dom("NotFoundError", function() {
|
||||||
|
a.replaceChild(b, a);
|
||||||
|
});
|
||||||
|
}, "If child's parent is not the context node, a NotFoundError exception should be thrown");
|
||||||
|
|
||||||
|
// Step 1.
|
||||||
|
test(function() {
|
||||||
|
var nodes = getNonParentNodes();
|
||||||
|
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
node.replaceChild(a, b);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "If the context node is not a node that can contain children, a HierarchyRequestError exception should be thrown")
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
a.replaceChild(a, a);
|
||||||
|
});
|
||||||
|
|
||||||
|
a.appendChild(b);
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
a.replaceChild(a, b);
|
||||||
|
});
|
||||||
|
|
||||||
|
var c = document.createElement("div");
|
||||||
|
c.appendChild(a);
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
a.replaceChild(c, b);
|
||||||
|
});
|
||||||
|
}, "If node is an inclusive ancestor of the context node, a HierarchyRequestError should be thrown.")
|
||||||
|
|
||||||
|
// Steps 4/5.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var doc2 = document.implementation.createHTMLDocument("title2");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(doc2, doc.documentElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(doc.createTextNode("text"), doc.documentElement);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 6.1.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
df.appendChild(doc.createElement("b"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, doc.documentElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createTextNode("text"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, doc.documentElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createComment("comment"));
|
||||||
|
df.appendChild(doc.createTextNode("text"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, doc.documentElement);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
df.appendChild(doc.createElement("b"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, doc.doctype);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document (without element children), inserting a DocumentFragment that contains multiple elements should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 6.1.
|
||||||
|
test(function() {
|
||||||
|
// The context node has an element child that is not /child/.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, doc.doctype);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
// A doctype is following /child/.
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
df.appendChild(doc.createElement("a"));
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(df, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 6.2.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(a, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(a, doc.doctype);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
doc.removeChild(doc.documentElement);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype]);
|
||||||
|
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(a, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 6.3.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
|
||||||
|
assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(doctype, comment);
|
||||||
|
});
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(doctype, doc.documentElement);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var comment = doc.appendChild(doc.createComment("foo"));
|
||||||
|
doc.removeChild(doc.doctype);
|
||||||
|
assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
doc.replaceChild(doctype, comment);
|
||||||
|
});
|
||||||
|
}, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Steps 4/5.
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment();
|
||||||
|
var a = df.appendChild(document.createElement("a"));
|
||||||
|
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.replaceChild(doc, a);
|
||||||
|
});
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
df.replaceChild(doctype, a);
|
||||||
|
});
|
||||||
|
}, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div");
|
||||||
|
var a = el.appendChild(document.createElement("a"));
|
||||||
|
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.replaceChild(doc, a);
|
||||||
|
});
|
||||||
|
|
||||||
|
var doctype = document.implementation.createDocumentType("html", "", "");
|
||||||
|
assert_throws_dom("HierarchyRequestError", function() {
|
||||||
|
el.replaceChild(doctype, a);
|
||||||
|
});
|
||||||
|
}, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
|
||||||
|
|
||||||
|
// Step 6.
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
a.appendChild(b);
|
||||||
|
a.appendChild(c);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
assert_equals(a.replaceChild(c, b), b);
|
||||||
|
assert_array_equals(a.childNodes, [c]);
|
||||||
|
}, "Replacing a node with its next sibling should work (2 children)");
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
var d = document.createElement("div");
|
||||||
|
var e = document.createElement("div");
|
||||||
|
a.appendChild(b);
|
||||||
|
a.appendChild(c);
|
||||||
|
a.appendChild(d);
|
||||||
|
a.appendChild(e);
|
||||||
|
assert_array_equals(a.childNodes, [b, c, d, e]);
|
||||||
|
assert_equals(a.replaceChild(d, c), c);
|
||||||
|
assert_array_equals(a.childNodes, [b, d, e]);
|
||||||
|
}, "Replacing a node with its next sibling should work (4 children)");
|
||||||
|
test(function() {
|
||||||
|
var a = document.createElement("div");
|
||||||
|
var b = document.createElement("div");
|
||||||
|
var c = document.createElement("div");
|
||||||
|
a.appendChild(b);
|
||||||
|
a.appendChild(c);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
assert_equals(a.replaceChild(b, b), b);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
assert_equals(a.replaceChild(c, c), c);
|
||||||
|
assert_array_equals(a.childNodes, [b, c]);
|
||||||
|
}, "Replacing a node with itself should not move the node");
|
||||||
|
|
||||||
|
// Step 7.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var doctype = doc.doctype;
|
||||||
|
assert_array_equals(doc.childNodes, [doctype, doc.documentElement]);
|
||||||
|
|
||||||
|
var doc2 = document.implementation.createHTMLDocument("title2");
|
||||||
|
var doctype2 = doc2.doctype;
|
||||||
|
assert_array_equals(doc2.childNodes, [doctype2, doc2.documentElement]);
|
||||||
|
|
||||||
|
doc.replaceChild(doc2.doctype, doc.doctype);
|
||||||
|
assert_array_equals(doc.childNodes, [doctype2, doc.documentElement]);
|
||||||
|
assert_array_equals(doc2.childNodes, [doc2.documentElement]);
|
||||||
|
assert_equals(doctype.parentNode, null);
|
||||||
|
assert_equals(doctype.ownerDocument, doc);
|
||||||
|
assert_equals(doctype2.parentNode, doc);
|
||||||
|
assert_equals(doctype2.ownerDocument, doc);
|
||||||
|
}, "If the context node is a document, inserting a new doctype should work.")
|
||||||
|
|
||||||
|
// Bugs.
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
var a = df.appendChild(doc.createElement("a"));
|
||||||
|
assert_equals(doc.documentElement, doc.replaceChild(df, doc.documentElement));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, a]);
|
||||||
|
}, "Replacing the document element with a DocumentFragment containing a single element should work.");
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var df = doc.createDocumentFragment();
|
||||||
|
var a = df.appendChild(doc.createComment("a"));
|
||||||
|
var b = df.appendChild(doc.createElement("b"));
|
||||||
|
var c = df.appendChild(doc.createComment("c"));
|
||||||
|
assert_equals(doc.documentElement, doc.replaceChild(df, doc.documentElement));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, a, b, c]);
|
||||||
|
}, "Replacing the document element with a DocumentFragment containing a single element and comments should work.");
|
||||||
|
test(function() {
|
||||||
|
var doc = document.implementation.createHTMLDocument("title");
|
||||||
|
var a = doc.createElement("a");
|
||||||
|
assert_equals(doc.documentElement, doc.replaceChild(a, doc.documentElement));
|
||||||
|
assert_array_equals(doc.childNodes, [doc.doctype, a]);
|
||||||
|
}, "Replacing the document element with a single element should work.");
|
||||||
|
test(function() {
|
||||||
|
document.addEventListener("DOMNodeRemoved", function(e) {
|
||||||
|
document.body.appendChild(document.createElement("x"));
|
||||||
|
}, false);
|
||||||
|
var a = document.body.firstChild, b = a.firstChild, c = b.nextSibling;
|
||||||
|
assert_equals(a.replaceChild(c, b), b);
|
||||||
|
assert_equals(b.parentNode, null);
|
||||||
|
assert_equals(a.firstChild, c);
|
||||||
|
assert_equals(c.parentNode, a);
|
||||||
|
}, "replaceChild should work in the presence of mutation events.")
|
||||||
|
test(function() {
|
||||||
|
var TEST_ID = "findme";
|
||||||
|
var gBody = document.getElementsByTagName("body")[0];
|
||||||
|
var parent = document.createElement("div");
|
||||||
|
gBody.appendChild(parent);
|
||||||
|
var child = document.createElement("div");
|
||||||
|
parent.appendChild(child);
|
||||||
|
var df = document.createDocumentFragment();
|
||||||
|
var fragChild = df.appendChild(document.createElement("div"));
|
||||||
|
fragChild.setAttribute("id", TEST_ID);
|
||||||
|
parent.replaceChild(df, child);
|
||||||
|
assert_equals(document.getElementById(TEST_ID), fragChild, "should not be null");
|
||||||
|
}, "Replacing an element with a DocumentFragment should allow a child of the DocumentFragment to be found by Id.")
|
||||||
|
|
||||||
|
</script>
|
||||||
265
tests/wpt/dom/nodes/Node-textContent.html
Normal file
265
tests/wpt/dom/nodes/Node-textContent.html
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Node.textContent</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
// XXX mutation observers?
|
||||||
|
// XXX Range gravitation?
|
||||||
|
|
||||||
|
var documents, doctypes;
|
||||||
|
setup(function() {
|
||||||
|
documents = [
|
||||||
|
[document, "parser"],
|
||||||
|
[document.implementation.createDocument("", "test", null), "createDocument"],
|
||||||
|
[document.implementation.createHTMLDocument("title"), "createHTMLDocument"],
|
||||||
|
]
|
||||||
|
doctypes = [
|
||||||
|
[document.doctype, "parser"],
|
||||||
|
[document.implementation.createDocumentType("x", "", ""), "script"],
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// Getting
|
||||||
|
// DocumentFragment, Element:
|
||||||
|
test(function() {
|
||||||
|
var element = document.createElement("div")
|
||||||
|
assert_equals(element.textContent, "")
|
||||||
|
}, "For an empty Element, textContent should be the empty string")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createDocumentFragment().textContent, "")
|
||||||
|
}, "For an empty DocumentFragment, textContent should be the empty string")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
el.appendChild(document.createComment(" abc "))
|
||||||
|
el.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
el.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
assert_equals(el.textContent, "\tDEF\t")
|
||||||
|
}, "Element with children")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
var child = document.createElement("div")
|
||||||
|
el.appendChild(child)
|
||||||
|
child.appendChild(document.createComment(" abc "))
|
||||||
|
child.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
child.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
assert_equals(el.textContent, "\tDEF\t")
|
||||||
|
}, "Element with descendants")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
df.appendChild(document.createComment(" abc "))
|
||||||
|
df.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
df.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
assert_equals(df.textContent, "\tDEF\t")
|
||||||
|
}, "DocumentFragment with children")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
var child = document.createElement("div")
|
||||||
|
df.appendChild(child)
|
||||||
|
child.appendChild(document.createComment(" abc "))
|
||||||
|
child.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
child.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
assert_equals(df.textContent, "\tDEF\t")
|
||||||
|
}, "DocumentFragment with descendants")
|
||||||
|
|
||||||
|
// Text, ProcessingInstruction, Comment:
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createTextNode("").textContent, "")
|
||||||
|
}, "For an empty Text, textContent should be the empty string")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createProcessingInstruction("x", "").textContent, "")
|
||||||
|
}, "For an empty ProcessingInstruction, textContent should be the empty string")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createComment("").textContent, "")
|
||||||
|
}, "For an empty Comment, textContent should be the empty string")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createTextNode("abc").textContent, "abc")
|
||||||
|
}, "For a Text with data, textContent should be that data")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createProcessingInstruction("x", "abc").textContent,
|
||||||
|
"abc")
|
||||||
|
}, "For a ProcessingInstruction with data, textContent should be that data")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
assert_equals(document.createComment("abc").textContent, "abc")
|
||||||
|
}, "For a Comment with data, textContent should be that data")
|
||||||
|
|
||||||
|
// Any other node:
|
||||||
|
documents.forEach(function(argument) {
|
||||||
|
var doc = argument[0], creator = argument[1]
|
||||||
|
test(function() {
|
||||||
|
assert_equals(doc.textContent, null)
|
||||||
|
}, "For Documents created by " + creator + ", textContent should be null")
|
||||||
|
})
|
||||||
|
|
||||||
|
doctypes.forEach(function(argument) {
|
||||||
|
var doctype = argument[0], creator = argument[1]
|
||||||
|
test(function() {
|
||||||
|
assert_equals(doctype.textContent, null)
|
||||||
|
}, "For DocumentType created by " + creator + ", textContent should be null")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Setting
|
||||||
|
// DocumentFragment, Element:
|
||||||
|
var testArgs = [
|
||||||
|
[null, null],
|
||||||
|
[undefined, null],
|
||||||
|
["", null],
|
||||||
|
[42, "42"],
|
||||||
|
["abc", "abc"],
|
||||||
|
["<b>xyz<\/b>", "<b>xyz<\/b>"],
|
||||||
|
["d\0e", "d\0e"]
|
||||||
|
// XXX unpaired surrogate?
|
||||||
|
]
|
||||||
|
testArgs.forEach(function(aValue) {
|
||||||
|
var argument = aValue[0], expectation = aValue[1]
|
||||||
|
var check = function(aElementOrDocumentFragment) {
|
||||||
|
if (expectation === null) {
|
||||||
|
assert_equals(aElementOrDocumentFragment.textContent, "")
|
||||||
|
assert_equals(aElementOrDocumentFragment.firstChild, null)
|
||||||
|
} else {
|
||||||
|
assert_equals(aElementOrDocumentFragment.textContent, expectation)
|
||||||
|
assert_equals(aElementOrDocumentFragment.childNodes.length, 1,
|
||||||
|
"Should have one child")
|
||||||
|
var firstChild = aElementOrDocumentFragment.firstChild
|
||||||
|
assert_true(firstChild instanceof Text, "child should be a Text")
|
||||||
|
assert_equals(firstChild.data, expectation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
el.textContent = argument
|
||||||
|
check(el)
|
||||||
|
}, "Element without children set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
var text = el.appendChild(document.createTextNode(""))
|
||||||
|
el.textContent = argument
|
||||||
|
check(el)
|
||||||
|
assert_equals(text.parentNode, null,
|
||||||
|
"Preexisting Text should have been removed")
|
||||||
|
}, "Element with empty text node as child set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
el.appendChild(document.createComment(" abc "))
|
||||||
|
el.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
el.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
el.textContent = argument
|
||||||
|
check(el)
|
||||||
|
}, "Element with children set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var el = document.createElement("div")
|
||||||
|
var child = document.createElement("div")
|
||||||
|
el.appendChild(child)
|
||||||
|
child.appendChild(document.createComment(" abc "))
|
||||||
|
child.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
child.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
el.textContent = argument
|
||||||
|
check(el)
|
||||||
|
assert_equals(child.childNodes.length, 3,
|
||||||
|
"Should not have changed the internal structure of the removed nodes.")
|
||||||
|
}, "Element with descendants set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
df.textContent = argument
|
||||||
|
check(df)
|
||||||
|
}, "DocumentFragment without children set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
var text = df.appendChild(document.createTextNode(""))
|
||||||
|
df.textContent = argument
|
||||||
|
check(df)
|
||||||
|
assert_equals(text.parentNode, null,
|
||||||
|
"Preexisting Text should have been removed")
|
||||||
|
}, "DocumentFragment with empty text node as child set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
df.appendChild(document.createComment(" abc "))
|
||||||
|
df.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
df.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
df.textContent = argument
|
||||||
|
check(df)
|
||||||
|
}, "DocumentFragment with children set to " + format_value(argument))
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var df = document.createDocumentFragment()
|
||||||
|
var child = document.createElement("div")
|
||||||
|
df.appendChild(child)
|
||||||
|
child.appendChild(document.createComment(" abc "))
|
||||||
|
child.appendChild(document.createTextNode("\tDEF\t"))
|
||||||
|
child.appendChild(document.createProcessingInstruction("x", " ghi "))
|
||||||
|
df.textContent = argument
|
||||||
|
check(df)
|
||||||
|
assert_equals(child.childNodes.length, 3,
|
||||||
|
"Should not have changed the internal structure of the removed nodes.")
|
||||||
|
}, "DocumentFragment with descendants set to " + format_value(argument))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Text, ProcessingInstruction, Comment:
|
||||||
|
test(function() {
|
||||||
|
var text = document.createTextNode("abc")
|
||||||
|
text.textContent = "def"
|
||||||
|
assert_equals(text.textContent, "def")
|
||||||
|
assert_equals(text.data, "def")
|
||||||
|
}, "For a Text, textContent should set the data")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var pi = document.createProcessingInstruction("x", "abc")
|
||||||
|
pi.textContent = "def"
|
||||||
|
assert_equals(pi.textContent, "def")
|
||||||
|
assert_equals(pi.data, "def")
|
||||||
|
assert_equals(pi.target, "x")
|
||||||
|
}, "For a ProcessingInstruction, textContent should set the data")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var comment = document.createComment("abc")
|
||||||
|
comment.textContent = "def"
|
||||||
|
assert_equals(comment.textContent, "def")
|
||||||
|
assert_equals(comment.data, "def")
|
||||||
|
}, "For a Comment, textContent should set the data")
|
||||||
|
|
||||||
|
// Any other node:
|
||||||
|
documents.forEach(function(argument) {
|
||||||
|
var doc = argument[0], creator = argument[1]
|
||||||
|
test(function() {
|
||||||
|
var root = doc.documentElement
|
||||||
|
doc.textContent = "a"
|
||||||
|
assert_equals(doc.textContent, null)
|
||||||
|
assert_equals(doc.documentElement, root)
|
||||||
|
}, "For Documents created by " + creator + ", setting textContent should do nothing")
|
||||||
|
})
|
||||||
|
|
||||||
|
doctypes.forEach(function(argument) {
|
||||||
|
var doctype = argument[0], creator = argument[1]
|
||||||
|
test(function() {
|
||||||
|
var props = {
|
||||||
|
name: doctype.name,
|
||||||
|
publicId: doctype.publicId,
|
||||||
|
systemId: doctype.systemId,
|
||||||
|
}
|
||||||
|
doctype.textContent = "b"
|
||||||
|
assert_equals(doctype.textContent, null)
|
||||||
|
assert_equals(doctype.name, props.name, "name should not change")
|
||||||
|
assert_equals(doctype.publicId, props.publicId, "publicId should not change")
|
||||||
|
assert_equals(doctype.systemId, props.systemId, "systemId should not change")
|
||||||
|
}, "For DocumentType created by " + creator + ", setting textContent should do nothing")
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
53
tests/wpt/dom/nodes/append-on-Document.html
Normal file
53
tests/wpt/dom/nodes/append-on-Document.html
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>DocumentType.append</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-append">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function test_append_on_Document() {
|
||||||
|
|
||||||
|
var node = document.implementation.createDocument(null, null);
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
parent.append();
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() without any argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.append(x);
|
||||||
|
assert_array_equals(parent.childNodes, [x]);
|
||||||
|
}, 'Document.append() with only one element as an argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(x);
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append(y); });
|
||||||
|
assert_array_equals(parent.childNodes, [x]);
|
||||||
|
}, 'Document.append() with only one element as an argument, on a Document having one child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append('text'); });
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() with text as an argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append(x, y); });
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() with two elements as the argument, on a Document having no child.');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
test_append_on_Document();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
11
tests/wpt/failure.html.skip
Normal file
11
tests/wpt/failure.html.skip
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Failure</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
assert_true(false);
|
||||||
|
}, "failure")
|
||||||
|
</script>
|
||||||
|
|
||||||
4941
tests/wpt/resources/testharness.js
Normal file
4941
tests/wpt/resources/testharness.js
Normal file
File diff suppressed because it is too large
Load Diff
34
tests/wpt/resources/testharnessreport.js
Normal file
34
tests/wpt/resources/testharnessreport.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Prepare a report object containeing all tests results.
|
||||||
|
* https://wpt-docs.readthedocs.io/en/latest/_writing-tests/testharness-api.html#callback-api
|
||||||
|
*/
|
||||||
|
var report = {
|
||||||
|
status: "",
|
||||||
|
log: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
add_completion_callback(function (tests, status) {
|
||||||
|
// report the tests global status.
|
||||||
|
// TODO the status.status is always OK even if a test fail.
|
||||||
|
// I ingore the global status for now, but I build one with the tests results.
|
||||||
|
//report.status = status.status;
|
||||||
|
|
||||||
|
var status = "Pass";
|
||||||
|
// report a log with details per test.
|
||||||
|
var log = "";
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
const test = tests[i];
|
||||||
|
log += test.name+": "+test.format_status();
|
||||||
|
if (test.message != null) {
|
||||||
|
log += " " + test.message;
|
||||||
|
}
|
||||||
|
log += "\n";
|
||||||
|
|
||||||
|
if (test.status !== 0) {
|
||||||
|
status = test.format_status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report.log = log;
|
||||||
|
report.status = status;
|
||||||
|
});
|
||||||
10
tests/wpt/success.html
Normal file
10
tests/wpt/success.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Success</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
assert_true(true);
|
||||||
|
}, "success")
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user