mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 08:18:59 +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 => try children(node, opts, writer),
|
||||||
|
.document_type => {},
|
||||||
.document_fragment => try children(node, opts, writer),
|
.document_fragment => try children(node, opts, writer),
|
||||||
.attribute => unreachable,
|
.attribute => unreachable,
|
||||||
}
|
}
|
||||||
@@ -49,6 +50,9 @@ pub fn toJSON(node: *Node, writer: *std.json.Stringify) !void {
|
|||||||
.document => {
|
.document => {
|
||||||
try writer.write("document");
|
try writer.write("document");
|
||||||
},
|
},
|
||||||
|
.document_type => {
|
||||||
|
try writer.write("document_type");
|
||||||
|
},
|
||||||
.element => |*el| {
|
.element => |*el| {
|
||||||
try writer.write("element");
|
try writer.write("element");
|
||||||
try writer.objectField("tag");
|
try writer.objectField("tag");
|
||||||
|
|||||||
@@ -446,7 +446,9 @@ pub const JsApis = flattenTypes(&.{
|
|||||||
@import("../webapi/HTMLDocument.zig"),
|
@import("../webapi/HTMLDocument.zig"),
|
||||||
@import("../webapi/KeyValueList.zig"),
|
@import("../webapi/KeyValueList.zig"),
|
||||||
@import("../webapi/DocumentFragment.zig"),
|
@import("../webapi/DocumentFragment.zig"),
|
||||||
|
@import("../webapi/DocumentType.zig"),
|
||||||
@import("../webapi/DOMException.zig"),
|
@import("../webapi/DOMException.zig"),
|
||||||
|
@import("../webapi/DOMImplementation.zig"),
|
||||||
@import("../webapi/DOMTreeWalker.zig"),
|
@import("../webapi/DOMTreeWalker.zig"),
|
||||||
@import("../webapi/DOMNodeIterator.zig"),
|
@import("../webapi/DOMNodeIterator.zig"),
|
||||||
@import("../webapi/NodeFilter.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 NodeFilter = @import("NodeFilter.zig");
|
||||||
const DOMTreeWalker = @import("DOMTreeWalker.zig");
|
const DOMTreeWalker = @import("DOMTreeWalker.zig");
|
||||||
const DOMNodeIterator = @import("DOMNodeIterator.zig");
|
const DOMNodeIterator = @import("DOMNodeIterator.zig");
|
||||||
|
const DOMImplementation = @import("DOMImplementation.zig");
|
||||||
|
|
||||||
pub const HTMLDocument = @import("HTMLDocument.zig");
|
pub const HTMLDocument = @import("HTMLDocument.zig");
|
||||||
|
|
||||||
@@ -124,6 +125,10 @@ pub fn className(_: *const Document) []const u8 {
|
|||||||
return "[object Document]";
|
return "[object Document]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getImplementation(_: *const Document) DOMImplementation {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn createDocumentFragment(_: *const Document, page: *Page) !*@import("DocumentFragment.zig") {
|
pub fn createDocumentFragment(_: *const Document, page: *Page) !*@import("DocumentFragment.zig") {
|
||||||
return @import("DocumentFragment.zig").init(page);
|
return @import("DocumentFragment.zig").init(page);
|
||||||
}
|
}
|
||||||
@@ -176,6 +181,7 @@ pub const JsApi = struct {
|
|||||||
pub const URL = bridge.accessor(Document.getURL, null, .{});
|
pub const URL = bridge.accessor(Document.getURL, null, .{});
|
||||||
pub const documentElement = bridge.accessor(Document.getDocumentElement, null, .{});
|
pub const documentElement = bridge.accessor(Document.getDocumentElement, null, .{});
|
||||||
pub const readyState = bridge.accessor(Document.getReadyState, 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 createElement = bridge.function(Document.createElement, .{});
|
||||||
pub const createElementNS = bridge.function(Document.createElementNS, .{});
|
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 CData = @import("CData.zig");
|
||||||
pub const Element = @import("Element.zig");
|
pub const Element = @import("Element.zig");
|
||||||
pub const Document = @import("Document.zig");
|
pub const Document = @import("Document.zig");
|
||||||
|
pub const HTMLDocument = @import("HTMLDocument.zig");
|
||||||
pub const Children = @import("children.zig").Children;
|
pub const Children = @import("children.zig").Children;
|
||||||
pub const DocumentFragment = @import("DocumentFragment.zig");
|
pub const DocumentFragment = @import("DocumentFragment.zig");
|
||||||
|
pub const DocumentType = @import("DocumentType.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const LinkedList = std.DoublyLinkedList;
|
const LinkedList = std.DoublyLinkedList;
|
||||||
@@ -29,6 +31,7 @@ pub const Type = union(enum) {
|
|||||||
cdata: *CData,
|
cdata: *CData,
|
||||||
element: *Element,
|
element: *Element,
|
||||||
document: *Document,
|
document: *Document,
|
||||||
|
document_type: *DocumentType,
|
||||||
attribute: *Element.Attribute,
|
attribute: *Element.Attribute,
|
||||||
document_fragment: *DocumentFragment,
|
document_fragment: *DocumentFragment,
|
||||||
};
|
};
|
||||||
@@ -76,6 +79,11 @@ pub fn is(self: *Node, comptime T: type) ?*T {
|
|||||||
return doc.is(T);
|
return doc.is(T);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.document_type => |dt| {
|
||||||
|
if (T == DocumentType) {
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
},
|
||||||
.document_fragment => |doc| {
|
.document_fragment => |doc| {
|
||||||
if (T == DocumentFragment) {
|
if (T == DocumentFragment) {
|
||||||
return doc;
|
return doc;
|
||||||
@@ -145,6 +153,7 @@ pub fn getTextContent(self: *Node, writer: *std.Io.Writer) error{WriteFailed}!vo
|
|||||||
.element => |el| return el.getInnerText(writer),
|
.element => |el| return el.getInnerText(writer),
|
||||||
.cdata => |c| try writer.writeAll(c.getData()),
|
.cdata => |c| try writer.writeAll(c.getData()),
|
||||||
.document => {},
|
.document => {},
|
||||||
|
.document_type => {},
|
||||||
.document_fragment => {},
|
.document_fragment => {},
|
||||||
.attribute => |attr| try writer.writeAll(attr._value),
|
.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),
|
.element => |el| return el.replaceChildren(&.{.{ .text = data }}, page),
|
||||||
.cdata => |c| c._data = try page.arena.dupe(u8, data),
|
.cdata => |c| c._data = try page.arena.dupe(u8, data),
|
||||||
.document => {},
|
.document => {},
|
||||||
|
.document_type => {},
|
||||||
.document_fragment => {},
|
.document_fragment => {},
|
||||||
.attribute => |attr| return attr.setValue(data, page),
|
.attribute => |attr| return attr.setValue(data, page),
|
||||||
}
|
}
|
||||||
@@ -176,6 +186,7 @@ pub fn getNodeName(self: *const Node, page: *Page) ![]const u8 {
|
|||||||
.comment => "#comment",
|
.comment => "#comment",
|
||||||
},
|
},
|
||||||
.document => "#document",
|
.document => "#document",
|
||||||
|
.document_type => |dt| dt.getName(),
|
||||||
.document_fragment => "#document-fragment",
|
.document_fragment => "#document-fragment",
|
||||||
.attribute => |attr| attr._name,
|
.attribute => |attr| attr._name,
|
||||||
};
|
};
|
||||||
@@ -190,6 +201,7 @@ pub fn nodeType(self: *const Node) u8 {
|
|||||||
.comment => 8,
|
.comment => 8,
|
||||||
},
|
},
|
||||||
.document => 9,
|
.document => 9,
|
||||||
|
.document_type => 10,
|
||||||
.document_fragment => 11,
|
.document_fragment => 11,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -333,6 +345,7 @@ pub fn getNodeValue(self: *const Node) ?[]const u8 {
|
|||||||
.attribute => |attr| attr._value,
|
.attribute => |attr| attr._value,
|
||||||
.element => null,
|
.element => null,
|
||||||
.document => null,
|
.document => null,
|
||||||
|
.document_type => null,
|
||||||
.document_fragment => 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),
|
.attribute => |attr| try attr.setValue(value, page),
|
||||||
.element => {},
|
.element => {},
|
||||||
.document => {},
|
.document => {},
|
||||||
|
.document_type => {},
|
||||||
.document_fragment => {},
|
.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 {
|
pub fn format(self: *Node, writer: *std.Io.Writer) !void {
|
||||||
// // If you need extra debugging:
|
// // If you need extra debugging:
|
||||||
// return @import("../dump.zig").deep(self, .{}, writer);
|
// return @import("../dump.zig").deep(self, .{}, writer);
|
||||||
|
|
||||||
return switch (self._type) {
|
return switch (self._type) {
|
||||||
.cdata => |cd| cd.format(writer),
|
.cdata => |cd| cd.format(writer),
|
||||||
.element => |el| writer.print("{f}", .{el}),
|
.element => |el| writer.print("{f}", .{el}),
|
||||||
.document => writer.writeAll("<document>"),
|
.document => writer.writeAll("<document>"),
|
||||||
|
.document_type => writer.writeAll("<doctype>"),
|
||||||
.document_fragment => writer.writeAll("<document_fragment>"),
|
.document_fragment => writer.writeAll("<document_fragment>"),
|
||||||
.attribute => |attr| writer.print("{f}", .{attr}),
|
.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 {
|
pub fn normalize(self: *Node, page: *Page) !void {
|
||||||
var buffer: std.ArrayListUnmanaged(u8) = .empty;
|
var buffer: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
const arena = page.call_arena;
|
return self._normalize(page.call_arena, &buffer, page);
|
||||||
return self._normalize(arena, &buffer, page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) error{ OutOfMemory, StringTooLarge, NotSupported, NotImplemented }!*Node {
|
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),
|
.element => |el| return el.cloneElement(deep, page),
|
||||||
.document => return error.NotSupported,
|
.document => return error.NotSupported,
|
||||||
|
.document_type => return error.NotSupported,
|
||||||
.document_fragment => return error.NotImplemented,
|
.document_fragment => return error.NotImplemented,
|
||||||
.attribute => return error.NotSupported,
|
.attribute => return error.NotSupported,
|
||||||
}
|
}
|
||||||
@@ -612,6 +626,7 @@ pub const JsApi = struct {
|
|||||||
.cdata => |cdata| return cdata.getData(),
|
.cdata => |cdata| return cdata.getData(),
|
||||||
.attribute => |attr| return attr._value,
|
.attribute => |attr| return attr._value,
|
||||||
.document => return null,
|
.document => return null,
|
||||||
|
.document_type => return null,
|
||||||
.document_fragment => 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 self = bridge.accessor(Window.getWindow, null, .{ .cache = "self" });
|
||||||
pub const window = bridge.accessor(Window.getWindow, null, .{ .cache = "window" });
|
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 console = bridge.accessor(Window.getConsole, null, .{ .cache = "console" });
|
||||||
pub const navigator = bridge.accessor(Window.getNavigator, null, .{ .cache = "navigator" });
|
pub const navigator = bridge.accessor(Window.getNavigator, null, .{ .cache = "navigator" });
|
||||||
pub const localStorage = bridge.accessor(Window.getLocalStorage, null, .{ .cache = "localStorage" });
|
pub const localStorage = bridge.accessor(Window.getLocalStorage, null, .{ .cache = "localStorage" });
|
||||||
|
|||||||
Reference in New Issue
Block a user