Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/browser/dom/document.zig
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,67 @@ pub const Document = struct {
log.debug(.web_api, "not implemented", .{ .feature = "Document hasFocus" });
return true;
}

pub fn _open(_: *parser.Document, page: *Page) !*parser.DocumentHTML {
if (page.open) {
return page.window.document;
}

// This implementation is invalid.
// According to MDN, we should cleanup registered listeners.
// So we sould cleanup previous DOM memory.
// But this implementation is more simple for now.
const html_doc = try parser.documentHTMLParseFromStr("");
try page.setDocument(html_doc);
page.open = true;

return page.window.document;
}

pub fn _close(_: *parser.Document, page: *Page) !void {
page.open = false;
}

pub fn _write(self: *parser.Document, str: []const u8, page: *Page) !void {
_ = try _open(self, page);

const document = parser.documentHTMLToDocument(page.window.document);
const fragment = try parser.documentParseFragmentFromStr(document, str);
const fragment_node = parser.documentFragmentToNode(fragment);

const fragment_html = parser.nodeFirstChild(fragment_node) orelse return;
const fragment_head = parser.nodeFirstChild(fragment_html) orelse return;
const fragment_body = parser.nodeNextSibling(fragment_head) orelse return;

const document_node = parser.documentToNode(document);
const document_html = parser.nodeFirstChild(document_node) orelse return;
const document_head = parser.nodeFirstChild(document_html) orelse return;
const document_body = parser.nodeNextSibling(document_head) orelse return;

{
const children = try parser.nodeGetChildNodes(fragment_head);
// always index 0, because nodeAppendChild moves the node out of
// the nodeList and into the new tree
while (parser.nodeListItem(children, 0)) |child| {
_ = try parser.nodeAppendChild(document_head, child);
}
}

{
const children = try parser.nodeGetChildNodes(fragment_body);
// always index 0, because nodeAppendChild moves the node out of
// the nodeList and into the new tree
while (parser.nodeListItem(children, 0)) |child| {
_ = try parser.nodeAppendChild(document_body, child);
}
}
}
};

const testing = @import("../../testing.zig");
test "Browser: DOM.Document" {
try testing.htmlRunner("dom/document.html");
}
test "Browser: DOM.Document.write" {
try testing.htmlRunner("dom/document_write.html");
}
4 changes: 4 additions & 0 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ pub const Page = struct {
notified_network_idle: IdleNotification = .init,
notified_network_almost_idle: IdleNotification = .init,

// Indicates if the page's document is open or close.
// Relates with https://developer.mozilla.org/en-US/docs/Web/API/Document/open
open: bool = false,

const Mode = union(enum) {
pre: void,
err: anyerror,
Expand Down
25 changes: 25 additions & 0 deletions src/tests/dom/document_write.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<script src="../testing.js"></script>

<div id="content">
<a id="a1" href="foo" class="ok">OK</a>
<p id="p1" class="ok empty">
<span id="s1"></span>
</p>
<p id="p2"> And</p>
</div>


<script id=document_write>
document.open();
document.write("<p id=ok>Hello world!</p>");
document.write("<p>I am a fish</p>");
document.write("<p>The number is 42</p>");
document.close();

const ok = document.getElementById("ok");
testing.expectEqual('Hello world!', ok.innerText);

const content = document.firstElementChild.innerHTML;
testing.expectEqual('<head></head><body><p id="ok">Hello world!</p><p>I am a fish</p><p>The number is 42</p></body>', content);
</script>