mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-30 07:31:47 +00:00
@@ -29,57 +29,57 @@ pub const CharacterData = struct {
|
|||||||
|
|
||||||
// Read attributes
|
// Read attributes
|
||||||
|
|
||||||
pub fn get_length(self: *parser.CharacterData) u32 {
|
pub fn get_length(self: *parser.CharacterData) !u32 {
|
||||||
return parser.characterDataLength(self);
|
return try parser.characterDataLength(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_nextElementSibling(self: *parser.CharacterData) ?HTMLElem.Union {
|
pub fn get_nextElementSibling(self: *parser.CharacterData) !?HTMLElem.Union {
|
||||||
const res = parser.nodeNextElementSibling(parser.characterDataToNode(self));
|
const res = try parser.nodeNextElementSibling(parser.characterDataToNode(self));
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return HTMLElem.toInterface(HTMLElem.Union, res.?);
|
return try HTMLElem.toInterface(HTMLElem.Union, res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_previousElementSibling(self: *parser.CharacterData) ?HTMLElem.Union {
|
pub fn get_previousElementSibling(self: *parser.CharacterData) !?HTMLElem.Union {
|
||||||
const res = parser.nodePreviousElementSibling(parser.characterDataToNode(self));
|
const res = try parser.nodePreviousElementSibling(parser.characterDataToNode(self));
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return HTMLElem.toInterface(HTMLElem.Union, res.?);
|
return try HTMLElem.toInterface(HTMLElem.Union, res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read/Write attributes
|
// Read/Write attributes
|
||||||
|
|
||||||
pub fn get_data(self: *parser.CharacterData) []const u8 {
|
pub fn get_data(self: *parser.CharacterData) ![]const u8 {
|
||||||
return parser.characterDataData(self);
|
return try parser.characterDataData(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_data(self: *parser.CharacterData, data: []const u8) void {
|
pub fn set_data(self: *parser.CharacterData, data: []const u8) !void {
|
||||||
return parser.characterDataSetData(self, data);
|
return try parser.characterDataSetData(self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS methods
|
// JS methods
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
pub fn _appendData(self: *parser.CharacterData, data: []const u8) void {
|
pub fn _appendData(self: *parser.CharacterData, data: []const u8) !void {
|
||||||
return parser.characterDataAppendData(self, data);
|
return try parser.characterDataAppendData(self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _deleteData(self: *parser.CharacterData, offset: u32, count: u32) void {
|
pub fn _deleteData(self: *parser.CharacterData, offset: u32, count: u32) !void {
|
||||||
return parser.characterDataDeleteData(self, offset, count);
|
return try parser.characterDataDeleteData(self, offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _insertData(self: *parser.CharacterData, offset: u32, data: []const u8) void {
|
pub fn _insertData(self: *parser.CharacterData, offset: u32, data: []const u8) !void {
|
||||||
return parser.characterDataInsertData(self, offset, data);
|
return try parser.characterDataInsertData(self, offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _replaceData(self: *parser.CharacterData, offset: u32, count: u32, data: []const u8) void {
|
pub fn _replaceData(self: *parser.CharacterData, offset: u32, count: u32, data: []const u8) !void {
|
||||||
return parser.characterDataReplaceData(self, offset, count, data);
|
return try parser.characterDataReplaceData(self, offset, count, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _substringData(self: *parser.CharacterData, offset: u32, count: u32) []const u8 {
|
pub fn _substringData(self: *parser.CharacterData, offset: u32, count: u32) ![]const u8 {
|
||||||
return parser.characterDataSubstringData(self, offset, count);
|
return try parser.characterDataSubstringData(self, offset, count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,28 +22,27 @@ pub const Document = struct {
|
|||||||
pub const prototype = *Node;
|
pub const prototype = *Node;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
pub fn constructor() *parser.Document {
|
pub fn constructor() !*parser.Document {
|
||||||
return parser.domImplementationCreateHTMLDocument(null);
|
return try parser.domImplementationCreateHTMLDocument(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
pub fn get_implementation(_: *parser.Document) DOMImplementation {
|
pub fn get_implementation(_: *parser.Document) DOMImplementation {
|
||||||
return DOMImplementation{};
|
return DOMImplementation{};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_documentElement(self: *parser.Document) ElementUnion {
|
pub fn get_documentElement(self: *parser.Document) !ElementUnion {
|
||||||
const e = parser.documentGetDocumentElement(self);
|
const e = try parser.documentGetDocumentElement(self);
|
||||||
return Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_documentURI(self: *parser.Document) []const u8 {
|
pub fn get_documentURI(self: *parser.Document) ![]const u8 {
|
||||||
return parser.documentGetDocumentURI(self);
|
return try parser.documentGetDocumentURI(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_URL(self: *parser.Document) []const u8 {
|
pub fn get_URL(self: *parser.Document) ![]const u8 {
|
||||||
return get_documentURI(self);
|
return try get_documentURI(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement contentType
|
// TODO implement contentType
|
||||||
@@ -58,37 +57,37 @@ pub const Document = struct {
|
|||||||
return "CSS1Compat";
|
return "CSS1Compat";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_characterSet(self: *parser.Document) []const u8 {
|
pub fn get_characterSet(self: *parser.Document) ![]const u8 {
|
||||||
return parser.documentGetInputEncoding(self);
|
return try parser.documentGetInputEncoding(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// alias of get_characterSet
|
// alias of get_characterSet
|
||||||
pub fn get_charset(self: *parser.Document) []const u8 {
|
pub fn get_charset(self: *parser.Document) ![]const u8 {
|
||||||
return get_characterSet(self);
|
return try get_characterSet(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// alias of get_characterSet
|
// alias of get_characterSet
|
||||||
pub fn get_inputEncoding(self: *parser.Document) []const u8 {
|
pub fn get_inputEncoding(self: *parser.Document) ![]const u8 {
|
||||||
return get_characterSet(self);
|
return try get_characterSet(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_doctype(self: *parser.Document) ?*parser.DocumentType {
|
pub fn get_doctype(self: *parser.Document) !?*parser.DocumentType {
|
||||||
return parser.documentGetDoctype(self);
|
return try parser.documentGetDoctype(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _getElementById(self: *parser.Document, id: []const u8) ?ElementUnion {
|
pub fn _getElementById(self: *parser.Document, id: []const u8) !?ElementUnion {
|
||||||
const e = parser.documentGetElementById(self, id) orelse return null;
|
const e = try parser.documentGetElementById(self, id) orelse return null;
|
||||||
return Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _createElement(self: *parser.Document, tag_name: []const u8) ElementUnion {
|
pub fn _createElement(self: *parser.Document, tag_name: []const u8) !ElementUnion {
|
||||||
const e = parser.documentCreateElement(self, tag_name);
|
const e = try parser.documentCreateElement(self, tag_name);
|
||||||
return Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _createElementNS(self: *parser.Document, ns: []const u8, tag_name: []const u8) ElementUnion {
|
pub fn _createElementNS(self: *parser.Document, ns: []const u8, tag_name: []const u8) !ElementUnion {
|
||||||
const e = parser.documentCreateElementNS(self, ns, tag_name);
|
const e = try parser.documentCreateElementNS(self, ns, tag_name);
|
||||||
return Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't simply use libdom dom_document_get_elements_by_tag_name here.
|
// We can't simply use libdom dom_document_get_elements_by_tag_name here.
|
||||||
@@ -104,7 +103,7 @@ pub const Document = struct {
|
|||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
tag_name: []const u8,
|
tag_name: []const u8,
|
||||||
) !collection.HTMLCollection {
|
) !collection.HTMLCollection {
|
||||||
const root = parser.documentGetDocumentElement(self);
|
const root = try parser.documentGetDocumentElement(self);
|
||||||
return try collection.HTMLCollectionByTagName(
|
return try collection.HTMLCollectionByTagName(
|
||||||
alloc,
|
alloc,
|
||||||
parser.elementToNode(root),
|
parser.elementToNode(root),
|
||||||
@@ -117,7 +116,7 @@ pub const Document = struct {
|
|||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
classNames: []const u8,
|
classNames: []const u8,
|
||||||
) !collection.HTMLCollection {
|
) !collection.HTMLCollection {
|
||||||
const root = parser.documentGetDocumentElement(self);
|
const root = try parser.documentGetDocumentElement(self);
|
||||||
return try collection.HTMLCollectionByClassName(
|
return try collection.HTMLCollectionByClassName(
|
||||||
alloc,
|
alloc,
|
||||||
parser.elementToNode(root),
|
parser.elementToNode(root),
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ pub const DocumentType = struct {
|
|||||||
pub const prototype = *Node;
|
pub const prototype = *Node;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
pub fn get_name(self: *parser.DocumentType) []const u8 {
|
pub fn get_name(self: *parser.DocumentType) ![]const u8 {
|
||||||
return parser.documentTypeGetName(self);
|
return try parser.documentTypeGetName(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_publicId(self: *parser.DocumentType) []const u8 {
|
pub fn get_publicId(self: *parser.DocumentType) ![]const u8 {
|
||||||
return parser.documentTypeGetPublicId(self);
|
return try parser.documentTypeGetPublicId(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_systemId(self: *parser.DocumentType) []const u8 {
|
pub fn get_systemId(self: *parser.DocumentType) ![]const u8 {
|
||||||
return parser.documentTypeGetSystemId(self);
|
return try parser.documentTypeGetSystemId(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ pub const Element = struct {
|
|||||||
pub const prototype = *Node;
|
pub const prototype = *Node;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
pub fn toInterface(e: *parser.Element) Union {
|
pub fn toInterface(e: *parser.Element) !Union {
|
||||||
return HTMLElem.toInterface(Union, e);
|
return try HTMLElem.toInterface(Union, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
pub fn get_localName(self: *parser.Element) []const u8 {
|
pub fn get_localName(self: *parser.Element) ![]const u8 {
|
||||||
return parser.elementLocalName(self);
|
return try parser.elementLocalName(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,7 +54,11 @@ pub const DOMException = struct {
|
|||||||
.{ errName, callerName },
|
.{ errName, callerName },
|
||||||
),
|
),
|
||||||
error.NoError => unreachable,
|
error.NoError => unreachable,
|
||||||
else => "", // TODO: implement other messages
|
else => try allocPrint(
|
||||||
|
alloc,
|
||||||
|
"{s}: TODO message", // TODO: implement other messages
|
||||||
|
.{DOMException.name(errCast)},
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return .{ .err = errCast, .str = str };
|
return .{ .err = errCast, .str = str };
|
||||||
}
|
}
|
||||||
@@ -154,6 +158,8 @@ pub fn testExecFn(
|
|||||||
.{ .src = "HierarchyRequestError.code", .ex = "3" },
|
.{ .src = "HierarchyRequestError.code", .ex = "3" },
|
||||||
.{ .src = "HierarchyRequestError.message", .ex = err },
|
.{ .src = "HierarchyRequestError.message", .ex = err },
|
||||||
.{ .src = "HierarchyRequestError.toString()", .ex = "HierarchyRequestError: " ++ err },
|
.{ .src = "HierarchyRequestError.toString()", .ex = "HierarchyRequestError: " ++ err },
|
||||||
|
.{ .src = "HierarchyRequestError instanceof DOMException", .ex = "true" },
|
||||||
|
.{ .src = "HierarchyRequestError instanceof Error", .ex = "true" },
|
||||||
};
|
};
|
||||||
try checkCases(js_env, &cases);
|
try checkCases(js_env, &cases);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const Matcher = union(enum) {
|
|||||||
matchByTagName: MatchByTagName,
|
matchByTagName: MatchByTagName,
|
||||||
matchByClassName: MatchByClassName,
|
matchByClassName: MatchByClassName,
|
||||||
|
|
||||||
pub fn match(self: Matcher, node: *parser.Node) bool {
|
pub fn match(self: Matcher, node: *parser.Node) !bool {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
inline else => |case| return case.match(node),
|
inline else => |case| return case.match(node),
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@ pub const MatchByTagName = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match(self: MatchByTagName, node: *parser.Node) bool {
|
pub fn match(self: MatchByTagName, node: *parser.Node) !bool {
|
||||||
return self.is_wildcard or std.ascii.eqlIgnoreCase(self.tag, parser.nodeName(node));
|
return self.is_wildcard or std.ascii.eqlIgnoreCase(self.tag, try parser.nodeName(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: MatchByTagName, alloc: std.mem.Allocator) void {
|
fn deinit(self: MatchByTagName, alloc: std.mem.Allocator) void {
|
||||||
@@ -76,11 +76,11 @@ pub const MatchByClassName = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match(self: MatchByClassName, node: *parser.Node) bool {
|
pub fn match(self: MatchByClassName, node: *parser.Node) !bool {
|
||||||
var it = std.mem.splitAny(u8, self.classNames, " ");
|
var it = std.mem.splitAny(u8, self.classNames, " ");
|
||||||
const e = parser.nodeToElement(node);
|
const e = parser.nodeToElement(node);
|
||||||
while (it.next()) |c| {
|
while (it.next()) |c| {
|
||||||
if (!parser.elementHasClass(e, c)) {
|
if (!try parser.elementHasClass(e, c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,24 +130,24 @@ pub const HTMLCollection = struct {
|
|||||||
// The iteration is a depth first as required by the specification.
|
// The iteration is a depth first as required by the specification.
|
||||||
// https://dom.spec.whatwg.org/#htmlcollection
|
// https://dom.spec.whatwg.org/#htmlcollection
|
||||||
// https://dom.spec.whatwg.org/#concept-tree-order
|
// https://dom.spec.whatwg.org/#concept-tree-order
|
||||||
fn get_next(root: *parser.Node, cur: *parser.Node) ?*parser.Node {
|
fn get_next(root: *parser.Node, cur: *parser.Node) !?*parser.Node {
|
||||||
// TODO deinit next
|
// TODO deinit next
|
||||||
if (parser.nodeFirstChild(cur)) |next| {
|
if (try parser.nodeFirstChild(cur)) |next| {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO deinit next
|
// TODO deinit next
|
||||||
if (parser.nodeNextSibling(cur)) |next| {
|
if (try parser.nodeNextSibling(cur)) |next| {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO deinit parent
|
// TODO deinit parent
|
||||||
// Back to the parent of cur.
|
// Back to the parent of cur.
|
||||||
// If cur has no parent, then the iteration is over.
|
// If cur has no parent, then the iteration is over.
|
||||||
var parent = parser.nodeParentNode(cur) orelse return null;
|
var parent = try parser.nodeParentNode(cur) orelse return null;
|
||||||
|
|
||||||
// TODO deinit lastchild
|
// TODO deinit lastchild
|
||||||
var lastchild = parser.nodeLastChild(parent);
|
var lastchild = try parser.nodeLastChild(parent);
|
||||||
var prev = cur;
|
var prev = cur;
|
||||||
while (prev != root and prev == lastchild) {
|
while (prev != root and prev == lastchild) {
|
||||||
prev = parent;
|
prev = parent;
|
||||||
@@ -155,42 +155,42 @@ pub const HTMLCollection = struct {
|
|||||||
// TODO deinit parent
|
// TODO deinit parent
|
||||||
// Back to the prev's parent.
|
// Back to the prev's parent.
|
||||||
// If prev has no parent, then the loop must stop.
|
// If prev has no parent, then the loop must stop.
|
||||||
parent = parser.nodeParentNode(prev) orelse break;
|
parent = try parser.nodeParentNode(prev) orelse break;
|
||||||
|
|
||||||
// TODO deinit lastchild
|
// TODO deinit lastchild
|
||||||
lastchild = parser.nodeLastChild(parent);
|
lastchild = try parser.nodeLastChild(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev == root) {
|
if (prev == root) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser.nodeNextSibling(prev);
|
return try parser.nodeNextSibling(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get_length computes the collection's length dynamically according to
|
/// get_length computes the collection's length dynamically according to
|
||||||
/// the current root structure.
|
/// the current root structure.
|
||||||
// TODO: nodes retrieved must be de-referenced.
|
// TODO: nodes retrieved must be de-referenced.
|
||||||
pub fn get_length(self: *HTMLCollection) u32 {
|
pub fn get_length(self: *HTMLCollection) !u32 {
|
||||||
var len: u32 = 0;
|
var len: u32 = 0;
|
||||||
var node: *parser.Node = self.root;
|
var node: *parser.Node = self.root;
|
||||||
var ntype: parser.NodeType = undefined;
|
var ntype: parser.NodeType = undefined;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ntype = parser.nodeType(node);
|
ntype = try parser.nodeType(node);
|
||||||
if (ntype == .element) {
|
if (ntype == .element) {
|
||||||
if (self.matcher.match(node)) {
|
if (try self.matcher.match(node)) {
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = get_next(self.root, node) orelse break;
|
node = try get_next(self.root, node) orelse break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _item(self: *HTMLCollection, index: u32) ?Union {
|
pub fn _item(self: *HTMLCollection, index: u32) !?Union {
|
||||||
var i: u32 = 0;
|
var i: u32 = 0;
|
||||||
var node: *parser.Node = self.root;
|
var node: *parser.Node = self.root;
|
||||||
var ntype: parser.NodeType = undefined;
|
var ntype: parser.NodeType = undefined;
|
||||||
@@ -202,9 +202,9 @@ pub const HTMLCollection = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ntype = parser.nodeType(node);
|
ntype = try parser.nodeType(node);
|
||||||
if (ntype == .element) {
|
if (ntype == .element) {
|
||||||
if (self.matcher.match(node)) {
|
if (try self.matcher.match(node)) {
|
||||||
// check if we found the searched element.
|
// check if we found the searched element.
|
||||||
if (i == index) {
|
if (i == index) {
|
||||||
// save the current state
|
// save the current state
|
||||||
@@ -212,20 +212,20 @@ pub const HTMLCollection = struct {
|
|||||||
self.cur_idx = i;
|
self.cur_idx = i;
|
||||||
|
|
||||||
const e = @as(*parser.Element, @ptrCast(node));
|
const e = @as(*parser.Element, @ptrCast(node));
|
||||||
return Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = get_next(self.root, node) orelse break;
|
node = try get_next(self.root, node) orelse break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _namedItem(self: *HTMLCollection, name: []const u8) ?Union {
|
pub fn _namedItem(self: *HTMLCollection, name: []const u8) !?Union {
|
||||||
if (name.len == 0) {
|
if (name.len == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -234,26 +234,26 @@ pub const HTMLCollection = struct {
|
|||||||
var ntype: parser.NodeType = undefined;
|
var ntype: parser.NodeType = undefined;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ntype = parser.nodeType(node);
|
ntype = try parser.nodeType(node);
|
||||||
if (ntype == .element) {
|
if (ntype == .element) {
|
||||||
if (self.matcher.match(node)) {
|
if (try self.matcher.match(node)) {
|
||||||
const elem = @as(*parser.Element, @ptrCast(node));
|
const elem = @as(*parser.Element, @ptrCast(node));
|
||||||
|
|
||||||
var attr = parser.elementGetAttribute(elem, "id");
|
var attr = try parser.elementGetAttribute(elem, "id");
|
||||||
// check if the node id corresponds to the name argument.
|
// check if the node id corresponds to the name argument.
|
||||||
if (attr != null and std.mem.eql(u8, name, attr.?)) {
|
if (attr != null and std.mem.eql(u8, name, attr.?)) {
|
||||||
return Element.toInterface(elem);
|
return try Element.toInterface(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = parser.elementGetAttribute(elem, "name");
|
attr = try parser.elementGetAttribute(elem, "name");
|
||||||
// check if the node id corresponds to the name argument.
|
// check if the node id corresponds to the name argument.
|
||||||
if (attr != null and std.mem.eql(u8, name, attr.?)) {
|
if (attr != null and std.mem.eql(u8, name, attr.?)) {
|
||||||
return Element.toInterface(elem);
|
return try Element.toInterface(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = get_next(self.root, node) orelse break;
|
node = try get_next(self.root, node) orelse break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ const checkCases = jsruntime.test_utils.checkCases;
|
|||||||
|
|
||||||
const Document = @import("document.zig").Document;
|
const Document = @import("document.zig").Document;
|
||||||
const DocumentType = @import("document_type.zig").DocumentType;
|
const DocumentType = @import("document_type.zig").DocumentType;
|
||||||
|
const DOMException = @import("exceptions.zig").DOMException;
|
||||||
|
|
||||||
// WEB IDL https://dom.spec.whatwg.org/#domimplementation
|
// WEB IDL https://dom.spec.whatwg.org/#domimplementation
|
||||||
pub const DOMImplementation = struct {
|
pub const DOMImplementation = struct {
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
|
pub const Exception = DOMException;
|
||||||
|
|
||||||
pub fn _createDocumentType(
|
pub fn _createDocumentType(
|
||||||
_: *DOMImplementation,
|
_: *DOMImplementation,
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
@@ -29,7 +32,7 @@ pub const DOMImplementation = struct {
|
|||||||
const csystemId = try alloc.dupeZ(u8, systemId);
|
const csystemId = try alloc.dupeZ(u8, systemId);
|
||||||
defer alloc.free(csystemId);
|
defer alloc.free(csystemId);
|
||||||
|
|
||||||
return parser.domImplementationCreateDocumentType(cqname, cpublicId, csystemId);
|
return try parser.domImplementationCreateDocumentType(cqname, cpublicId, csystemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _createDocument(
|
pub fn _createDocument(
|
||||||
@@ -42,20 +45,20 @@ pub const DOMImplementation = struct {
|
|||||||
var cnamespace: ?[:0]const u8 = null;
|
var cnamespace: ?[:0]const u8 = null;
|
||||||
if (namespace) |ns| {
|
if (namespace) |ns| {
|
||||||
cnamespace = try alloc.dupeZ(u8, ns);
|
cnamespace = try alloc.dupeZ(u8, ns);
|
||||||
defer alloc.free(cnamespace.?);
|
|
||||||
}
|
}
|
||||||
|
defer if (cnamespace) |v| alloc.free(v);
|
||||||
|
|
||||||
var cqname: ?[:0]const u8 = null;
|
var cqname: ?[:0]const u8 = null;
|
||||||
if (qname) |qn| {
|
if (qname) |qn| {
|
||||||
cqname = try alloc.dupeZ(u8, qn);
|
cqname = try alloc.dupeZ(u8, qn);
|
||||||
defer alloc.free(cqname.?);
|
}
|
||||||
|
defer if (cqname) |v| alloc.free(v);
|
||||||
|
|
||||||
|
return try parser.domImplementationCreateDocument(cnamespace, cqname, doctype);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser.domImplementationCreateDocument(cnamespace, cqname, doctype);
|
pub fn _createHTMLDocument(_: *DOMImplementation, title: ?[]const u8) !*parser.Document {
|
||||||
}
|
return try parser.domImplementationCreateHTMLDocument(title);
|
||||||
|
|
||||||
pub fn _createHTMLDocument(_: *DOMImplementation, title: ?[]const u8) *parser.Document {
|
|
||||||
return parser.domImplementationCreateHTMLDocument(title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _hasFeature(_: *DOMImplementation) bool {
|
pub fn _hasFeature(_: *DOMImplementation) bool {
|
||||||
|
|||||||
135
src/dom/node.zig
135
src/dom/node.zig
@@ -42,9 +42,12 @@ pub const Node = struct {
|
|||||||
pub const prototype = *EventTarget;
|
pub const prototype = *EventTarget;
|
||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
|
|
||||||
pub fn toInterface(node: *parser.Node) Union {
|
pub fn toInterface(node: *parser.Node) !Union {
|
||||||
return switch (parser.nodeType(node)) {
|
return switch (try parser.nodeType(node)) {
|
||||||
.element => HTMLElem.toInterface(Union, @as(*parser.Element, @ptrCast(node))),
|
.element => try HTMLElem.toInterface(
|
||||||
|
Union,
|
||||||
|
@as(*parser.Element, @ptrCast(node)),
|
||||||
|
),
|
||||||
.comment => .{ .Comment = @as(*parser.Comment, @ptrCast(node)) },
|
.comment => .{ .Comment = @as(*parser.Comment, @ptrCast(node)) },
|
||||||
.text => .{ .Text = @as(*parser.Text, @ptrCast(node)) },
|
.text => .{ .Text = @as(*parser.Text, @ptrCast(node)) },
|
||||||
.document => .{ .HTMLDocument = @as(*parser.DocumentHTML, @ptrCast(node)) },
|
.document => .{ .HTMLDocument = @as(*parser.DocumentHTML, @ptrCast(node)) },
|
||||||
@@ -58,94 +61,94 @@ pub const Node = struct {
|
|||||||
|
|
||||||
// Read-only attributes
|
// Read-only attributes
|
||||||
|
|
||||||
pub fn get_firstChild(self: *parser.Node) ?Union {
|
pub fn get_firstChild(self: *parser.Node) !?Union {
|
||||||
const res = parser.nodeFirstChild(self);
|
const res = try parser.nodeFirstChild(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Node.toInterface(res.?);
|
return try Node.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lastChild(self: *parser.Node) ?Union {
|
pub fn get_lastChild(self: *parser.Node) !?Union {
|
||||||
const res = parser.nodeLastChild(self);
|
const res = try parser.nodeLastChild(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Node.toInterface(res.?);
|
return try Node.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_nextSibling(self: *parser.Node) ?Union {
|
pub fn get_nextSibling(self: *parser.Node) !?Union {
|
||||||
const res = parser.nodeNextSibling(self);
|
const res = try parser.nodeNextSibling(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Node.toInterface(res.?);
|
return try Node.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_previousSibling(self: *parser.Node) ?Union {
|
pub fn get_previousSibling(self: *parser.Node) !?Union {
|
||||||
const res = parser.nodePreviousSibling(self);
|
const res = try parser.nodePreviousSibling(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Node.toInterface(res.?);
|
return try Node.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_parentNode(self: *parser.Node) ?Union {
|
pub fn get_parentNode(self: *parser.Node) !?Union {
|
||||||
const res = parser.nodeParentNode(self);
|
const res = try parser.nodeParentNode(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Node.toInterface(res.?);
|
return try Node.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_parentElement(self: *parser.Node) ?HTMLElem.Union {
|
pub fn get_parentElement(self: *parser.Node) !?HTMLElem.Union {
|
||||||
const res = parser.nodeParentElement(self);
|
const res = try parser.nodeParentElement(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return HTMLElem.toInterface(HTMLElem.Union, @as(*parser.Element, @ptrCast(res.?)));
|
return try HTMLElem.toInterface(HTMLElem.Union, @as(*parser.Element, @ptrCast(res.?)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_nodeName(self: *parser.Node) []const u8 {
|
pub fn get_nodeName(self: *parser.Node) ![]const u8 {
|
||||||
return parser.nodeName(self);
|
return try parser.nodeName(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_nodeType(self: *parser.Node) u8 {
|
pub fn get_nodeType(self: *parser.Node) !u8 {
|
||||||
return @intFromEnum(parser.nodeType(self));
|
return @intFromEnum(try parser.nodeType(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ownerDocument(self: *parser.Node) ?*parser.DocumentHTML {
|
pub fn get_ownerDocument(self: *parser.Node) !?*parser.DocumentHTML {
|
||||||
const res = parser.nodeOwnerDocument(self);
|
const res = try parser.nodeOwnerDocument(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return @as(*parser.DocumentHTML, @ptrCast(res.?));
|
return @as(*parser.DocumentHTML, @ptrCast(res.?));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_isConnected(self: *parser.Node) bool {
|
pub fn get_isConnected(self: *parser.Node) !bool {
|
||||||
// TODO: handle Shadow DOM
|
// TODO: handle Shadow DOM
|
||||||
if (parser.nodeType(self) == .document) {
|
if (try parser.nodeType(self) == .document) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return Node.get_parentNode(self) != null;
|
return try Node.get_parentNode(self) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read/Write attributes
|
// Read/Write attributes
|
||||||
|
|
||||||
pub fn get_nodeValue(self: *parser.Node) ?[]const u8 {
|
pub fn get_nodeValue(self: *parser.Node) !?[]const u8 {
|
||||||
return parser.nodeValue(self);
|
return try parser.nodeValue(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_nodeValue(self: *parser.Node, data: []u8) void {
|
pub fn set_nodeValue(self: *parser.Node, data: []u8) !void {
|
||||||
parser.nodeSetValue(self, data);
|
try parser.nodeSetValue(self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_textContent(self: *parser.Node) ?[]const u8 {
|
pub fn get_textContent(self: *parser.Node) !?[]const u8 {
|
||||||
return parser.nodeTextContent(self);
|
return try parser.nodeTextContent(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_textContent(self: *parser.Node, data: []u8) void {
|
pub fn set_textContent(self: *parser.Node, data: []u8) !void {
|
||||||
return parser.nodeSetTextContent(self, data);
|
return try parser.nodeSetTextContent(self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -153,12 +156,12 @@ pub const Node = struct {
|
|||||||
pub fn _appendChild(self: *parser.Node, child: *parser.Node) !Union {
|
pub fn _appendChild(self: *parser.Node, child: *parser.Node) !Union {
|
||||||
// TODO: DocumentFragment special case
|
// TODO: DocumentFragment special case
|
||||||
const res = try parser.nodeAppendChild(self, child);
|
const res = try parser.nodeAppendChild(self, child);
|
||||||
return Node.toInterface(res);
|
return try Node.toInterface(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _cloneNode(self: *parser.Node, deep: ?bool) Union {
|
pub fn _cloneNode(self: *parser.Node, deep: ?bool) !Union {
|
||||||
const clone = parser.nodeCloneNode(self, deep orelse false);
|
const clone = try parser.nodeCloneNode(self, deep orelse false);
|
||||||
return Node.toInterface(clone);
|
return try Node.toInterface(clone);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _compareDocumentPosition(self: *parser.Node, other: *parser.Node) void {
|
pub fn _compareDocumentPosition(self: *parser.Node, other: *parser.Node) void {
|
||||||
@@ -168,8 +171,8 @@ pub const Node = struct {
|
|||||||
std.log.err("Not implemented {s}", .{"node.compareDocumentPosition()"});
|
std.log.err("Not implemented {s}", .{"node.compareDocumentPosition()"});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _contains(self: *parser.Node, other: *parser.Node) bool {
|
pub fn _contains(self: *parser.Node, other: *parser.Node) !bool {
|
||||||
return parser.nodeContains(self, other);
|
return try parser.nodeContains(self, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _getRootNode(self: *parser.Node) void {
|
pub fn _getRootNode(self: *parser.Node) void {
|
||||||
@@ -178,31 +181,31 @@ pub const Node = struct {
|
|||||||
std.log.err("Not implemented {s}", .{"node.getRootNode()"});
|
std.log.err("Not implemented {s}", .{"node.getRootNode()"});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _hasChildNodes(self: *parser.Node) bool {
|
pub fn _hasChildNodes(self: *parser.Node) !bool {
|
||||||
return parser.nodeHasChildNodes(self);
|
return try parser.nodeHasChildNodes(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _insertBefore(self: *parser.Node, new_node: *parser.Node, ref_node: *parser.Node) *parser.Node {
|
pub fn _insertBefore(self: *parser.Node, new_node: *parser.Node, ref_node: *parser.Node) !*parser.Node {
|
||||||
return parser.nodeInsertBefore(self, new_node, ref_node);
|
return try parser.nodeInsertBefore(self, new_node, ref_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _isDefaultNamespace(self: *parser.Node, namespace: []const u8) bool {
|
pub fn _isDefaultNamespace(self: *parser.Node, namespace: []const u8) !bool {
|
||||||
// TODO: namespace is not an optional parameter, but can be null.
|
// TODO: namespace is not an optional parameter, but can be null.
|
||||||
return parser.nodeIsDefaultNamespace(self, namespace);
|
return try parser.nodeIsDefaultNamespace(self, namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _isEqualNode(self: *parser.Node, other: *parser.Node) bool {
|
pub fn _isEqualNode(self: *parser.Node, other: *parser.Node) !bool {
|
||||||
// TODO: other is not an optional parameter, but can be null.
|
// TODO: other is not an optional parameter, but can be null.
|
||||||
return parser.nodeIsEqualNode(self, other);
|
return try parser.nodeIsEqualNode(self, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _isSameNode(self: *parser.Node, other: *parser.Node) bool {
|
pub fn _isSameNode(self: *parser.Node, other: *parser.Node) !bool {
|
||||||
// TODO: other is not an optional parameter, but can be null.
|
// TODO: other is not an optional parameter, but can be null.
|
||||||
// NOTE: there is no need to use isSameNode(); instead use the === strict equality operator
|
// NOTE: there is no need to use isSameNode(); instead use the === strict equality operator
|
||||||
return parser.nodeIsSameNode(self, other);
|
return try parser.nodeIsSameNode(self, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _lookupPrefix(self: *parser.Node, namespace: ?[]const u8) ?[]const u8 {
|
pub fn _lookupPrefix(self: *parser.Node, namespace: ?[]const u8) !?[]const u8 {
|
||||||
// TODO: other is not an optional parameter, but can be null.
|
// TODO: other is not an optional parameter, but can be null.
|
||||||
if (namespace == null) {
|
if (namespace == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -210,26 +213,26 @@ pub const Node = struct {
|
|||||||
if (std.mem.eql(u8, namespace.?, "")) {
|
if (std.mem.eql(u8, namespace.?, "")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return parser.nodeLookupPrefix(self, namespace.?);
|
return try parser.nodeLookupPrefix(self, namespace.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _lookupNamespaceURI(self: *parser.Node, prefix: ?[]const u8) ?[]const u8 {
|
pub fn _lookupNamespaceURI(self: *parser.Node, prefix: ?[]const u8) !?[]const u8 {
|
||||||
// TODO: other is not an optional parameter, but can be null.
|
// TODO: other is not an optional parameter, but can be null.
|
||||||
return parser.nodeLookupNamespaceURI(self, prefix);
|
return try parser.nodeLookupNamespaceURI(self, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _normalize(self: *parser.Node) void {
|
pub fn _normalize(self: *parser.Node) !void {
|
||||||
return parser.nodeNormalize(self);
|
return try parser.nodeNormalize(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _removeChild(self: *parser.Node, child: *parser.Node) Union {
|
pub fn _removeChild(self: *parser.Node, child: *parser.Node) !Union {
|
||||||
const res = parser.nodeRemoveChild(self, child);
|
const res = try parser.nodeRemoveChild(self, child);
|
||||||
return Node.toInterface(res);
|
return try Node.toInterface(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _replaceChild(self: *parser.Node, new_child: *parser.Node, old_child: *parser.Node) Union {
|
pub fn _replaceChild(self: *parser.Node, new_child: *parser.Node, old_child: *parser.Node) !Union {
|
||||||
const res = parser.nodeReplaceChild(self, new_child, old_child);
|
const res = try parser.nodeReplaceChild(self, new_child, old_child);
|
||||||
return Node.toInterface(res);
|
return try Node.toInterface(res);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ pub const Text = struct {
|
|||||||
|
|
||||||
// Read attributes
|
// Read attributes
|
||||||
|
|
||||||
pub fn get_wholeText(self: *parser.Text) []const u8 {
|
pub fn get_wholeText(self: *parser.Text) ![]const u8 {
|
||||||
return parser.textWholdeText(self);
|
return try parser.textWholdeText(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JS methods
|
// JS methods
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
pub fn _splitText(self: *parser.Text, offset: u32) *parser.Text {
|
pub fn _splitText(self: *parser.Text, offset: u32) !*parser.Text {
|
||||||
return parser.textSplitText(self, offset);
|
return try parser.textSplitText(self, offset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ pub const HTMLDocument = struct {
|
|||||||
// JS funcs
|
// JS funcs
|
||||||
// --------
|
// --------
|
||||||
|
|
||||||
pub fn get_body(self: *parser.DocumentHTML) ?*parser.Body {
|
pub fn get_body(self: *parser.DocumentHTML) !?*parser.Body {
|
||||||
return parser.documentHTMLBody(self);
|
return try parser.documentHTMLBody(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -491,9 +491,9 @@ pub const HTMLVideoElement = struct {
|
|||||||
pub const mem_guarantied = true;
|
pub const mem_guarantied = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn toInterface(comptime T: type, e: *parser.Element) T {
|
pub fn toInterface(comptime T: type, e: *parser.Element) !T {
|
||||||
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
|
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
|
||||||
const tag = parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
||||||
return switch (tag) {
|
return switch (tag) {
|
||||||
.abbr, .acronym, .address, .article, .aside, .b, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .kbd, .main, .mark, .marquee, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(elem)) },
|
.abbr, .acronym, .address, .article, .aside, .b, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .kbd, .main, .mark, .marquee, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(elem)) },
|
||||||
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) },
|
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) },
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ pub fn main() !void {
|
|||||||
|
|
||||||
// document
|
// document
|
||||||
doc = try parser.documentHTMLParseFromFileAlloc(arena.allocator(), "test.html");
|
doc = try parser.documentHTMLParseFromFileAlloc(arena.allocator(), "test.html");
|
||||||
defer parser.documentHTMLClose(doc);
|
defer parser.documentHTMLClose(doc) catch |err| {
|
||||||
|
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
|
||||||
// remove socket file of internal server
|
// remove socket file of internal server
|
||||||
// reuse_address (SO_REUSEADDR flag) does not seems to work on unix socket
|
// reuse_address (SO_REUSEADDR flag) does not seems to work on unix socket
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ pub fn main() !void {
|
|||||||
|
|
||||||
// document
|
// document
|
||||||
doc = try parser.documentHTMLParseFromFileAlloc(arena.allocator(), "test.html");
|
doc = try parser.documentHTMLParseFromFileAlloc(arena.allocator(), "test.html");
|
||||||
defer parser.documentHTMLClose(doc);
|
defer parser.documentHTMLClose(doc) catch |err| {
|
||||||
|
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
|
||||||
// create JS vm
|
// create JS vm
|
||||||
const vm = jsruntime.VM.init();
|
const vm = jsruntime.VM.init();
|
||||||
|
|||||||
@@ -217,13 +217,13 @@ fn runWPT(arena: *std.heap.ArenaAllocator, comptime apis: []jsruntime.API, f: []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loop hover the scripts.
|
// loop hover the scripts.
|
||||||
const scripts = parser.documentGetElementsByTagName(doc, "script");
|
const scripts = try parser.documentGetElementsByTagName(doc, "script");
|
||||||
const slen = parser.nodeListLength(scripts);
|
const slen = try parser.nodeListLength(scripts);
|
||||||
for (0..slen) |i| {
|
for (0..slen) |i| {
|
||||||
const s = parser.nodeListItem(scripts, @intCast(i)).?;
|
const s = (try parser.nodeListItem(scripts, @intCast(i))).?;
|
||||||
|
|
||||||
// If the script contains an src attribute, load it.
|
// If the script contains an src attribute, load it.
|
||||||
if (parser.elementGetAttribute(@as(*parser.Element, @ptrCast(s)), "src")) |src| {
|
if (try parser.elementGetAttribute(@as(*parser.Element, @ptrCast(s)), "src")) |src| {
|
||||||
var path = src;
|
var path = src;
|
||||||
if (!std.mem.startsWith(u8, src, "/")) {
|
if (!std.mem.startsWith(u8, src, "/")) {
|
||||||
// no need to free path, thanks to the arena.
|
// no need to free path, thanks to the arena.
|
||||||
@@ -237,7 +237,7 @@ fn runWPT(arena: *std.heap.ArenaAllocator, comptime apis: []jsruntime.API, f: []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the script as a source text, execute it.
|
// If the script as a source text, execute it.
|
||||||
const src = parser.nodeTextContent(s) orelse continue;
|
const src = try parser.nodeTextContent(s) orelse continue;
|
||||||
res = try evalJS(js_env, alloc, src, "");
|
res = try evalJS(js_env, alloc, src, "");
|
||||||
|
|
||||||
// return the first failure.
|
// return the first failure.
|
||||||
|
|||||||
374
src/netsurf.zig
374
src/netsurf.zig
@@ -59,9 +59,10 @@ inline fn stringToData(s: *String) []const u8 {
|
|||||||
return data[0..c.dom_string_byte_length(s)];
|
return data[0..c.dom_string_byte_length(s)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn stringFromData(data: []const u8) *String {
|
inline fn stringFromData(data: []const u8) !*String {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = c.dom_string_create(data.ptr, data.len, &s);
|
const err = c.dom_string_create(data.ptr, data.len, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return s.?;
|
return s.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,9 +72,10 @@ const LWCString = c.lwc_string;
|
|||||||
// inline fn lwcStringToData(s: *LWCString) []const u8 {
|
// inline fn lwcStringToData(s: *LWCString) []const u8 {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
inline fn lwcStringFromData(data: []const u8) *LWCString {
|
inline fn lwcStringFromData(data: []const u8) !*LWCString {
|
||||||
var s: ?*LWCString = undefined;
|
var s: ?*LWCString = undefined;
|
||||||
_ = c.lwc_intern_string(data.ptr, data.len, &s);
|
const err = c.lwc_intern_string(data.ptr, data.len, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return s.?;
|
return s.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,15 +356,17 @@ pub const NodeType = enum(u4) {
|
|||||||
// NodeList
|
// NodeList
|
||||||
pub const NodeList = c.dom_nodelist;
|
pub const NodeList = c.dom_nodelist;
|
||||||
|
|
||||||
pub fn nodeListLength(nodeList: *NodeList) u32 {
|
pub fn nodeListLength(nodeList: *NodeList) !u32 {
|
||||||
var ln: u32 = undefined;
|
var ln: u32 = undefined;
|
||||||
_ = c.dom_nodelist_get_length(nodeList, &ln);
|
const err = c.dom_nodelist_get_length(nodeList, &ln);
|
||||||
|
try DOMErr(err);
|
||||||
return ln;
|
return ln;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeListItem(nodeList: *NodeList, index: u32) ?*Node {
|
pub fn nodeListItem(nodeList: *NodeList, index: u32) !?*Node {
|
||||||
var n: [*c]c.dom_node = undefined;
|
var n: [*c]c.dom_node = undefined;
|
||||||
_ = c._dom_nodelist_item(nodeList, index, &n);
|
const err = c._dom_nodelist_item(nodeList, index, &n);
|
||||||
|
try DOMErr(err);
|
||||||
|
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -379,46 +383,52 @@ fn nodeVtable(node: *Node) c.dom_node_vtable {
|
|||||||
return getVtable(c.dom_node_vtable, Node, node);
|
return getVtable(c.dom_node_vtable, Node, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeLocalName(node: *Node) []const u8 {
|
pub fn nodeLocalName(node: *Node) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_local_name.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_local_name.?(node, &s);
|
||||||
|
try DOMErr(err);
|
||||||
var s_lower: ?*String = undefined;
|
var s_lower: ?*String = undefined;
|
||||||
_ = c.dom_string_tolower(s, true, &s_lower);
|
const errStr = c.dom_string_tolower(s, true, &s_lower);
|
||||||
|
try DOMErr(errStr);
|
||||||
return stringToData(s_lower.?);
|
return stringToData(s_lower.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeType(node: *Node) NodeType {
|
pub fn nodeType(node: *Node) !NodeType {
|
||||||
var node_type: c.dom_node_type = undefined;
|
var node_type: c.dom_node_type = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_node_type.?(node, &node_type);
|
const err = nodeVtable(node).dom_node_get_node_type.?(node, &node_type);
|
||||||
|
try DOMErr(err);
|
||||||
return @as(NodeType, @enumFromInt(node_type));
|
return @as(NodeType, @enumFromInt(node_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeFirstChild(node: *Node) ?*Node {
|
pub fn nodeFirstChild(node: *Node) !?*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_first_child.?(node, &res);
|
const err = nodeVtable(node).dom_node_get_first_child.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeLastChild(node: *Node) ?*Node {
|
pub fn nodeLastChild(node: *Node) !?*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_last_child.?(node, &res);
|
const err = nodeVtable(node).dom_node_get_last_child.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeNextSibling(node: *Node) ?*Node {
|
pub fn nodeNextSibling(node: *Node) !?*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_next_sibling.?(node, &res);
|
const err = nodeVtable(node).dom_node_get_next_sibling.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeNextElementSibling(node: *Node) ?*Element {
|
pub fn nodeNextElementSibling(node: *Node) !?*Element {
|
||||||
var n = node;
|
var n = node;
|
||||||
while (true) {
|
while (true) {
|
||||||
const res = nodeNextSibling(n);
|
const res = try nodeNextSibling(n);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (nodeType(res.?) == .element) {
|
if (try nodeType(res.?) == .element) {
|
||||||
return @as(*Element, @ptrCast(res.?));
|
return @as(*Element, @ptrCast(res.?));
|
||||||
}
|
}
|
||||||
n = res.?;
|
n = res.?;
|
||||||
@@ -426,20 +436,21 @@ pub fn nodeNextElementSibling(node: *Node) ?*Element {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodePreviousSibling(node: *Node) ?*Node {
|
pub fn nodePreviousSibling(node: *Node) !?*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_previous_sibling.?(node, &res);
|
const err = nodeVtable(node).dom_node_get_previous_sibling.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodePreviousElementSibling(node: *Node) ?*Element {
|
pub fn nodePreviousElementSibling(node: *Node) !?*Element {
|
||||||
var n = node;
|
var n = node;
|
||||||
while (true) {
|
while (true) {
|
||||||
const res = nodePreviousSibling(n);
|
const res = try nodePreviousSibling(n);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (nodeType(res.?) == .element) {
|
if (try nodeType(res.?) == .element) {
|
||||||
return @as(*Element, @ptrCast(res.?));
|
return @as(*Element, @ptrCast(res.?));
|
||||||
}
|
}
|
||||||
n = res.?;
|
n = res.?;
|
||||||
@@ -447,55 +458,61 @@ pub fn nodePreviousElementSibling(node: *Node) ?*Element {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeParentNode(node: *Node) ?*Node {
|
pub fn nodeParentNode(node: *Node) !?*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_parent_node.?(node, &res);
|
const err = nodeVtable(node).dom_node_get_parent_node.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeParentElement(node: *Node) ?*Element {
|
pub fn nodeParentElement(node: *Node) !?*Element {
|
||||||
const res = nodeParentNode(node);
|
const res = try nodeParentNode(node);
|
||||||
if (res) |value| {
|
if (res) |value| {
|
||||||
if (nodeType(value) == .element) {
|
if (try nodeType(value) == .element) {
|
||||||
return @as(*Element, @ptrCast(value));
|
return @as(*Element, @ptrCast(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeName(node: *Node) []const u8 {
|
pub fn nodeName(node: *Node) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_node_name.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_node_name.?(node, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeOwnerDocument(node: *Node) ?*Document {
|
pub fn nodeOwnerDocument(node: *Node) !?*Document {
|
||||||
var doc: ?*Document = undefined;
|
var doc: ?*Document = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_owner_document.?(node, &doc);
|
const err = nodeVtable(node).dom_node_get_owner_document.?(node, &doc);
|
||||||
|
try DOMErr(err);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeValue(node: *Node) ?[]const u8 {
|
pub fn nodeValue(node: *Node) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_node_value.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_node_value.?(node, &s);
|
||||||
|
try DOMErr(err);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeSetValue(node: *Node, value: []const u8) void {
|
pub fn nodeSetValue(node: *Node, value: []const u8) !void {
|
||||||
const s = stringFromData(value);
|
const s = try stringFromData(value);
|
||||||
_ = nodeVtable(node).dom_node_set_node_value.?(node, s);
|
const err = nodeVtable(node).dom_node_set_node_value.?(node, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeTextContent(node: *Node) ?[]const u8 {
|
pub fn nodeTextContent(node: *Node) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_get_text_content.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_text_content.?(node, &s);
|
||||||
|
try DOMErr(err);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
// NOTE: it seems that there is a bug in netsurf implem
|
// NOTE: it seems that there is a bug in netsurf implem
|
||||||
// an empty Element should return an empty string and not null
|
// an empty Element should return an empty string and not null
|
||||||
if (nodeType(node) == .element) {
|
if (try nodeType(node) == .element) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -503,92 +520,113 @@ pub fn nodeTextContent(node: *Node) ?[]const u8 {
|
|||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeSetTextContent(node: *Node, value: []const u8) void {
|
pub fn nodeSetTextContent(node: *Node, value: []const u8) !void {
|
||||||
const s = stringFromData(value);
|
const s = try stringFromData(value);
|
||||||
_ = nodeVtable(node).dom_node_set_text_content.?(node, s);
|
const err = nodeVtable(node).dom_node_set_text_content.?(node, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeAppendChild(node: *Node, child: *Node) DOMError!*Node {
|
pub fn nodeAppendChild(node: *Node, child: *Node) !*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
const err = nodeVtable(node).dom_node_append_child.?(node, child, &res);
|
const err = nodeVtable(node).dom_node_append_child.?(node, child, &res);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeCloneNode(node: *Node, is_deep: bool) *Node {
|
pub fn nodeCloneNode(node: *Node, is_deep: bool) !*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_clone_node.?(node, is_deep, &res);
|
const err = nodeVtable(node).dom_node_clone_node.?(node, is_deep, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeContains(node: *Node, other: *Node) bool {
|
pub fn nodeContains(node: *Node, other: *Node) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = c._dom_node_contains(node, other, &res);
|
const err = c._dom_node_contains(node, other, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeHasChildNodes(node: *Node) bool {
|
pub fn nodeHasChildNodes(node: *Node) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = nodeVtable(node).dom_node_has_child_nodes.?(node, &res);
|
const err = nodeVtable(node).dom_node_has_child_nodes.?(node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeInsertBefore(node: *Node, new_node: *Node, ref_node: *Node) *Node {
|
pub fn nodeInsertBefore(node: *Node, new_node: *Node, ref_node: *Node) !*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_insert_before.?(node, new_node, ref_node, &res);
|
const err = nodeVtable(node).dom_node_insert_before.?(node, new_node, ref_node, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeIsDefaultNamespace(node: *Node, namespace: []const u8) bool {
|
pub fn nodeIsDefaultNamespace(node: *Node, namespace: []const u8) !bool {
|
||||||
const s = stringFromData(namespace);
|
const s = try stringFromData(namespace);
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = nodeVtable(node).dom_node_is_default_namespace.?(node, s, &res);
|
const err = nodeVtable(node).dom_node_is_default_namespace.?(node, s, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeIsEqualNode(node: *Node, other: *Node) bool {
|
pub fn nodeIsEqualNode(node: *Node, other: *Node) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = nodeVtable(node).dom_node_is_equal.?(node, other, &res);
|
const err = nodeVtable(node).dom_node_is_equal.?(node, other, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeIsSameNode(node: *Node, other: *Node) bool {
|
pub fn nodeIsSameNode(node: *Node, other: *Node) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = nodeVtable(node).dom_node_is_same.?(node, other, &res);
|
const err = nodeVtable(node).dom_node_is_same.?(node, other, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeLookupPrefix(node: *Node, namespace: []const u8) ?[]const u8 {
|
pub fn nodeLookupPrefix(node: *Node, namespace: []const u8) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_lookup_prefix.?(node, stringFromData(namespace), &s);
|
const err = nodeVtable(node).dom_node_lookup_prefix.?(
|
||||||
|
node,
|
||||||
|
try stringFromData(namespace),
|
||||||
|
&s,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeLookupNamespaceURI(node: *Node, prefix: ?[]const u8) ?[]const u8 {
|
pub fn nodeLookupNamespaceURI(node: *Node, prefix: ?[]const u8) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = nodeVtable(node).dom_node_lookup_namespace.?(node, stringFromData(prefix.?), &s);
|
const err = nodeVtable(node).dom_node_lookup_namespace.?(
|
||||||
|
node,
|
||||||
|
try stringFromData(prefix.?),
|
||||||
|
&s,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeNormalize(node: *Node) void {
|
pub fn nodeNormalize(node: *Node) !void {
|
||||||
_ = nodeVtable(node).dom_node_normalize.?(node);
|
const err = nodeVtable(node).dom_node_normalize.?(node);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeRemoveChild(node: *Node, child: *Node) *Node {
|
pub fn nodeRemoveChild(node: *Node, child: *Node) !*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_remove_child.?(node, child, &res);
|
const err = nodeVtable(node).dom_node_remove_child.?(node, child, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeReplaceChild(node: *Node, new_child: *Node, old_child: *Node) *Node {
|
pub fn nodeReplaceChild(node: *Node, new_child: *Node, old_child: *Node) !*Node {
|
||||||
var res: ?*Node = undefined;
|
var res: ?*Node = undefined;
|
||||||
_ = nodeVtable(node).dom_node_replace_child.?(node, new_child, old_child, &res);
|
const err = nodeVtable(node).dom_node_replace_child.?(node, new_child, old_child, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,45 +646,53 @@ pub inline fn characterDataToNode(cdata: *CharacterData) *Node {
|
|||||||
return @as(*Node, @ptrCast(cdata));
|
return @as(*Node, @ptrCast(cdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataData(cdata: *CharacterData) []const u8 {
|
pub fn characterDataData(cdata: *CharacterData) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_get_data.?(cdata, &s);
|
const err = characterDataVtable(cdata).dom_characterdata_get_data.?(cdata, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataSetData(cdata: *CharacterData, data: []const u8) void {
|
pub fn characterDataSetData(cdata: *CharacterData, data: []const u8) !void {
|
||||||
const s = stringFromData(data);
|
const s = try stringFromData(data);
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_set_data.?(cdata, s);
|
const err = characterDataVtable(cdata).dom_characterdata_set_data.?(cdata, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataLength(cdata: *CharacterData) u32 {
|
pub fn characterDataLength(cdata: *CharacterData) !u32 {
|
||||||
var n: u32 = undefined;
|
var n: u32 = undefined;
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_get_length.?(cdata, &n);
|
const err = characterDataVtable(cdata).dom_characterdata_get_length.?(cdata, &n);
|
||||||
|
try DOMErr(err);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataAppendData(cdata: *CharacterData, data: []const u8) void {
|
pub fn characterDataAppendData(cdata: *CharacterData, data: []const u8) !void {
|
||||||
const s = stringFromData(data);
|
const s = try stringFromData(data);
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_append_data.?(cdata, s);
|
const err = characterDataVtable(cdata).dom_characterdata_append_data.?(cdata, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataDeleteData(cdata: *CharacterData, offset: u32, count: u32) void {
|
pub fn characterDataDeleteData(cdata: *CharacterData, offset: u32, count: u32) !void {
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_delete_data.?(cdata, offset, count);
|
const err = characterDataVtable(cdata).dom_characterdata_delete_data.?(cdata, offset, count);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataInsertData(cdata: *CharacterData, offset: u32, data: []const u8) void {
|
pub fn characterDataInsertData(cdata: *CharacterData, offset: u32, data: []const u8) !void {
|
||||||
const s = stringFromData(data);
|
const s = try stringFromData(data);
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_insert_data.?(cdata, offset, s);
|
const err = characterDataVtable(cdata).dom_characterdata_insert_data.?(cdata, offset, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataReplaceData(cdata: *CharacterData, offset: u32, count: u32, data: []const u8) void {
|
pub fn characterDataReplaceData(cdata: *CharacterData, offset: u32, count: u32, data: []const u8) !void {
|
||||||
const s = stringFromData(data);
|
const s = try stringFromData(data);
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_replace_data.?(cdata, offset, count, s);
|
const err = characterDataVtable(cdata).dom_characterdata_replace_data.?(cdata, offset, count, s);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn characterDataSubstringData(cdata: *CharacterData, offset: u32, count: u32) []const u8 {
|
pub fn characterDataSubstringData(cdata: *CharacterData, offset: u32, count: u32) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = characterDataVtable(cdata).dom_characterdata_substring_data.?(cdata, offset, count, &s);
|
const err = characterDataVtable(cdata).dom_characterdata_substring_data.?(cdata, offset, count, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,15 +703,17 @@ fn textVtable(text: *Text) c.dom_text_vtable {
|
|||||||
return getVtable(c.dom_text_vtable, Text, text);
|
return getVtable(c.dom_text_vtable, Text, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn textWholdeText(text: *Text) []const u8 {
|
pub fn textWholdeText(text: *Text) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = textVtable(text).dom_text_get_whole_text.?(text, &s);
|
const err = textVtable(text).dom_text_get_whole_text.?(text, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn textSplitText(text: *Text, offset: u32) *Text {
|
pub fn textSplitText(text: *Text, offset: u32) !*Text {
|
||||||
var res: ?*Text = undefined;
|
var res: ?*Text = undefined;
|
||||||
_ = textVtable(text).dom_text_split_text.?(text, offset, &res);
|
const err = textVtable(text).dom_text_split_text.?(text, offset, &res);
|
||||||
|
try DOMErr(err);
|
||||||
return res.?;
|
return res.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,23 +730,33 @@ fn elementVtable(elem: *Element) c.dom_element_vtable {
|
|||||||
return getVtable(c.dom_element_vtable, Element, elem);
|
return getVtable(c.dom_element_vtable, Element, elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elementLocalName(elem: *Element) []const u8 {
|
pub fn elementLocalName(elem: *Element) ![]const u8 {
|
||||||
const node = @as(*Node, @ptrCast(elem));
|
const node = @as(*Node, @ptrCast(elem));
|
||||||
return nodeLocalName(node);
|
return try nodeLocalName(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elementGetAttribute(elem: *Element, name: []const u8) ?[]const u8 {
|
pub fn elementGetAttribute(elem: *Element, name: []const u8) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = elementVtable(elem).dom_element_get_attribute.?(elem, stringFromData(name), &s);
|
const err = elementVtable(elem).dom_element_get_attribute.?(
|
||||||
|
elem,
|
||||||
|
try stringFromData(name),
|
||||||
|
&s,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elementHasClass(elem: *Element, class: []const u8) bool {
|
pub fn elementHasClass(elem: *Element, class: []const u8) !bool {
|
||||||
var res: bool = undefined;
|
var res: bool = undefined;
|
||||||
_ = elementVtable(elem).dom_element_has_class.?(elem, lwcStringFromData(class), &res);
|
const err = elementVtable(elem).dom_element_has_class.?(
|
||||||
|
elem,
|
||||||
|
try lwcStringFromData(class),
|
||||||
|
&res,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,9 +772,10 @@ fn elementHTMLVtable(elem_html: *ElementHTML) c.dom_html_element_vtable {
|
|||||||
return getVtable(c.dom_html_element_vtable, ElementHTML, elem_html);
|
return getVtable(c.dom_html_element_vtable, ElementHTML, elem_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elementHTMLGetTagType(elem_html: *ElementHTML) Tag {
|
pub fn elementHTMLGetTagType(elem_html: *ElementHTML) !Tag {
|
||||||
var tag_type: c.dom_html_element_type = undefined;
|
var tag_type: c.dom_html_element_type = undefined;
|
||||||
_ = elementHTMLVtable(elem_html).dom_html_element_get_tag_type.?(elem_html, &tag_type);
|
const err = elementHTMLVtable(elem_html).dom_html_element_get_tag_type.?(elem_html, &tag_type);
|
||||||
|
try DOMErr(err);
|
||||||
return @as(Tag, @enumFromInt(tag_type));
|
return @as(Tag, @enumFromInt(tag_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,26 +867,33 @@ fn documentTypeVtable(dt: *DocumentType) c.dom_document_type_vtable {
|
|||||||
return getVtable(c.dom_document_type_vtable, DocumentType, dt);
|
return getVtable(c.dom_document_type_vtable, DocumentType, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentTypeGetName(dt: *DocumentType) []const u8 {
|
pub inline fn documentTypeGetName(dt: *DocumentType) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = documentTypeVtable(dt).dom_document_type_get_name.?(dt, &s);
|
const err = documentTypeVtable(dt).dom_document_type_get_name.?(dt, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentTypeGetPublicId(dt: *DocumentType) []const u8 {
|
pub inline fn documentTypeGetPublicId(dt: *DocumentType) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = documentTypeVtable(dt).dom_document_type_get_public_id.?(dt, &s);
|
const err = documentTypeVtable(dt).dom_document_type_get_public_id.?(dt, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentTypeGetSystemId(dt: *DocumentType) []const u8 {
|
pub inline fn documentTypeGetSystemId(dt: *DocumentType) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = documentTypeVtable(dt).dom_document_type_get_system_id.?(dt, &s);
|
const err = documentTypeVtable(dt).dom_document_type_get_system_id.?(dt, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOMImplementation
|
// DOMImplementation
|
||||||
pub inline fn domImplementationCreateDocument(namespace: ?[:0]const u8, qname: ?[:0]const u8, doctype: ?*DocumentType) *Document {
|
pub inline fn domImplementationCreateDocument(
|
||||||
|
namespace: ?[:0]const u8,
|
||||||
|
qname: ?[:0]const u8,
|
||||||
|
doctype: ?*DocumentType,
|
||||||
|
) !*Document {
|
||||||
var doc: ?*Document = undefined;
|
var doc: ?*Document = undefined;
|
||||||
|
|
||||||
var ptrnamespace: [*c]const u8 = null;
|
var ptrnamespace: [*c]const u8 = null;
|
||||||
@@ -840,7 +906,7 @@ pub inline fn domImplementationCreateDocument(namespace: ?[:0]const u8, qname: ?
|
|||||||
ptrqname = qn.ptr;
|
ptrqname = qn.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = c.dom_implementation_create_document(
|
const err = c.dom_implementation_create_document(
|
||||||
c.DOM_IMPLEMENTATION_XML,
|
c.DOM_IMPLEMENTATION_XML,
|
||||||
ptrnamespace,
|
ptrnamespace,
|
||||||
ptrqname,
|
ptrqname,
|
||||||
@@ -849,18 +915,24 @@ pub inline fn domImplementationCreateDocument(namespace: ?[:0]const u8, qname: ?
|
|||||||
null,
|
null,
|
||||||
&doc,
|
&doc,
|
||||||
);
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return doc.?;
|
return doc.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn domImplementationCreateDocumentType(qname: [:0]const u8, publicId: [:0]const u8, systemId: [:0]const u8) *DocumentType {
|
pub inline fn domImplementationCreateDocumentType(
|
||||||
|
qname: [:0]const u8,
|
||||||
|
publicId: [:0]const u8,
|
||||||
|
systemId: [:0]const u8,
|
||||||
|
) !*DocumentType {
|
||||||
var dt: ?*DocumentType = undefined;
|
var dt: ?*DocumentType = undefined;
|
||||||
_ = c.dom_implementation_create_document_type(qname.ptr, publicId.ptr, systemId.ptr, &dt);
|
const err = c.dom_implementation_create_document_type(qname.ptr, publicId.ptr, systemId.ptr, &dt);
|
||||||
|
try DOMErr(err);
|
||||||
return dt.?;
|
return dt.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8) *Document {
|
pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8) !*Document {
|
||||||
var doc: ?*Document = undefined;
|
var doc: ?*Document = undefined;
|
||||||
_ = c.dom_implementation_create_document(
|
const err = c.dom_implementation_create_document(
|
||||||
c.DOM_IMPLEMENTATION_HTML,
|
c.DOM_IMPLEMENTATION_HTML,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -869,6 +941,7 @@ pub inline fn domImplementationCreateHTMLDocument(title: ?[]const u8) *Document
|
|||||||
null,
|
null,
|
||||||
&doc,
|
&doc,
|
||||||
);
|
);
|
||||||
|
try DOMErr(err);
|
||||||
// TODO set title
|
// TODO set title
|
||||||
_ = title;
|
_ = title;
|
||||||
return doc.?;
|
return doc.?;
|
||||||
@@ -881,52 +954,77 @@ fn documentVtable(doc: *Document) c.dom_document_vtable {
|
|||||||
return getVtable(c.dom_document_vtable, Document, doc);
|
return getVtable(c.dom_document_vtable, Document, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentGetElementById(doc: *Document, id: []const u8) ?*Element {
|
pub inline fn documentGetElementById(doc: *Document, id: []const u8) !?*Element {
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_element_by_id.?(doc, stringFromData(id), &elem);
|
const err = documentVtable(doc).dom_document_get_element_by_id.?(
|
||||||
|
doc,
|
||||||
|
try stringFromData(id),
|
||||||
|
&elem,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentGetElementsByTagName(doc: *Document, tagname: []const u8) *NodeList {
|
pub inline fn documentGetElementsByTagName(doc: *Document, tagname: []const u8) !*NodeList {
|
||||||
var nlist: ?*NodeList = undefined;
|
var nlist: ?*NodeList = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_elements_by_tag_name.?(doc, stringFromData(tagname), &nlist);
|
const err = documentVtable(doc).dom_document_get_elements_by_tag_name.?(
|
||||||
|
doc,
|
||||||
|
try stringFromData(tagname),
|
||||||
|
&nlist,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return nlist.?;
|
return nlist.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentGetDocumentElement returns the root document element.
|
// documentGetDocumentElement returns the root document element.
|
||||||
pub inline fn documentGetDocumentElement(doc: *Document) *Element {
|
pub inline fn documentGetDocumentElement(doc: *Document) !*Element {
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_document_element.?(doc, &elem);
|
const err = documentVtable(doc).dom_document_get_document_element.?(doc, &elem);
|
||||||
|
try DOMErr(err);
|
||||||
return elem.?;
|
return elem.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentGetDocumentURI(doc: *Document) []const u8 {
|
pub inline fn documentGetDocumentURI(doc: *Document) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_uri.?(doc, &s);
|
const err = documentVtable(doc).dom_document_get_uri.?(doc, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentGetInputEncoding(doc: *Document) []const u8 {
|
pub inline fn documentGetInputEncoding(doc: *Document) ![]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_input_encoding.?(doc, &s);
|
const err = documentVtable(doc).dom_document_get_input_encoding.?(doc, &s);
|
||||||
|
try DOMErr(err);
|
||||||
return stringToData(s.?);
|
return stringToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentCreateElement(doc: *Document, tag_name: []const u8) *Element {
|
pub inline fn documentCreateElement(doc: *Document, tag_name: []const u8) !*Element {
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
_ = documentVtable(doc).dom_document_create_element.?(doc, stringFromData(tag_name), &elem);
|
const err = documentVtable(doc).dom_document_create_element.?(
|
||||||
|
doc,
|
||||||
|
try stringFromData(tag_name),
|
||||||
|
&elem,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return elem.?;
|
return elem.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentCreateElementNS(doc: *Document, ns: []const u8, tag_name: []const u8) *Element {
|
pub inline fn documentCreateElementNS(doc: *Document, ns: []const u8, tag_name: []const u8) !*Element {
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
_ = documentVtable(doc).dom_document_create_element_ns.?(doc, stringFromData(ns), stringFromData(tag_name), &elem);
|
const err = documentVtable(doc).dom_document_create_element_ns.?(
|
||||||
|
doc,
|
||||||
|
try stringFromData(ns),
|
||||||
|
try stringFromData(tag_name),
|
||||||
|
&elem,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
return elem.?;
|
return elem.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentGetDoctype(doc: *Document) ?*DocumentType {
|
pub inline fn documentGetDoctype(doc: *Document) !?*DocumentType {
|
||||||
var dt: ?*DocumentType = undefined;
|
var dt: ?*DocumentType = undefined;
|
||||||
_ = documentVtable(doc).dom_document_get_doctype.?(doc, &dt);
|
const err = documentVtable(doc).dom_document_get_doctype.?(doc, &dt);
|
||||||
|
try DOMErr(err);
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,17 +1080,19 @@ pub fn documentHTMLParseFromStr(cstr: [:0]const u8) !*DocumentHTML {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// documentHTMLClose closes the document.
|
// documentHTMLClose closes the document.
|
||||||
pub fn documentHTMLClose(doc: *DocumentHTML) void {
|
pub fn documentHTMLClose(doc: *DocumentHTML) !void {
|
||||||
_ = documentHTMLVtable(doc).close.?(doc);
|
const err = documentHTMLVtable(doc).close.?(doc);
|
||||||
|
try DOMErr(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentHTMLToDocument(doc_html: *DocumentHTML) *Document {
|
pub inline fn documentHTMLToDocument(doc_html: *DocumentHTML) *Document {
|
||||||
return @as(*Document, @ptrCast(doc_html));
|
return @as(*Document, @ptrCast(doc_html));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentHTMLBody(doc_html: *DocumentHTML) ?*Body {
|
pub inline fn documentHTMLBody(doc_html: *DocumentHTML) !?*Body {
|
||||||
var body: ?*ElementHTML = undefined;
|
var body: ?*ElementHTML = undefined;
|
||||||
_ = documentHTMLVtable(doc_html).get_body.?(doc_html, &body);
|
const err = documentHTMLVtable(doc_html).get_body.?(doc_html, &body);
|
||||||
|
try DOMErr(err);
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ fn testExecFn(
|
|||||||
|
|
||||||
// document
|
// document
|
||||||
doc = try parser.documentHTMLParseFromFileAlloc(std.testing.allocator, "test.html");
|
doc = try parser.documentHTMLParseFromFileAlloc(std.testing.allocator, "test.html");
|
||||||
defer parser.documentHTMLClose(doc);
|
defer parser.documentHTMLClose(doc) catch |err| {
|
||||||
|
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
|
||||||
// add document object
|
// add document object
|
||||||
try js_env.addObject(apis, doc, "document");
|
try js_env.addObject(apis, doc, "document");
|
||||||
|
|||||||
2
vendor/jsruntime-lib
vendored
2
vendor/jsruntime-lib
vendored
Submodule vendor/jsruntime-lib updated: b306f4688a...d63b0a592f
Reference in New Issue
Block a user