mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
DOMImplementation and DocumentType skeletons
This commit is contained in:
@@ -26,6 +26,7 @@ pub fn deep(node: *Node, opts: Opts, writer: *std.Io.Writer) error{WriteFailed}!
|
||||
}
|
||||
},
|
||||
.document => try children(node, opts, writer),
|
||||
.document_type => {},
|
||||
.document_fragment => try children(node, opts, writer),
|
||||
.attribute => unreachable,
|
||||
}
|
||||
@@ -49,6 +50,9 @@ pub fn toJSON(node: *Node, writer: *std.json.Stringify) !void {
|
||||
.document => {
|
||||
try writer.write("document");
|
||||
},
|
||||
.document_type => {
|
||||
try writer.write("document_type");
|
||||
},
|
||||
.element => |*el| {
|
||||
try writer.write("element");
|
||||
try writer.objectField("tag");
|
||||
|
||||
@@ -446,7 +446,9 @@ pub const JsApis = flattenTypes(&.{
|
||||
@import("../webapi/HTMLDocument.zig"),
|
||||
@import("../webapi/KeyValueList.zig"),
|
||||
@import("../webapi/DocumentFragment.zig"),
|
||||
@import("../webapi/DocumentType.zig"),
|
||||
@import("../webapi/DOMException.zig"),
|
||||
@import("../webapi/DOMImplementation.zig"),
|
||||
@import("../webapi/DOMTreeWalker.zig"),
|
||||
@import("../webapi/DOMNodeIterator.zig"),
|
||||
@import("../webapi/NodeFilter.zig"),
|
||||
|
||||
61
src/browser/tests/domimplementation.html
Normal file
61
src/browser/tests/domimplementation.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>DOMImplementation Test</title>
|
||||
<script src="testing.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
|
||||
<script id=implementation>
|
||||
{
|
||||
const impl = document.implementation;
|
||||
testing.expectEqual('[object DOMImplementation]', impl.toString());
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=hasFeature>
|
||||
{
|
||||
const impl = document.implementation;
|
||||
testing.expectEqual(true, impl.hasFeature('XML', '1.0'));
|
||||
testing.expectEqual(true, impl.hasFeature('HTML', '2.0'));
|
||||
testing.expectEqual(true, impl.hasFeature('', null));
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createDocumentType>
|
||||
{
|
||||
const impl = document.implementation;
|
||||
const doctype = impl.createDocumentType('html', '', '');
|
||||
testing.expectEqual(10, doctype.nodeType);
|
||||
testing.expectEqual('html', doctype.nodeName);
|
||||
testing.expectEqual('html', doctype.name);
|
||||
testing.expectEqual('', doctype.publicId);
|
||||
testing.expectEqual('', doctype.systemId);
|
||||
testing.expectEqual('[object DocumentType]', doctype.toString());
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createDocumentTypeWithIds>
|
||||
{
|
||||
const impl = document.implementation;
|
||||
const doctype = impl.createDocumentType(
|
||||
'svg',
|
||||
'-//W3C//DTD SVG 1.1//EN',
|
||||
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
|
||||
);
|
||||
testing.expectEqual('svg', doctype.name);
|
||||
testing.expectEqual('-//W3C//DTD SVG 1.1//EN', doctype.publicId);
|
||||
testing.expectEqual('http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd', doctype.systemId);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id=createDocumentTypeNullIds>
|
||||
{
|
||||
const impl = document.implementation;
|
||||
const doctype = impl.createDocumentType('html', null, null);
|
||||
testing.expectEqual('html', doctype.name);
|
||||
testing.expectEqual('', doctype.publicId);
|
||||
testing.expectEqual('', doctype.systemId);
|
||||
}
|
||||
</script>
|
||||
57
src/browser/webapi/DOMImplementation.zig
Normal file
57
src/browser/webapi/DOMImplementation.zig
Normal file
@@ -0,0 +1,57 @@
|
||||
const std = @import("std");
|
||||
|
||||
const js = @import("../js/js.zig");
|
||||
const Page = @import("../Page.zig");
|
||||
const Node = @import("Node.zig");
|
||||
const DocumentType = @import("DocumentType.zig");
|
||||
|
||||
const DOMImplementation = @This();
|
||||
|
||||
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);
|
||||
const pub_id = try page.dupeString(public_id orelse "");
|
||||
const sys_id = try page.dupeString(system_id orelse "");
|
||||
|
||||
const doctype = try page._factory.node(DocumentType{
|
||||
._proto = undefined,
|
||||
._name = name,
|
||||
._public_id = pub_id,
|
||||
._system_id = sys_id,
|
||||
});
|
||||
|
||||
return doctype;
|
||||
}
|
||||
|
||||
pub fn hasFeature(_: *const DOMImplementation, _: []const u8, _: ?[]const u8) bool {
|
||||
// Modern DOM spec says this should always return true
|
||||
// This method is deprecated and kept for compatibility only
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn className(_: *const DOMImplementation) []const u8 {
|
||||
return "[object DOMImplementation]";
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(DOMImplementation);
|
||||
|
||||
pub const Meta = struct {
|
||||
pub const name = "DOMImplementation";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_index: u16 = 0;
|
||||
pub const empty_with_no_proto = true;
|
||||
};
|
||||
|
||||
pub const createDocumentType = bridge.function(DOMImplementation.createDocumentType, .{ .dom_exception = true });
|
||||
pub const hasFeature = bridge.function(DOMImplementation.hasFeature, .{});
|
||||
|
||||
pub const toString = bridge.function(_toString, .{});
|
||||
fn _toString(_: *const DOMImplementation) []const u8 {
|
||||
return "[object DOMImplementation]";
|
||||
}
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "WebApi: DOMImplementation" {
|
||||
try testing.htmlRunner("domimplementation.html", .{});
|
||||
}
|
||||
@@ -12,6 +12,7 @@ const Selector = @import("selector/Selector.zig");
|
||||
const NodeFilter = @import("NodeFilter.zig");
|
||||
const DOMTreeWalker = @import("DOMTreeWalker.zig");
|
||||
const DOMNodeIterator = @import("DOMNodeIterator.zig");
|
||||
const DOMImplementation = @import("DOMImplementation.zig");
|
||||
|
||||
pub const HTMLDocument = @import("HTMLDocument.zig");
|
||||
|
||||
@@ -124,6 +125,10 @@ pub fn className(_: *const Document) []const u8 {
|
||||
return "[object Document]";
|
||||
}
|
||||
|
||||
pub fn getImplementation(_: *const Document) DOMImplementation {
|
||||
return .{};
|
||||
}
|
||||
|
||||
pub fn createDocumentFragment(_: *const Document, page: *Page) !*@import("DocumentFragment.zig") {
|
||||
return @import("DocumentFragment.zig").init(page);
|
||||
}
|
||||
@@ -176,6 +181,7 @@ pub const JsApi = struct {
|
||||
pub const URL = bridge.accessor(Document.getURL, null, .{});
|
||||
pub const documentElement = bridge.accessor(Document.getDocumentElement, null, .{});
|
||||
pub const readyState = bridge.accessor(Document.getReadyState, null, .{});
|
||||
pub const implementation = bridge.accessor(Document.getImplementation, null, .{});
|
||||
|
||||
pub const createElement = bridge.function(Document.createElement, .{});
|
||||
pub const createElementNS = bridge.function(Document.createElementNS, .{});
|
||||
|
||||
60
src/browser/webapi/DocumentType.zig
Normal file
60
src/browser/webapi/DocumentType.zig
Normal file
@@ -0,0 +1,60 @@
|
||||
const std = @import("std");
|
||||
|
||||
const js = @import("../js/js.zig");
|
||||
const Page = @import("../Page.zig");
|
||||
const Node = @import("Node.zig");
|
||||
|
||||
const DocumentType = @This();
|
||||
|
||||
_proto: *Node,
|
||||
_name: []const u8,
|
||||
_public_id: []const u8,
|
||||
_system_id: []const u8,
|
||||
|
||||
pub fn asNode(self: *DocumentType) *Node {
|
||||
return self._proto;
|
||||
}
|
||||
|
||||
pub fn asEventTarget(self: *DocumentType) *@import("EventTarget.zig") {
|
||||
return self._proto.asEventTarget();
|
||||
}
|
||||
|
||||
pub fn getName(self: *const DocumentType) []const u8 {
|
||||
return self._name;
|
||||
}
|
||||
|
||||
pub fn getPublicId(self: *const DocumentType) []const u8 {
|
||||
return self._public_id;
|
||||
}
|
||||
|
||||
pub fn getSystemId(self: *const DocumentType) []const u8 {
|
||||
return self._system_id;
|
||||
}
|
||||
|
||||
pub fn className(_: *const DocumentType) []const u8 {
|
||||
return "[object DocumentType]";
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(DocumentType);
|
||||
|
||||
pub const Meta = struct {
|
||||
pub const name = "DocumentType";
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_index: u16 = 0;
|
||||
};
|
||||
|
||||
pub const name = bridge.accessor(DocumentType.getName, null, .{});
|
||||
pub const publicId = bridge.accessor(DocumentType.getPublicId, null, .{});
|
||||
pub const systemId = bridge.accessor(DocumentType.getSystemId, null, .{});
|
||||
|
||||
pub const toString = bridge.function(_toString, .{});
|
||||
fn _toString(self: *const DocumentType) []const u8 {
|
||||
return self.className();
|
||||
}
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "WebApi: DOMImplementation" {
|
||||
try testing.htmlRunner("domimplementation.html", .{});
|
||||
}
|
||||
@@ -11,8 +11,10 @@ const collections = @import("collections.zig");
|
||||
pub const CData = @import("CData.zig");
|
||||
pub const Element = @import("Element.zig");
|
||||
pub const Document = @import("Document.zig");
|
||||
pub const HTMLDocument = @import("HTMLDocument.zig");
|
||||
pub const Children = @import("children.zig").Children;
|
||||
pub const DocumentFragment = @import("DocumentFragment.zig");
|
||||
pub const DocumentType = @import("DocumentType.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const LinkedList = std.DoublyLinkedList;
|
||||
@@ -29,6 +31,7 @@ pub const Type = union(enum) {
|
||||
cdata: *CData,
|
||||
element: *Element,
|
||||
document: *Document,
|
||||
document_type: *DocumentType,
|
||||
attribute: *Element.Attribute,
|
||||
document_fragment: *DocumentFragment,
|
||||
};
|
||||
@@ -76,6 +79,11 @@ pub fn is(self: *Node, comptime T: type) ?*T {
|
||||
return doc.is(T);
|
||||
}
|
||||
},
|
||||
.document_type => |dt| {
|
||||
if (T == DocumentType) {
|
||||
return dt;
|
||||
}
|
||||
},
|
||||
.document_fragment => |doc| {
|
||||
if (T == DocumentFragment) {
|
||||
return doc;
|
||||
@@ -145,6 +153,7 @@ pub fn getTextContent(self: *Node, writer: *std.Io.Writer) error{WriteFailed}!vo
|
||||
.element => |el| return el.getInnerText(writer),
|
||||
.cdata => |c| try writer.writeAll(c.getData()),
|
||||
.document => {},
|
||||
.document_type => {},
|
||||
.document_fragment => {},
|
||||
.attribute => |attr| try writer.writeAll(attr._value),
|
||||
}
|
||||
@@ -163,6 +172,7 @@ pub fn setTextContent(self: *Node, data: []const u8, page: *Page) !void {
|
||||
.element => |el| return el.replaceChildren(&.{.{ .text = data }}, page),
|
||||
.cdata => |c| c._data = try page.arena.dupe(u8, data),
|
||||
.document => {},
|
||||
.document_type => {},
|
||||
.document_fragment => {},
|
||||
.attribute => |attr| return attr.setValue(data, page),
|
||||
}
|
||||
@@ -176,6 +186,7 @@ pub fn getNodeName(self: *const Node, page: *Page) ![]const u8 {
|
||||
.comment => "#comment",
|
||||
},
|
||||
.document => "#document",
|
||||
.document_type => |dt| dt.getName(),
|
||||
.document_fragment => "#document-fragment",
|
||||
.attribute => |attr| attr._name,
|
||||
};
|
||||
@@ -190,6 +201,7 @@ pub fn nodeType(self: *const Node) u8 {
|
||||
.comment => 8,
|
||||
},
|
||||
.document => 9,
|
||||
.document_type => 10,
|
||||
.document_fragment => 11,
|
||||
};
|
||||
}
|
||||
@@ -333,6 +345,7 @@ pub fn getNodeValue(self: *const Node) ?[]const u8 {
|
||||
.attribute => |attr| attr._value,
|
||||
.element => null,
|
||||
.document => null,
|
||||
.document_type => null,
|
||||
.document_fragment => null,
|
||||
};
|
||||
}
|
||||
@@ -343,6 +356,7 @@ pub fn setNodeValue(self: *const Node, value: ?[]const u8, page: *Page) !void {
|
||||
.attribute => |attr| try attr.setValue(value, page),
|
||||
.element => {},
|
||||
.document => {},
|
||||
.document_type => {},
|
||||
.document_fragment => {},
|
||||
}
|
||||
}
|
||||
@@ -350,11 +364,11 @@ pub fn setNodeValue(self: *const Node, value: ?[]const u8, page: *Page) !void {
|
||||
pub fn format(self: *Node, writer: *std.Io.Writer) !void {
|
||||
// // If you need extra debugging:
|
||||
// return @import("../dump.zig").deep(self, .{}, writer);
|
||||
|
||||
return switch (self._type) {
|
||||
.cdata => |cd| cd.format(writer),
|
||||
.element => |el| writer.print("{f}", .{el}),
|
||||
.document => writer.writeAll("<document>"),
|
||||
.document_type => writer.writeAll("<doctype>"),
|
||||
.document_fragment => writer.writeAll("<document_fragment>"),
|
||||
.attribute => |attr| writer.print("{f}", .{attr}),
|
||||
};
|
||||
@@ -380,8 +394,7 @@ pub fn className(self: *const Node) []const u8 {
|
||||
|
||||
pub fn normalize(self: *Node, page: *Page) !void {
|
||||
var buffer: std.ArrayListUnmanaged(u8) = .empty;
|
||||
const arena = page.call_arena;
|
||||
return self._normalize(arena, &buffer, page);
|
||||
return self._normalize(page.call_arena, &buffer, page);
|
||||
}
|
||||
|
||||
pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, StringTooLarge, NotSupported, NotImplemented }!*Node {
|
||||
@@ -396,6 +409,7 @@ pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, Str
|
||||
},
|
||||
.element => |el| return el.cloneElement(deep, page),
|
||||
.document => return error.NotSupported,
|
||||
.document_type => return error.NotSupported,
|
||||
.document_fragment => return error.NotImplemented,
|
||||
.attribute => return error.NotSupported,
|
||||
}
|
||||
@@ -612,6 +626,7 @@ pub const JsApi = struct {
|
||||
.cdata => |cdata| return cdata.getData(),
|
||||
.attribute => |attr| return attr._value,
|
||||
.document => return null,
|
||||
.document_type => return null,
|
||||
.document_fragment => return null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +249,7 @@ pub const JsApi = struct {
|
||||
|
||||
pub const self = bridge.accessor(Window.getWindow, null, .{ .cache = "self" });
|
||||
pub const window = bridge.accessor(Window.getWindow, null, .{ .cache = "window" });
|
||||
pub const parent = bridge.accessor(Window.getWindow, null, .{ .cache = "parent" });
|
||||
pub const console = bridge.accessor(Window.getConsole, null, .{ .cache = "console" });
|
||||
pub const navigator = bridge.accessor(Window.getNavigator, null, .{ .cache = "navigator" });
|
||||
pub const localStorage = bridge.accessor(Window.getLocalStorage, null, .{ .cache = "localStorage" });
|
||||
|
||||
Reference in New Issue
Block a user