From 3544e98871729cc3be532d0ea9c928067c9b10b4 Mon Sep 17 00:00:00 2001 From: sjorsdonkers <72333389+sjorsdonkers@users.noreply.github.com> Date: Sat, 7 Jun 2025 00:19:39 +0200 Subject: [PATCH] create_element_external WIP --- src/browser/State.zig | 4 ++++ src/browser/dom/implementation.zig | 3 ++- src/browser/html/elements.zig | 31 ++++++++++++++++-------------- src/browser/netsurf.zig | 10 ++++++++-- vendor/netsurf/libdom | 2 +- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/browser/State.zig b/src/browser/State.zig index 55447923..9f02d4e4 100644 --- a/src/browser/State.zig +++ b/src/browser/State.zig @@ -29,6 +29,7 @@ const Env = @import("env.zig").Env; const parser = @import("netsurf.zig"); const CSSStyleDeclaration = @import("cssom/css_style_declaration.zig").CSSStyleDeclaration; +const Page = @import("page.zig").Page; // for HTMLScript (but probably needs to be added to more) onload: ?Env.Function = null, @@ -58,6 +59,9 @@ active_element: ?*parser.Element = null, // default (by returning selectedIndex == 0). explicit_index_set: bool = false, +// TODO +page: ?*Page = null, + const ReadyState = enum { loading, interactive, diff --git a/src/browser/dom/implementation.zig b/src/browser/dom/implementation.zig index 55d302a1..4609041d 100644 --- a/src/browser/dom/implementation.zig +++ b/src/browser/dom/implementation.zig @@ -42,7 +42,8 @@ pub const DOMImplementation = struct { } pub fn _createHTMLDocument(_: *DOMImplementation, title: ?[]const u8) !*parser.DocumentHTML { - return try parser.domImplementationCreateHTMLDocument(title); + const Elements = @import("../html/elements.zig"); + return try parser.domImplementationCreateHTMLDocument(title, &Elements.createElement); } pub fn _hasFeature(_: *DOMImplementation) bool { diff --git a/src/browser/html/elements.zig b/src/browser/html/elements.zig index 8c691124..4f88e1fb 100644 --- a/src/browser/html/elements.zig +++ b/src/browser/html/elements.zig @@ -627,17 +627,20 @@ pub const HTMLImageElement = struct { }; }; -pub fn createElement(doc: *parser.Document, params: *parser.dom_html_element_create_params, elem: **parser.HtmlElement) !void { - // Required to be set on all documents. How during dom parsing? - const wrap = parser.nodeGetEmbedderData(@ptrCast(doc)).?; - const state = @as(State, @alignCast(@ptrCast(wrap))); - const page = state.page; +pub fn createElement(doc: [*c]parser.DocumentHTML, params: [*c]parser.c.dom_html_element_create_params, elem: [*c][*c]parser.ElementHTML) callconv(.c) parser.c.dom_exception { + // Required to be set on all htmldocuments. How during dom parsing? + const wrap = parser.nodeGetEmbedderData(@ptrCast(doc)).?; // TODO this is not set yet + const state = @as(*State, @alignCast(@ptrCast(wrap))); + const page = state.page.?; - switch (params.type) { - .DOM_HTML_ELEMENT_TYPE_INPUT => { + const p: *parser.c.dom_html_element_create_params = @ptrCast(params); + switch (p.type) { + parser.c.DOM_HTML_ELEMENT_TYPE_INPUT => { elem.* = try HTMLInputElement.dom_create(params, page); }, + else => return parser.c.DOM_NOT_FOUND_ERR, } + return parser.c.DOM_NO_ERR; } pub const HTMLInputElement = struct { @@ -646,29 +649,29 @@ pub const HTMLInputElement = struct { pub const subtype = .node; // VTables can be generated from the dom_ funcs - pub const vtable: parser.dom_html_element_vtable = parser._dom_html_element_vtable; - pub const protected_vtable: parser.dom_element_protected_vtable = .{ + vtable: parser.c.dom_html_element_vtable = parser.c._dom_html_element_vtable, // TODO make global, instantiate value and cast to void probably + protected_vtable: parser.c.dom_element_protected_vtable = .{ .dom_node_copy = dom_node_copy, // .dom_node_destroy = dom_node_destroy, // Not needed in zig .dom_initialise = dom_initialise, - }; + }, base: parser.ElementHTML, // Should instead have 2 vtable fields to generate the creation function - pub fn dom_create(params: *parser.dom_html_element_create_params, page: *Page) !*parser.HtmlElement { + pub fn dom_create(params: *parser.c.dom_html_element_create_params, page: *Page) !*parser.ElementHTML { var self = try page.arena.create(HTMLInputElement); // Put in pool? self.base.base.base.vtable = &HTMLInputElement.vtable; self.base.base.vtable = &HTMLInputElement.protected_vtable; // set vtable and protected vtable - self.initialise(params); + self.dom_initialise(params); return self.base; } // Initialise is separated from create such that the leaf type sets the vtable, then calls all the way up the protochain to init // Currently we do only leaf types tho - pub fn dom_initialise(self: *HTMLInputElement, params: *parser.dom_html_element_create_params) !void { - return parser._dom_html_element_initialise(params, &self.base); + pub fn dom_initialise(self: *HTMLInputElement, params: *parser.c.dom_html_element_create_params) parser.c.dom_exception { + return parser.c._dom_html_element_initialise(params, &self.base); } // This should always be the same and we should not have cleanup for new zig implementation, hopefully diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index 03db92e2..e480074e 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -18,7 +18,7 @@ const std = @import("std"); -const c = @cImport({ +pub const c = @cImport({ @cInclude("dom/dom.h"); @cInclude("core/pi.h"); @cInclude("dom/bindings/hubbub/parser.h"); @@ -1989,7 +1989,9 @@ pub inline fn domImplementationCreateDocumentType( return dt.?; } -pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8) !*DocumentHTML { +pub const CreateElementFn = ?*const fn ([*c]DocumentHTML, [*c]c.dom_html_element_create_params, [*c][*c]ElementHTML) callconv(.c) c.dom_exception; + +pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8, create_element: CreateElementFn) !*DocumentHTML { const doc_html = try documentCreateDocument(title); const doc = documentHTMLToDocument(doc_html); @@ -2010,6 +2012,7 @@ pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8) !*Document const body = try documentCreateElement(doc, "body"); _ = try nodeAppendChild(elementToNode(html), elementToNode(body)); + doc_html.create_element_external = create_element; return doc_html; } @@ -2085,6 +2088,9 @@ pub inline fn documentCreateDocument(title: ?[]const u8) !*DocumentHTML { try DOMErr(err); const doc_html = @as(*DocumentHTML, @ptrCast(doc.?)); if (title) |t| try documentHTMLSetTitle(doc_html, t); + + // doc_html.create_element_external = + return doc_html; } diff --git a/vendor/netsurf/libdom b/vendor/netsurf/libdom index 614187b0..af1b1757 160000 --- a/vendor/netsurf/libdom +++ b/vendor/netsurf/libdom @@ -1 +1 @@ -Subproject commit 614187b0aa6305ff992b4e0cb24af2e3ca0c4bfc +Subproject commit af1b1757ad9b1bbdb1eff8d8420bce1c167b8fcc