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
12 changes: 12 additions & 0 deletions src/browser/env.zig
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,16 @@ pub const SessionState = struct {
// shorter-lived than the arena above, which
// exists for the entire rendering of the page
call_arena: std.mem.Allocator = undefined,

pub fn getNodeWrapper(self: *SessionState, comptime T: type, node: *parser.Node) !*T {
if (parser.nodeGetEmbedderData(node)) |wrap| {
return @alignCast(@ptrCast(wrap));
}

const wrap = try self.arena.create(T);
wrap.* = T{};

parser.nodeSetEmbedderData(node, wrap);
return wrap;
}
};
43 changes: 43 additions & 0 deletions src/browser/html/document.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ pub const HTMLDocument = struct {
pub const prototype = *Document;
pub const subtype = .node;

ready_state: ReadyState = .loading,

const ReadyState = enum {
loading,
interactive,
complete,
};

// JS funcs
// --------

Expand Down Expand Up @@ -176,6 +184,11 @@ pub const HTMLDocument = struct {
return state.window;
}

pub fn get_readyState(node: *parser.DocumentHTML, state: *SessionState) ![]const u8 {
const self = try state.getNodeWrapper(HTMLDocument, @ptrCast(node));
return @tagName(self.ready_state);
}

// noop legacy functions
// https://html.spec.whatwg.org/#Document-partial
pub fn _clear(_: *parser.DocumentHTML) void {}
Expand Down Expand Up @@ -212,6 +225,22 @@ pub const HTMLDocument = struct {
pub fn set_bgColor(_: *parser.DocumentHTML, _: []const u8) []const u8 {
return "";
}

pub fn documentIsLoaded(html_doc: *parser.DocumentHTML, state: *SessionState) !void {
const self = try state.getNodeWrapper(HTMLDocument, @ptrCast(html_doc));
self.ready_state = .interactive;

const evt = try parser.eventCreate();
defer parser.eventDestroy(evt);

try parser.eventInit(evt, "DOMContentLoaded", .{ .bubbles = true, .cancelable = true });
_ = try parser.eventTargetDispatchEvent(parser.toEventTarget(parser.DocumentHTML, html_doc), evt);
}

pub fn documentIsComplete(html_doc: *parser.DocumentHTML, state: *SessionState) !void {
const self = try state.getNodeWrapper(HTMLDocument, @ptrCast(html_doc));
self.ready_state = .complete;
}
};

// Tests
Expand Down Expand Up @@ -276,4 +305,18 @@ test "Browser.HTML.Document" {
try runner.testCases(&.{
.{ "document.defaultView.document == document", "true" },
}, .{});

try runner.testCases(&.{
.{ "document.readyState", "loading" },
}, .{});

try HTMLDocument.documentIsLoaded(runner.state.document.?, &runner.state);
try runner.testCases(&.{
.{ "document.readyState", "interactive" },
}, .{});

try HTMLDocument.documentIsComplete(runner.state.document.?, &runner.state);
try runner.testCases(&.{
.{ "document.readyState", "complete" },
}, .{});
}
8 changes: 8 additions & 0 deletions src/browser/netsurf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,14 @@ pub fn nodeGetPrefix(node: *Node) !?[]const u8 {
return strToData(s.?);
}

pub fn nodeGetEmbedderData(node: *Node) ?*anyopaque {
return c._dom_node_get_embedder_data(node);
}

pub fn nodeSetEmbedderData(node: *Node, data: *anyopaque) void {
c._dom_node_set_embedder_data(node, data);
}

// nodeToElement is an helper to convert a node to an element.
pub inline fn nodeToElement(node: *Node) *Element {
return @as(*Element, @ptrCast(node));
Expand Down
12 changes: 3 additions & 9 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Window = @import("html/window.zig").Window;
const Walker = @import("dom/walker.zig").WalkerDepthFirst;
const Env = @import("env.zig").Env;
const Loop = @import("../runtime/loop.zig").Loop;
const HTMLDocument = @import("html/document.zig").HTMLDocument;

const URL = @import("../url.zig").URL;

Expand Down Expand Up @@ -351,16 +352,11 @@ pub const Page = struct {
self.evalScript(&s) catch |err| log.warn("evaljs: {any}", .{err});
try parser.documentHTMLSetCurrentScript(html_doc, null);
}

// dispatch DOMContentLoaded before the transition to "complete",
// at the point where all subresources apart from async script elements
// have loaded.
// https://html.spec.whatwg.org/#reporting-document-loading-status
const evt = try parser.eventCreate();
defer parser.eventDestroy(evt);

try parser.eventInit(evt, "DOMContentLoaded", .{ .bubbles = true, .cancelable = true });
_ = try parser.eventTargetDispatchEvent(parser.toEventTarget(parser.DocumentHTML, html_doc), evt);
try HTMLDocument.documentIsLoaded(html_doc, &self.state);

// eval async scripts.
for (async_scripts.items) |s| {
Expand All @@ -369,9 +365,7 @@ pub const Page = struct {
try parser.documentHTMLSetCurrentScript(html_doc, null);
}

// TODO wait for async scripts

// TODO set document.readyState to complete
try HTMLDocument.documentIsComplete(html_doc, &self.state);

// dispatch window.load event
const loadevt = try parser.eventCreate();
Expand Down
2 changes: 1 addition & 1 deletion vendor/netsurf/libdom