mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
migrate to htmlRunne (plus zig fmt)
This commit is contained in:
@@ -316,20 +316,4 @@ pub const Document = struct {
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser: DOM.Document" {
|
||||
try testing.htmlRunner("dom/document.html");
|
||||
|
||||
// const Case = testing.JsRunner.Case;
|
||||
// const tags = comptime parser.Tag.all();
|
||||
// var createElements: [(tags.len) * 2]Case = undefined;
|
||||
// inline for (tags, 0..) |tag, i| {
|
||||
// const tag_name = @tagName(tag);
|
||||
// createElements[i * 2] = Case{
|
||||
// "var " ++ tag_name ++ "Elem = document.createElement('" ++ tag_name ++ "')",
|
||||
// "undefined",
|
||||
// };
|
||||
// createElements[(i * 2) + 1] = Case{
|
||||
// tag_name ++ "Elem.localName",
|
||||
// tag_name,
|
||||
// };
|
||||
// }
|
||||
// try runner.testCases(&createElements, .{});
|
||||
}
|
||||
|
||||
@@ -91,41 +91,6 @@ pub const DocumentFragment = struct {
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser.DOM.DocumentFragment" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||
defer runner.deinit();
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const dc = new DocumentFragment()", "undefined" },
|
||||
.{ "dc.constructor.name", "DocumentFragment" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const dc1 = new DocumentFragment()", "undefined" },
|
||||
.{ "const dc2 = new DocumentFragment()", "undefined" },
|
||||
.{ "dc1.isEqualNode(dc1)", "true" },
|
||||
.{ "dc1.isEqualNode(dc2)", "true" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let f = document.createDocumentFragment()", null },
|
||||
.{ "let d = document.createElement('div');", null },
|
||||
.{ "d.childElementCount", "0" },
|
||||
|
||||
.{ "d.id = 'x';", null },
|
||||
.{ "document.getElementById('x') == null;", "true" },
|
||||
.{ "f.append(d);", null },
|
||||
.{ "f.childElementCount", "1" },
|
||||
.{ "f.children[0].id", "x" },
|
||||
.{ "document.getElementById('x') == null;", "true" },
|
||||
|
||||
.{ "document.getElementsByTagName('body')[0].append(f.cloneNode(true));", null },
|
||||
.{ "document.getElementById('x') != null;", "true" },
|
||||
|
||||
.{ "document.querySelector('.hello')", "null" },
|
||||
.{ "document.querySelectorAll('.hello').length", "0" },
|
||||
|
||||
.{ "document.querySelector('#x').id", "x" },
|
||||
.{ "document.querySelectorAll('#x')[0].id", "x" },
|
||||
}, .{});
|
||||
test "Browser: DOM.DocumentFragment" {
|
||||
try testing.htmlRunner("dom/document_fragment.html");
|
||||
}
|
||||
|
||||
@@ -62,19 +62,6 @@ pub const DocumentType = struct {
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser.DOM.DocumentType" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||
defer runner.deinit();
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let dt1 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');", "undefined" },
|
||||
.{ "let dt2 = document.implementation.createDocumentType('qname2', 'pid2', 'sys2');", "undefined" },
|
||||
.{ "let dt3 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');", "undefined" },
|
||||
.{ "dt1.isEqualNode(dt1)", "true" },
|
||||
.{ "dt1.isEqualNode(dt3)", "true" },
|
||||
.{ "dt1.isEqualNode(dt2)", "false" },
|
||||
.{ "dt2.isEqualNode(dt3)", "false" },
|
||||
.{ "dt1.isEqualNode(document)", "false" },
|
||||
.{ "document.isEqualNode(dt1)", "false" },
|
||||
}, .{});
|
||||
test "Browser: DOM.DocumentType" {
|
||||
try testing.htmlRunner("dom/document_type.html");
|
||||
}
|
||||
|
||||
@@ -36,12 +36,6 @@ pub const DOMParser = struct {
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser.DOM.DOMParser" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||
defer runner.deinit();
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const dp = new DOMParser()", "undefined" },
|
||||
.{ "dp.parseFromString('<div>abc</div>', 'text/html')", "[object HTMLDocument]" },
|
||||
}, .{});
|
||||
test "Browser: DOM.Parser" {
|
||||
try testing.htmlRunner("dom/dom_parser.html");
|
||||
}
|
||||
|
||||
@@ -593,277 +593,6 @@ pub const Element = struct {
|
||||
// -----
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser.DOM.Element" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||
defer runner.deinit();
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let g = document.getElementById('content')", "undefined" },
|
||||
.{ "g.namespaceURI", "http://www.w3.org/1999/xhtml" },
|
||||
.{ "g.prefix", "null" },
|
||||
.{ "g.localName", "div" },
|
||||
.{ "g.tagName", "DIV" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let gs = document.getElementById('content')", "undefined" },
|
||||
.{ "gs.id", "content" },
|
||||
.{ "gs.id = 'foo'", "foo" },
|
||||
.{ "gs.id", "foo" },
|
||||
.{ "gs.id = 'content'", "content" },
|
||||
.{ "gs.className", "" },
|
||||
.{ "let gs2 = document.getElementById('para-empty')", "undefined" },
|
||||
.{ "gs2.className", "ok empty" },
|
||||
.{ "gs2.className = 'foo bar baz'", "foo bar baz" },
|
||||
.{ "gs2.className", "foo bar baz" },
|
||||
.{ "gs2.className = 'ok empty'", "ok empty" },
|
||||
.{ "let cl = gs2.classList", "undefined" },
|
||||
.{ "cl.length", "2" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const el2 = document.createElement('div');", "undefined" },
|
||||
.{ "el2.id = 'closest'; el2.className = 'ok';", "ok" },
|
||||
.{ "el2.closest('#closest')", "[object HTMLDivElement]" },
|
||||
.{ "el2.closest('.ok')", "[object HTMLDivElement]" },
|
||||
.{ "el2.closest('#9000')", "null" },
|
||||
.{ "el2.closest('.notok')", "null" },
|
||||
|
||||
.{ "const sp = document.createElement('span');", "undefined" },
|
||||
.{ "el2.appendChild(sp);", "[object HTMLSpanElement]" },
|
||||
.{ "sp.closest('#closest')", "[object HTMLDivElement]" },
|
||||
.{ "sp.closest('#9000')", "null" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let a = document.getElementById('content')", "undefined" },
|
||||
.{ "a.hasAttributes()", "true" },
|
||||
.{ "a.attributes.length", "1" },
|
||||
.{ "a.getAttributeNames()", "id" },
|
||||
.{ "a.getAttribute('id')", "content" },
|
||||
.{ "a.attributes['id'].value", "content" },
|
||||
.{
|
||||
\\ let x = '';
|
||||
\\ for (const attr of a.attributes) {
|
||||
\\ x += attr.name + '=' + attr.value;
|
||||
\\ }
|
||||
\\ x;
|
||||
,
|
||||
"id=content",
|
||||
},
|
||||
|
||||
.{ "a.hasAttribute('foo')", "false" },
|
||||
.{ "a.getAttribute('foo')", "null" },
|
||||
|
||||
.{ "a.setAttribute('foo', 'bar')", "undefined" },
|
||||
.{ "a.hasAttribute('foo')", "true" },
|
||||
.{ "a.getAttribute('foo')", "bar" },
|
||||
.{ "a.getAttributeNames()", "id,foo" },
|
||||
.{ " try { a.setAttribute('.foo', 'invalid') } catch (e) { e }", "Error: InvalidCharacterError" },
|
||||
|
||||
.{ "a.setAttribute('foo', 'baz')", "undefined" },
|
||||
.{ "a.hasAttribute('foo')", "true" },
|
||||
.{ "a.getAttribute('foo')", "baz" },
|
||||
|
||||
.{ "a.removeAttribute('foo')", "undefined" },
|
||||
.{ "a.hasAttribute('foo')", "false" },
|
||||
.{ "a.getAttribute('foo')", "null" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let b = document.getElementById('content')", "undefined" },
|
||||
.{ "b.toggleAttribute('foo')", "true" },
|
||||
.{ "b.hasAttribute('foo')", "true" },
|
||||
.{ "b.getAttribute('foo')", "" },
|
||||
|
||||
.{ "b.toggleAttribute('foo')", "false" },
|
||||
.{ "b.hasAttribute('foo')", "false" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let c = document.getElementById('content')", "undefined" },
|
||||
.{ "c.children.length", "3" },
|
||||
.{ "c.firstElementChild.nodeName", "A" },
|
||||
.{ "c.lastElementChild.nodeName", "P" },
|
||||
.{ "c.childElementCount", "3" },
|
||||
|
||||
.{ "c.prepend(document.createTextNode('foo'))", "undefined" },
|
||||
.{ "c.append(document.createTextNode('bar'))", "undefined" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let d = document.getElementById('para')", "undefined" },
|
||||
.{ "d.previousElementSibling.nodeName", "P" },
|
||||
.{ "d.nextElementSibling", "null" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let e = document.getElementById('content')", "undefined" },
|
||||
.{ "e.querySelector('foo')", "null" },
|
||||
.{ "e.querySelector('#foo')", "null" },
|
||||
.{ "e.querySelector('#link').id", "link" },
|
||||
.{ "e.querySelector('#para').id", "para" },
|
||||
.{ "e.querySelector('*').id", "link" },
|
||||
.{ "e.querySelector('')", "null" },
|
||||
.{ "e.querySelector('*').id", "link" },
|
||||
.{ "e.querySelector('#content')", "null" },
|
||||
.{ "e.querySelector('#para').id", "para" },
|
||||
.{ "e.querySelector('.ok').id", "link" },
|
||||
.{ "e.querySelector('a ~ p').id", "para-empty" },
|
||||
|
||||
.{ "e.querySelectorAll('foo').length", "0" },
|
||||
.{ "e.querySelectorAll('#foo').length", "0" },
|
||||
.{ "e.querySelectorAll('#link').length", "1" },
|
||||
.{ "e.querySelectorAll('#link').item(0).id", "link" },
|
||||
.{ "e.querySelectorAll('#para').length", "1" },
|
||||
.{ "e.querySelectorAll('#para').item(0).id", "para" },
|
||||
.{ "e.querySelectorAll('*').length", "4" },
|
||||
.{ "e.querySelectorAll('p').length", "2" },
|
||||
.{ "e.querySelectorAll('.ok').item(0).id", "link" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "let f = document.getElementById('content')", "undefined" },
|
||||
.{ "let ff = document.createAttribute('foo')", "undefined" },
|
||||
.{ "f.setAttributeNode(ff)", "null" },
|
||||
.{ "f.getAttributeNode('foo').name", "foo" },
|
||||
.{ "f.removeAttributeNode(ff).name", "foo" },
|
||||
.{ "f.getAttributeNode('bar')", "null" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "document.getElementById('para').innerHTML", " And" },
|
||||
.{ "document.getElementById('para-empty').innerHTML.trim()", "<span id=\"para-empty-child\"></span>" },
|
||||
|
||||
.{ "let h = document.getElementById('para-empty')", "undefined" },
|
||||
.{ "const prev = h.innerHTML", "undefined" },
|
||||
.{ "h.innerHTML = '<p id=\"hello\">hello world</p>'", "<p id=\"hello\">hello world</p>" },
|
||||
.{ "h.innerHTML", "<p id=\"hello\">hello world</p>" },
|
||||
.{ "h.firstChild.nodeName", "P" },
|
||||
.{ "h.firstChild.id", "hello" },
|
||||
.{ "h.firstChild.textContent", "hello world" },
|
||||
.{ "h.innerHTML = prev; true", "true" },
|
||||
.{ "document.getElementById('para-empty').innerHTML.trim()", "<span id=\"para-empty-child\"></span>" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "document.getElementById('para').outerHTML", "<p id=\"para\"> And</p>" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "document.getElementById('para').clientWidth", "1" },
|
||||
.{ "document.getElementById('para').clientHeight", "1" },
|
||||
|
||||
.{ "let r1 = document.getElementById('para').getBoundingClientRect()", "undefined" },
|
||||
.{ "r1.x", "0" },
|
||||
.{ "r1.y", "0" },
|
||||
.{ "r1.width", "1" },
|
||||
.{ "r1.height", "1" },
|
||||
|
||||
.{ "let r2 = document.getElementById('content').getBoundingClientRect()", "undefined" },
|
||||
.{ "r2.x", "1" },
|
||||
.{ "r2.y", "0" },
|
||||
.{ "r2.width", "1" },
|
||||
.{ "r2.height", "1" },
|
||||
|
||||
.{ "let r3 = document.getElementById('para').getBoundingClientRect()", "undefined" },
|
||||
.{ "r3.x", "0" },
|
||||
.{ "r3.y", "0" },
|
||||
.{ "r3.width", "1" },
|
||||
.{ "r3.height", "1" },
|
||||
|
||||
.{ "document.getElementById('para').clientWidth", "2" },
|
||||
.{ "document.getElementById('para').clientHeight", "1" },
|
||||
|
||||
.{ "let r4 = document.createElement('div').getBoundingClientRect()", null },
|
||||
.{ "r4.x", "0" },
|
||||
.{ "r4.y", "0" },
|
||||
.{ "r4.width", "0" },
|
||||
.{ "r4.height", "0" },
|
||||
|
||||
// Test setup causes WrongDocument or HierarchyRequest error unlike in chrome/firefox
|
||||
// .{ // An element of another document, even if created from the main document, is not rendered.
|
||||
// \\ let div5 = document.createElement('div');
|
||||
// \\ const newDoc = document.implementation.createHTMLDocument("New Document");
|
||||
// \\ newDoc.body.appendChild(div5);
|
||||
// \\ let r5 = div5.getBoundingClientRect();
|
||||
// ,
|
||||
// null,
|
||||
// },
|
||||
// .{ "r5.x", "0" },
|
||||
// .{ "r5.y", "0" },
|
||||
// .{ "r5.width", "0" },
|
||||
// .{ "r5.height", "0" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const el = document.createElement('div');", "undefined" },
|
||||
.{ "el.id = 'matches'; el.className = 'ok';", "ok" },
|
||||
.{ "el.matches('#matches')", "true" },
|
||||
.{ "el.matches('.ok')", "true" },
|
||||
.{ "el.matches('#9000')", "false" },
|
||||
.{ "el.matches('.notok')", "false" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const el3 = document.createElement('div');", "undefined" },
|
||||
.{ "el3.scrollIntoViewIfNeeded();", "undefined" },
|
||||
.{ "el3.scrollIntoViewIfNeeded(false);", "undefined" },
|
||||
}, .{});
|
||||
|
||||
// before
|
||||
try runner.testCases(&.{
|
||||
.{ "const before_container = document.createElement('div');", "undefined" },
|
||||
.{ "document.append(before_container);", "undefined" },
|
||||
.{ "const b1 = document.createElement('div');", "undefined" },
|
||||
.{ "before_container.append(b1);", "undefined" },
|
||||
|
||||
.{ "const b1_a = document.createElement('p');", "undefined" },
|
||||
.{ "b1.before(b1_a, 'over 9000');", "undefined" },
|
||||
.{ "before_container.innerHTML", "<p></p>over 9000<div></div>" },
|
||||
}, .{});
|
||||
|
||||
// after
|
||||
try runner.testCases(&.{
|
||||
.{ "const after_container = document.createElement('div');", "undefined" },
|
||||
.{ "document.append(after_container);", "undefined" },
|
||||
.{ "const a1 = document.createElement('div');", "undefined" },
|
||||
.{ "after_container.append(a1);", "undefined" },
|
||||
|
||||
.{ "const a1_a = document.createElement('p');", "undefined" },
|
||||
.{ "a1.after('over 9000', a1_a);", "undefined" },
|
||||
.{ "after_container.innerHTML", "<div></div>over 9000<p></p>" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "var div1 = document.createElement('div');", null },
|
||||
.{ "div1.innerHTML = \" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\"", null },
|
||||
.{ "div1.getElementsByTagName('a').length", "1" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "document.createElement('a').hasAttributes()", "false" },
|
||||
.{ "var fc; (fc = document.createElement('div')).innerHTML = '<script><\\/script>'", null },
|
||||
.{ "fc.outerHTML", "<div><script></script></div>" },
|
||||
|
||||
.{ "fc; (fc = document.createElement('div')).innerHTML = '<script><\\/script><p>hello</p>'", null },
|
||||
.{ "fc.outerHTML", "<div><script></script><p>hello</p></div>" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const rm = document.createElement('div')", null },
|
||||
.{ "rm.getAttributeNames()", "" },
|
||||
.{ "rm.id = 'to-remove'", null },
|
||||
.{ "document.getElementsByTagName('body')[0].appendChild(rm)", null },
|
||||
.{ "document.getElementById('to-remove') != null", "true" },
|
||||
.{ "rm.remove()", "undefined" },
|
||||
.{ "document.getElementById('to-remove') != null", "false" },
|
||||
}, .{});
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "const div2 = document.createElement('div');", null },
|
||||
.{ "div2.innerHTML = '<p id=1 .lit$id=9>a</p>';", null },
|
||||
.{ "div2.innerHTML", "<p id=\"1\" .lit$id=\"9\">a</p>" },
|
||||
.{ "div2.childNodes[0].getAttributeNames()", "id,.lit$id" },
|
||||
}, .{});
|
||||
test "Browser: DOM.Element" {
|
||||
try testing.htmlRunner("dom/element.html");
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ pub const Page = struct {
|
||||
// Look, we want to exit ASAP, but we don't want
|
||||
// to exit so fast that we've run none of the
|
||||
// background jobs.
|
||||
break :blk 50;
|
||||
break :blk if (comptime builtin.is_test) 5 else 50;
|
||||
}
|
||||
// No http transfers, no cdp extra socket, no
|
||||
// scheduled tasks, we're done.
|
||||
@@ -397,7 +397,7 @@ pub const Page = struct {
|
||||
// we _could_ http_client.tick(ms_to_wait), but this has
|
||||
// the same result, and I feel is more correct.
|
||||
return .no_page;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const ms_elapsed = timer.lap() / 1_000_000;
|
||||
|
||||
@@ -176,8 +176,6 @@ pub const Session = struct {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const QueuedNavigation = struct {
|
||||
url: []const u8,
|
||||
opts: NavigateOpts,
|
||||
|
||||
@@ -117,9 +117,7 @@ pub fn CDPT(comptime TypeProvider: type) type {
|
||||
// scheduled task. So we run this directly in order to process any
|
||||
// timeouts (or http events) which are ready to be processed.
|
||||
|
||||
pub fn hasPage() bool {
|
||||
|
||||
}
|
||||
pub fn hasPage() bool {}
|
||||
pub fn pageWait(self: *Self, ms: i32) Session.WaitResult {
|
||||
const session = &(self.browser.session orelse return .no_page);
|
||||
return session.wait(ms);
|
||||
|
||||
@@ -387,7 +387,7 @@ fn makeRequest(self: *Client, handle: *Handle, transfer: *Transfer) !void {
|
||||
_ = try self.perform(0);
|
||||
}
|
||||
|
||||
pub const PerformStatus = enum{
|
||||
pub const PerformStatus = enum {
|
||||
extra_socket,
|
||||
normal,
|
||||
};
|
||||
|
||||
@@ -331,18 +331,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
||||
|
||||
fn promiseRejectCallback(v8_msg: v8.C_PromiseRejectMessage) callconv(.c) void {
|
||||
const msg = v8.PromiseRejectMessage.initFromC(v8_msg);
|
||||
const isolate = msg.getPromise().toObject().getIsolate();
|
||||
const isolate = msg.getPromise().toObject().getIsolate();
|
||||
const v8_context = isolate.getCurrentContext();
|
||||
const context: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64());
|
||||
|
||||
const value =
|
||||
if (msg.getValue()) |v8_value| valueToString(context.call_arena, v8_value, isolate, v8_context) catch |err| @errorName(err)
|
||||
else "no value";
|
||||
if (msg.getValue()) |v8_value| valueToString(context.call_arena, v8_value, isolate, v8_context) catch |err| @errorName(err) else "no value";
|
||||
|
||||
log.debug(.js, "unhandled rejection", .{.value =value});
|
||||
log.debug(.js, "unhandled rejection", .{ .value = value });
|
||||
}
|
||||
|
||||
|
||||
// ExecutionWorld closely models a JS World.
|
||||
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md#World
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/ExecutionWorld
|
||||
|
||||
33
src/tests/dom/document_fragment.html
Normal file
33
src/tests/dom/document_fragment.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<script src="../testing.js"></script>
|
||||
<body></body>
|
||||
|
||||
<script id=documentFragement>
|
||||
testing.expectEqual('DocumentFragment', new DocumentFragment().constructor.name);
|
||||
|
||||
const dc1 = new DocumentFragment();
|
||||
testing.expectEqual(true, dc1.isEqualNode(dc1))
|
||||
|
||||
const dc2 = new DocumentFragment();
|
||||
testing.expectEqual(true, dc1.isEqualNode(dc2))
|
||||
|
||||
let f = document.createDocumentFragment();
|
||||
let d = document.createElement('div');
|
||||
testing.expectEqual(0, d.childElementCount);
|
||||
|
||||
d.id = 'x';
|
||||
testing.expectEqual(null, $('#x'));
|
||||
|
||||
f.append(d);
|
||||
testing.expectEqual(1, f.childElementCount)
|
||||
testing.expectEqual('x', f.children[0].id);
|
||||
testing.expectEqual(null, $('#x'));
|
||||
|
||||
document.getElementsByTagName('body')[0].append(f.cloneNode(true));
|
||||
testing.expectEqual(true, $('#x') != null);
|
||||
|
||||
testing.expectEqual(null, document.querySelector('.hello'));
|
||||
testing.expectEqual(0, document.querySelectorAll('.hello').length);
|
||||
|
||||
testing.expectEqual('x', document.querySelector('#x').id);
|
||||
testing.expectEqual(['x'], Array.from(document.querySelectorAll('#x')).map((n) => n.id));
|
||||
</script>
|
||||
12
src/tests/dom/document_type.html
Normal file
12
src/tests/dom/document_type.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<script src="../testing.js"></script>
|
||||
<script id=documentType>
|
||||
let dt1 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');
|
||||
let dt2 = document.implementation.createDocumentType('qname2', 'pid2', 'sys2');
|
||||
let dt3 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');
|
||||
testing.expectEqual(true, dt1.isEqualNode(dt1));
|
||||
testing.expectEqual(true, dt1.isEqualNode(dt3));
|
||||
testing.expectEqual(false, dt1.isEqualNode(dt2));
|
||||
testing.expectEqual(false, dt2.isEqualNode(dt3));
|
||||
testing.expectEqual(false, dt1.isEqualNode(document));
|
||||
testing.expectEqual(false, document.isEqualNode(dt1));
|
||||
</script>
|
||||
6
src/tests/dom/dom_parser.html
Normal file
6
src/tests/dom/dom_parser.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<script src="../testing.js"></script>
|
||||
<script id=domParser>
|
||||
const dp = new DOMParser();;
|
||||
const parsed = dp.parseFromString('<div>abc</div>', 'text/html');
|
||||
testing.expectEqual('[object HTMLDocument]', parsed.toString());
|
||||
</script>
|
||||
264
src/tests/dom/element.html
Normal file
264
src/tests/dom/element.html
Normal file
@@ -0,0 +1,264 @@
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<div id="content">
|
||||
<a id="link" href="foo" class="ok">OK</a>
|
||||
<p id="para-empty" class="ok empty">
|
||||
<span id="para-empty-child"></span>
|
||||
</p>
|
||||
<p id="para"> And</p>
|
||||
<!--comment-->
|
||||
</div>
|
||||
|
||||
<script id=element>
|
||||
let content = document.getElementById('content');
|
||||
testing.expectEqual('http://www.w3.org/1999/xhtml', content.namespaceURI);
|
||||
testing.expectEqual(null, content.prefix);
|
||||
testing.expectEqual('div', content.localName);
|
||||
testing.expectEqual('DIV', content.tagName);
|
||||
testing.expectEqual('content', content.id);
|
||||
|
||||
content.id = 'foo';
|
||||
testing.expectEqual('foo', content.id);
|
||||
|
||||
content.id = 'content';
|
||||
testing.expectEqual('', content.className);
|
||||
|
||||
let p1 = document.getElementById('para-empty');
|
||||
testing.expectEqual('ok empty', p1.className);
|
||||
|
||||
p1.className = 'foo bar baz';
|
||||
testing.expectEqual('foo bar baz', p1.className);
|
||||
|
||||
p1.className = 'ok empty';
|
||||
testing.expectEqual(2, p1.classList.length);
|
||||
</script>
|
||||
|
||||
<script id=closest>
|
||||
const el2 = document.createElement('div');
|
||||
el2.id = 'closest';
|
||||
el2.className = 'ok';
|
||||
|
||||
testing.expectEqual(el2, el2.closest('#closest'));
|
||||
testing.expectEqual(el2, el2.closest('.ok'));
|
||||
testing.expectEqual(null, el2.closest('#9000'));
|
||||
testing.expectEqual(null, el2.closest('.notok'));
|
||||
|
||||
const sp = document.createElement('span');
|
||||
el2.appendChild(sp);
|
||||
testing.expectEqual(el2, sp.closest('#closest'));
|
||||
testing.expectEqual(null, sp.closest('#9000'));
|
||||
</script>
|
||||
|
||||
<script id=attributes>
|
||||
testing.expectEqual(true, content.hasAttributes());
|
||||
testing.expectEqual(1, content.attributes.length);
|
||||
testing.expectEqual(['id'], content.getAttributeNames());
|
||||
testing.expectEqual('content', content.getAttribute('id'));
|
||||
testing.expectEqual('content', content.attributes['id'].value);
|
||||
|
||||
let x = '';
|
||||
for (const attr of content.attributes) {
|
||||
x += attr.name + '=' + attr.value;
|
||||
}
|
||||
testing.expectEqual('id=content', x);
|
||||
|
||||
testing.expectEqual(false, content.hasAttribute('foo'));
|
||||
testing.expectEqual(null, content.getAttribute('foo'));
|
||||
|
||||
content.setAttribute('foo', 'bar');
|
||||
testing.expectEqual(true, content.hasAttribute('foo'));
|
||||
testing.expectEqual('bar', content.getAttribute('foo'));
|
||||
testing.expectEqual(['id', 'foo'], content.getAttributeNames());
|
||||
|
||||
testing.expectError('Error: InvalidCharacterError', () => {
|
||||
content.setAttribute('.foo', 'invalid')
|
||||
});
|
||||
|
||||
content.setAttribute('foo', 'baz');
|
||||
testing.expectEqual(true, content.hasAttribute('foo'));
|
||||
testing.expectEqual('baz', content.getAttribute('foo'));
|
||||
|
||||
content.removeAttribute('foo');
|
||||
testing.expectEqual(false, content.hasAttribute('foo'));
|
||||
testing.expectEqual(null, content.getAttribute('foo'));
|
||||
|
||||
let b = document.getElementById('content');
|
||||
testing.expectEqual(true, b.toggleAttribute('foo'));
|
||||
testing.expectEqual(true, b.hasAttribute('foo'));
|
||||
testing.expectEqual('', b.getAttribute('foo'));
|
||||
|
||||
testing.expectEqual(false, b.toggleAttribute('foo'));
|
||||
testing.expectEqual(false, b.hasAttribute('foo'));
|
||||
|
||||
testing.expectEqual(false, document.createElement('a').hasAttributes());
|
||||
|
||||
const div2 = document.createElement('div');
|
||||
div2.innerHTML = '<p id=1 .lit$id=9>a</p>';
|
||||
testing.expectEqual('<p id="1" .lit$id="9">a</p>', div2.innerHTML);
|
||||
testing.expectEqual(['id', '.lit$id'], div2.childNodes[0].getAttributeNames());
|
||||
</script>
|
||||
|
||||
<script id=children>
|
||||
testing.expectEqual(3, content.children.length);
|
||||
testing.expectEqual('A', content.firstElementChild.nodeName);
|
||||
testing.expectEqual('P', content.lastElementChild.nodeName);
|
||||
testing.expectEqual(3, content.childElementCount);
|
||||
</script>
|
||||
|
||||
<script id=sibling>
|
||||
content.prepend(document.createTextNode('foo'));
|
||||
content.append(document.createTextNode('bar'));
|
||||
|
||||
let d = document.getElementById('para');
|
||||
testing.expectEqual('P', d.previousElementSibling.nodeName);
|
||||
testing.expectEqual(null, d.nextElementSibling);
|
||||
</script>
|
||||
|
||||
<script id=querySelector>
|
||||
testing.expectEqual(null, content.querySelector('foo'));
|
||||
testing.expectEqual(null, content.querySelector('#foo'));
|
||||
testing.expectEqual('link', content.querySelector('#link').id);
|
||||
testing.expectEqual('para', content.querySelector('#para').id);
|
||||
testing.expectEqual('link', content.querySelector('*').id);
|
||||
testing.expectEqual(null, content.querySelector(''));
|
||||
testing.expectEqual('link', content.querySelector('*').id);
|
||||
testing.expectEqual(null, content.querySelector('#content'));
|
||||
testing.expectEqual('para', content.querySelector('#para').id);
|
||||
testing.expectEqual('link', content.querySelector('.ok').id);
|
||||
testing.expectEqual('para-empty', content.querySelector('a ~ p').id);
|
||||
|
||||
testing.expectEqual(0, content.querySelectorAll('foo').length);
|
||||
testing.expectEqual(0, content.querySelectorAll('#foo').length);
|
||||
testing.expectEqual(1, content.querySelectorAll('#link').length);
|
||||
testing.expectEqual('link', content.querySelectorAll('#link').item(0).id);
|
||||
testing.expectEqual(1, content.querySelectorAll('#para').length);
|
||||
testing.expectEqual('para', content.querySelectorAll('#para').item(0).id);
|
||||
testing.expectEqual(4, content.querySelectorAll('*').length);
|
||||
testing.expectEqual(2, content.querySelectorAll('p').length);
|
||||
testing.expectEqual('link', content.querySelectorAll('.ok').item(0).id);
|
||||
</script>
|
||||
|
||||
<script id=createdAttributes>
|
||||
let ff = document.createAttribute('foo');
|
||||
content.setAttributeNode(ff);
|
||||
testing.expectEqual('foo', content.getAttributeNode('foo').name);
|
||||
testing.expectEqual('foo', content.removeAttributeNode(ff).name);
|
||||
testing.expectEqual(null, content.getAttributeNode('bar'));
|
||||
</script>
|
||||
|
||||
<script id=innerHTML>
|
||||
testing.expectEqual(' And', document.getElementById('para').innerHTML);
|
||||
testing.expectEqual('<span id="para-empty-child"></span>', $('#para-empty').innerHTML.trim());
|
||||
|
||||
let h = $('#para-empty');
|
||||
const prev = h.innerHTML;
|
||||
h.innerHTML = '<p id="hello">hello world</p>';
|
||||
testing.expectEqual('<p id="hello">hello world</p>', h.innerHTML);
|
||||
testing.expectEqual('P', h.firstChild.nodeName);
|
||||
testing.expectEqual('hello', h.firstChild.id);
|
||||
testing.expectEqual('hello world', h.firstChild.textContent);
|
||||
|
||||
h.innerHTML = prev;
|
||||
testing.expectEqual('<span id="para-empty-child"></span>', $('#para-empty').innerHTML.trim());
|
||||
testing.expectEqual('<p id="para"> And</p>', $('#para').outerHTML);
|
||||
</script>
|
||||
|
||||
<script id=dimensions>
|
||||
const para = document.getElementById('para');
|
||||
testing.expectEqual(1, para.clientWidth);
|
||||
testing.expectEqual(1, para.clientHeight);
|
||||
|
||||
// let r1 = document.getElementById('para').getBoundingClientRect();
|
||||
// testing.expectEqual(0, r1.x);
|
||||
// testing.expectEqual(0, r1.y);
|
||||
// testing.expectEqual(1, r1.width);
|
||||
// testing.expectEqual(2, r1.height);
|
||||
|
||||
// let r2 = document.getElementById('content').getBoundingClientRect();
|
||||
// testing.expectEqual(1, r2.x);
|
||||
// testing.expectEqual(0, r2.y);
|
||||
// testing.expectEqual(1, r2.width);
|
||||
// testing.expectEqual(1, r2.height);
|
||||
|
||||
// let r3 = document.getElementById('para').getBoundingClientRect();
|
||||
// testing.expectEqual(0, r3.x);
|
||||
// testing.expectEqual(0, r3.y);
|
||||
// testing.expectEqual(1, r3.width);
|
||||
// testing.expectEqual(1, r3.height);
|
||||
|
||||
// testing.expectEqual(1, para.clientWidth);
|
||||
// testing.expectEqual(1, para.clientHeight);
|
||||
|
||||
// let r4 = document.createElement('div').getBoundingClientRect();
|
||||
// testing.expectEqual(0, r4.x);
|
||||
// testing.expectEqual(0, r4.y);
|
||||
// testing.expectEqual(0, r4.width);
|
||||
// testing.expectEqual(0, r4.height);
|
||||
</script>
|
||||
|
||||
<script id=matches>
|
||||
const el = document.createElement('div');
|
||||
el.id = 'matches';
|
||||
el.className = 'ok';
|
||||
testing.expectEqual(true, el.matches('#matches'));
|
||||
testing.expectEqual(true, el.matches('.ok'));
|
||||
testing.expectEqual(false, el.matches('#9000'));
|
||||
testing.expectEqual(false, el.matches('.notok'));
|
||||
</script>
|
||||
|
||||
<script id=scroll>
|
||||
const el3 = document.createElement('div');
|
||||
el3.scrollIntoViewIfNeeded();
|
||||
el3.scrollIntoViewIfNeeded(false);
|
||||
// doesn't throw is good enough
|
||||
testing.skip();
|
||||
</script>
|
||||
|
||||
<script id=before>
|
||||
const before_container = document.createElement('div');
|
||||
document.append(before_container);
|
||||
|
||||
const b1 = document.createElement('div');
|
||||
before_container.append(b1);
|
||||
|
||||
const b1_a = document.createElement('p');
|
||||
b1.before(b1_a, 'over 9000');
|
||||
testing.expectEqual('<p></p>over 9000<div></div>', before_container.innerHTML);
|
||||
</script>
|
||||
|
||||
<script id=after>
|
||||
const after_container = document.createElement('div');
|
||||
document.append(after_container);
|
||||
const a1 = document.createElement('div');
|
||||
after_container.append(a1);
|
||||
|
||||
const a1_a = document.createElement('p');
|
||||
a1.after('over 9000', a1_a);
|
||||
testing.expectEqual('<div></div>over 9000<p></p>', after_container.innerHTML);
|
||||
</script>
|
||||
|
||||
<script id=getElementsByTagName>
|
||||
var div1 = document.createElement('div');
|
||||
div1.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||||
testing.expectEqual(1, div1.getElementsByTagName('a').length);
|
||||
</script>
|
||||
|
||||
<script id=outerHTML>
|
||||
let fc = document.createElement('div')
|
||||
fc.innerHTML = '<script><\/script>';
|
||||
testing.expectEqual('<div><script><\/script></div>', fc.outerHTML);
|
||||
|
||||
fc = document.createElement('div')
|
||||
fc.innerHTML = '<script><\/script><p>hello</p>';
|
||||
testing.expectEqual('<div><script><\/script><p>hello</p></div>', fc.outerHTML);
|
||||
</script>
|
||||
|
||||
<script id=remove>
|
||||
const rm = document.createElement('div');
|
||||
testing.expectEqual([], rm.getAttributeNames());
|
||||
rm.id = 'to-remove';
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(rm);
|
||||
$('#to-remove').remove();
|
||||
testing.expectEqual(null, $('#to-remove'));
|
||||
</script>
|
||||
Reference in New Issue
Block a user