Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dom: add DocumentType #75

Merged
merged 2 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/dom/document.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const HTMLCollection = @import("html_collection.zig").HTMLCollection;
const Element = @import("element.zig").Element;
const ElementUnion = @import("element.zig").Union;

const DocumentType = @import("document_type.zig").DocumentType;

// WEB IDL https://dom.spec.whatwg.org/#document
pub const Document = struct {
pub const Self = parser.Document;
Expand All @@ -25,6 +27,10 @@ pub const Document = struct {

// JS funcs
// --------
//
pub fn get_doctype(self: *parser.Document) ?*parser.DocumentType {
return parser.documentGetDoctype(self);
}

pub fn _getElementById(self: *parser.Document, id: []const u8) ?ElementUnion {
const e = parser.documentGetElementById(self, id) orelse return null;
Expand Down
24 changes: 24 additions & 0 deletions src/dom/document_type.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const std = @import("std");

const parser = @import("../netsurf.zig");

const Node = @import("node.zig").Node;

// WEB IDL https://dom.spec.whatwg.org/#documenttype
pub const DocumentType = struct {
pub const Self = parser.DocumentType;
pub const prototype = *Node;
pub const mem_guarantied = true;

pub fn get_name(self: *parser.DocumentType) []const u8 {
return parser.documentTypeGetName(self);
}

pub fn get_publicId(self: *parser.DocumentType) []const u8 {
return parser.documentTypeGetPublicId(self);
}

pub fn get_systemId(self: *parser.DocumentType) []const u8 {
return parser.documentTypeGetSystemId(self);
}
};
3 changes: 3 additions & 0 deletions src/dom/node.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const EventTarget = @import("event_target.zig").EventTarget;
const CData = @import("character_data.zig");
const Element = @import("element.zig").Element;
const Document = @import("document.zig").Document;
const DocumentType = @import("document_type.zig").DocumentType;
const HTMLCollection = @import("html_collection.zig").HTMLCollection;

// HTML
Expand All @@ -26,6 +27,7 @@ pub const Interfaces = generate.Tuple(.{
CData.Interfaces,
Element,
Document,
DocumentType,
HTMLCollection,

HTML.Interfaces,
Expand All @@ -46,6 +48,7 @@ pub const Node = struct {
.comment => .{ .Comment = @as(*parser.Comment, @ptrCast(node)) },
.text => .{ .Text = @as(*parser.Text, @ptrCast(node)) },
.document => .{ .HTMLDocument = @as(*parser.DocumentHTML, @ptrCast(node)) },
.document_type => .{ .DocumentType = @as(*parser.DocumentType, @ptrCast(node)) },
else => @panic("node type not handled"), // TODO
};
}
Expand Down
31 changes: 31 additions & 0 deletions src/netsurf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,31 @@ pub const DocumentPosition = enum(u2) {
implementation_specific = c.DOM_DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
};

// DocumentType
pub const DocumentType = c.dom_document_type;

fn documentTypeVtable(dt: *DocumentType) c.dom_document_type_vtable {
return getVtable(c.dom_document_type_vtable, DocumentType, dt);
}

pub inline fn documentTypeGetName(dt: *DocumentType) []const u8 {
var s: ?*String = undefined;
_ = documentTypeVtable(dt).dom_document_type_get_name.?(dt, &s);
return stringToData(s.?);
}

pub inline fn documentTypeGetPublicId(dt: *DocumentType) []const u8 {
var s: ?*String = undefined;
_ = documentTypeVtable(dt).dom_document_type_get_public_id.?(dt, &s);
return stringToData(s.?);
}

pub inline fn documentTypeGetSystemId(dt: *DocumentType) []const u8 {
var s: ?*String = undefined;
_ = documentTypeVtable(dt).dom_document_type_get_system_id.?(dt, &s);
return stringToData(s.?);
}

// Document
pub const Document = c.dom_document;

Expand Down Expand Up @@ -758,6 +783,12 @@ pub inline fn documentCreateElementNS(doc: *Document, ns: []const u8, tag_name:
return elem.?;
}

pub inline fn documentGetDoctype(doc: *Document) ?*DocumentType {
var dt: ?*DocumentType = undefined;
_ = documentVtable(doc).dom_document_get_doctype.?(doc, &dt);
return dt;
}

// DocumentHTML
pub const DocumentHTML = c.dom_html_document;

Expand Down
21 changes: 21 additions & 0 deletions tests/wpt/dom/nodes/Document-doctype.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- comment -->
<!doctype html>
<meta charset=utf-8>
<title>Document.doctype</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-doctype">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
assert_true(document.doctype instanceof DocumentType,
"Doctype should be a DocumentType");
assert_equals(document.doctype, document.childNodes[1]);
}, "Window document with doctype");

test(function() {
var newdoc = new Document();
newdoc.appendChild(newdoc.createElement("html"));
assert_equals(newdoc.doctype, null);
}, "new Document()");
</script>
17 changes: 17 additions & 0 deletions tests/wpt/dom/nodes/DocumentType-literal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC "STAFF" "staffNS.dtd">
<title>DocumentType literals</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-documenttype-name">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-documenttype-publicid">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-documenttype-systemid">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var doctype = document.firstChild;
assert_true(doctype instanceof DocumentType)
assert_equals(doctype.name, "html")
assert_equals(doctype.publicId, 'STAFF')
assert_equals(doctype.systemId, 'staffNS.dtd')
})
</script>
Loading