diff --git a/src/browser/webapi/DOMImplementation.zig b/src/browser/webapi/DOMImplementation.zig index 743cdd95..82405cdd 100644 --- a/src/browser/webapi/DOMImplementation.zig +++ b/src/browser/webapi/DOMImplementation.zig @@ -28,19 +28,7 @@ const DOMImplementation = @This(); _pad: bool = false, pub fn createDocumentType(_: *const DOMImplementation, qualified_name: []const u8, public_id: ?[]const u8, system_id: ?[]const u8, page: *Page) !*DocumentType { - const name = try page.dupeString(qualified_name); - // Firefox converts null to the string "null", not empty string - const pub_id = if (public_id) |p| try page.dupeString(p) else "null"; - const sys_id = if (system_id) |s| try page.dupeString(s) else "null"; - - const doctype = try page._factory.node(DocumentType{ - ._proto = undefined, - ._name = name, - ._public_id = pub_id, - ._system_id = sys_id, - }); - - return doctype; + return DocumentType.init(qualified_name, public_id, system_id, page); } pub fn createHTMLDocument(_: *const DOMImplementation, title: ?[]const u8, page: *Page) !*Document { diff --git a/src/browser/webapi/DocumentType.zig b/src/browser/webapi/DocumentType.zig index b5429c70..babda434 100644 --- a/src/browser/webapi/DocumentType.zig +++ b/src/browser/webapi/DocumentType.zig @@ -19,6 +19,8 @@ const std = @import("std"); const js = @import("../js/js.zig"); +const Page = @import("../Page.zig"); + const Node = @import("Node.zig"); const DocumentType = @This(); @@ -28,6 +30,20 @@ _name: []const u8, _public_id: []const u8, _system_id: []const u8, +pub fn init(qualified_name: []const u8, public_id: ?[]const u8, system_id: ?[]const u8, page: *Page) !*DocumentType { + const name = try page.dupeString(qualified_name); + // Firefox converts null to the string "null", not empty string + const pub_id = if (public_id) |p| try page.dupeString(p) else "null"; + const sys_id = if (system_id) |s| try page.dupeString(s) else "null"; + + return page._factory.node(DocumentType{ + ._proto = undefined, + ._name = name, + ._public_id = pub_id, + ._system_id = sys_id, + }); +} + pub fn asNode(self: *DocumentType) *Node { return self._proto; } @@ -54,6 +70,10 @@ pub fn isEqualNode(self: *const DocumentType, other: *const DocumentType) bool { std.mem.eql(u8, self._system_id, other._system_id); } +pub fn clone(self: *const DocumentType, page: *Page) !*DocumentType { + return .init(self._name, self._public_id, self._system_id, page); +} + pub const JsApi = struct { pub const bridge = js.Bridge(DocumentType); diff --git a/src/browser/webapi/Element.zig b/src/browser/webapi/Element.zig index d7464661..ec4fc2e6 100644 --- a/src/browser/webapi/Element.zig +++ b/src/browser/webapi/Element.zig @@ -1014,7 +1014,7 @@ pub fn getElementsByClassName(self: *Element, class_name: []const u8, page: *Pag return collections.NodeLive(.class_name).init(self.asNode(), class_names.items, page); } -pub fn cloneElement(self: *Element, deep: bool, page: *Page) !*Node { +pub fn clone(self: *Element, deep: bool, page: *Page) !*Node { const tag_name = self.getTagNameDump(); const node = try page.createElementNS(self._namespace, tag_name, self._attributes); diff --git a/src/browser/webapi/Node.zig b/src/browser/webapi/Node.zig index b5dfdebd..03f7ac7f 100644 --- a/src/browser/webapi/Node.zig +++ b/src/browser/webapi/Node.zig @@ -664,7 +664,7 @@ pub fn normalize(self: *Node, page: *Page) !void { return self._normalize(page.call_arena, &buffer, page); } -pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, StringTooLarge, NotSupported, NotImplemented, InvalidCharacterError }!*Node { +pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, StringTooLarge, NotSupported, NotImplemented, InvalidCharacterError, CloneError }!*Node { const deep = deep_ orelse false; switch (self._type) { .cdata => |cd| { @@ -676,11 +676,17 @@ pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, Str .processing_instruction => |pi| page.createProcessingInstruction(pi._target, data), }; }, - .element => |el| return el.cloneElement(deep, page), + .element => |el| return el.clone(deep, page), .document => return error.NotSupported, - .document_type => return error.NotSupported, + .document_type => |dt| { + const cloned = dt.clone(page) catch return error.CloneError; + return cloned.asNode(); + }, .document_fragment => |frag| return frag.cloneFragment(deep, page), - .attribute => return error.NotSupported, + .attribute => |attr| { + const cloned = attr.clone(page) catch return error.CloneError; + return cloned._proto; + }, } } diff --git a/src/browser/webapi/element/Attribute.zig b/src/browser/webapi/element/Attribute.zig index 76e65868..e0252753 100644 --- a/src/browser/webapi/element/Attribute.zig +++ b/src/browser/webapi/element/Attribute.zig @@ -78,6 +78,15 @@ pub fn isEqualNode(self: *const Attribute, other: *const Attribute) bool { return std.mem.eql(u8, self.getName(), other.getName()) and std.mem.eql(u8, self.getValue(), other.getValue()); } +pub fn clone(self: *const Attribute, page: *Page) !*Attribute { + return page._factory.node(Attribute{ + ._proto = undefined, + ._element = self._element, + ._name = self._name, + ._value = self._value, + }); +} + pub const JsApi = struct { pub const bridge = js.Bridge(Attribute);