diff --git a/src/browser/dom/character_data.zig b/src/browser/dom/character_data.zig index a3c35a4b..7a4e0f3a 100644 --- a/src/browser/dom/character_data.zig +++ b/src/browser/dom/character_data.zig @@ -97,6 +97,21 @@ pub const CharacterData = struct { pub fn _substringData(self: *parser.CharacterData, offset: u32, count: u32) ![]const u8 { return try parser.characterDataSubstringData(self, offset, count); } + + // netsurf's CharacterData (text, comment) doesn't implement the + // dom_node_get_attributes and thus will crash if we try to call nodeIsEqualNode. + pub fn _isEqualNode(self: *parser.CharacterData, other_node: *parser.Node) !bool { + if (try parser.nodeType(@ptrCast(self)) != try parser.nodeType(other_node)) { + return false; + } + + const other: *parser.CharacterData = @ptrCast(other_node); + if (std.mem.eql(u8, try get_data(self), try get_data(other)) == false) { + return false; + } + + return true; + } }; // Tests @@ -163,4 +178,9 @@ test "Browser.DOM.CharacterData" { .{ "cdata.substringData('OK'.length-1, 'replaced'.length) == 'replaced'", "true" }, .{ "cdata.substringData('OK'.length-1, 0) == ''", "true" }, }, .{}); + + try runner.testCases(&.{ + .{ "cdata.substringData('OK'.length-1, 'replaced'.length) == 'replaced'", "true" }, + .{ "cdata.substringData('OK'.length-1, 0) == ''", "true" }, + }, .{}); } diff --git a/src/browser/dom/document_fragment.zig b/src/browser/dom/document_fragment.zig index 0288dcb5..03884b1c 100644 --- a/src/browser/dom/document_fragment.zig +++ b/src/browser/dom/document_fragment.zig @@ -34,6 +34,15 @@ pub const DocumentFragment = struct { parser.documentHTMLToDocument(state.document.?), ); } + + pub fn _isEqualNode(self: *parser.DocumentFragment, other_node: *parser.Node) !bool { + const other_type = try parser.nodeType(other_node); + if (other_type != .document_fragment) { + return false; + } + _ = self; + return true; + } }; const testing = @import("../../testing.zig"); @@ -45,4 +54,11 @@ test "Browser.DOM.DocumentFragment" { .{ "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" }, + }, .{}); } diff --git a/src/browser/dom/document_type.zig b/src/browser/dom/document_type.zig index 6cdc4a45..d4425dc2 100644 --- a/src/browser/dom/document_type.zig +++ b/src/browser/dom/document_type.zig @@ -39,4 +39,42 @@ pub const DocumentType = struct { pub fn get_systemId(self: *parser.DocumentType) ![]const u8 { return try parser.documentTypeGetSystemId(self); } + + // netsurf's DocumentType doesn't implement the dom_node_get_attributes + // and thus will crash if we try to call nodeIsEqualNode. + pub fn _isEqualNode(self: *parser.DocumentType, other_node: *parser.Node) !bool { + if (try parser.nodeType(other_node) != .document_type) { + return false; + } + + const other: *parser.DocumentType = @ptrCast(other_node); + if (std.mem.eql(u8, try get_name(self), try get_name(other)) == false) { + return false; + } + if (std.mem.eql(u8, try get_publicId(self), try get_publicId(other)) == false) { + return false; + } + if (std.mem.eql(u8, try get_systemId(self), try get_systemId(other)) == false) { + return false; + } + return true; + } }; + +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" }, + }, .{}); +} diff --git a/src/browser/dom/processing_instruction.zig b/src/browser/dom/processing_instruction.zig index baf426cb..d72e4c97 100644 --- a/src/browser/dom/processing_instruction.zig +++ b/src/browser/dom/processing_instruction.zig @@ -46,6 +46,36 @@ pub const ProcessingInstruction = struct { pub fn set_data(self: *parser.ProcessingInstruction, data: []u8) !void { try parser.nodeSetValue(parser.processingInstructionToNode(self), data); } + + // netsurf's ProcessInstruction doesn't implement the dom_node_get_attributes + // and thus will crash if we try to call nodeIsEqualNode. + pub fn _isEqualNode(self: *parser.ProcessingInstruction, other_node: *parser.Node) !bool { + if (try parser.nodeType(other_node) != .processing_instruction) { + return false; + } + + const other: *parser.ProcessingInstruction = @ptrCast(other_node); + + if (std.mem.eql(u8, try get_target(self), try get_target(other)) == false) { + return false; + } + + { + const self_data = try get_data(self); + const other_data = try get_data(other); + if (self_data == null and other_data != null) { + return false; + } + if (self_data != null and other_data == null) { + return false; + } + if (std.mem.eql(u8, self_data.?, other_data.?) == false) { + return false; + } + } + + return true; + } }; const testing = @import("../../testing.zig"); @@ -62,4 +92,16 @@ test "Browser.DOM.ProcessingInstruction" { .{ "let pi2 = pi.cloneNode()", "undefined" }, }, .{}); + + try runner.testCases(&.{ + .{ "let pi11 = document.createProcessingInstruction('target1', 'data1');", "undefined" }, + .{ "let pi12 = document.createProcessingInstruction('target2', 'data2');", "undefined" }, + .{ "let pi13 = document.createProcessingInstruction('target1', 'data1');", "undefined" }, + .{ "pi11.isEqualNode(pi11)", "true" }, + .{ "pi11.isEqualNode(pi13)", "true" }, + .{ "pi11.isEqualNode(pi12)", "false" }, + .{ "pi12.isEqualNode(pi13)", "false" }, + .{ "pi11.isEqualNode(document)", "false" }, + .{ "document.isEqualNode(pi11)", "false" }, + }, .{}); }