Merge pull request #1205 from lightpanda-io/template-content

handle template's original content
This commit is contained in:
Pierre Tachoire
2025-11-13 08:27:46 +01:00
committed by GitHub
3 changed files with 46 additions and 1 deletions

View File

@@ -390,7 +390,23 @@ pub const Node = struct {
return parser.nodeHasChildNodes(self);
}
fn is_template(self: *parser.Node) !bool {
if (parser.nodeType(self) != .element) {
return false;
}
const e = parser.nodeToElement(self);
return try parser.elementTag(e) == .template;
}
pub fn get_childNodes(self: *parser.Node, page: *Page) !NodeList {
// special case for template:
// > The Node.childNodes property of the <template> element is always empty
// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/template#usage_notes
if (try is_template(self)) {
return .{};
}
const allocator = page.arena;
var list: NodeList = .{};

View File

@@ -33,6 +33,8 @@ const DataSet = @import("DataSet.zig");
const StyleSheet = @import("../cssom/StyleSheet.zig");
const CSSStyleDeclaration = @import("../cssom/CSSStyleDeclaration.zig");
const WalkerChildren = @import("../dom/walker.zig").WalkerChildren;
// HTMLElement interfaces
pub const Interfaces = .{
Element,
@@ -1200,11 +1202,22 @@ pub const HTMLTemplateElement = struct {
pub const subtype = .node;
pub fn get_content(self: *parser.Template, page: *Page) !*parser.DocumentFragment {
const state = try page.getOrCreateNodeState(@ptrCast(@alignCast(self)));
const n: *parser.Node = @ptrCast(@alignCast(self));
const state = try page.getOrCreateNodeState(n);
if (state.template_content) |tc| {
return tc;
}
const tc = try parser.documentCreateDocumentFragment(@ptrCast(page.window.document));
const ntc: *parser.Node = @ptrCast(@alignCast(tc));
// move existing template's childnodes to the fragment.
const walker = WalkerChildren{};
var next: ?*parser.Node = null;
while (true) {
next = try walker.get_next(n, next) orelse break;
_ = try parser.nodeAppendChild(ntc, next.?);
}
state.template_content = tc;
return tc;
}

View File

@@ -20,3 +20,19 @@
testing.expectEqual('P', t.content.childNodes[1].tagName);
testing.expectEqual('9000!', t.content.childNodes[1].innerHTML);
</script>
<template id="hello"><p>hello, world</p></template>
<script id=template_parsing>
const tt = document.getElementById('hello');
testing.expectEqual('<p>hello, world</p>', tt.innerHTML);
// > The Node.childNodes property of the <template> element is always empty
// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/template#usage_notes
testing.expectEqual(0, tt.childNodes.length);
let out = document.createElement('div');
out.appendChild(tt.content.cloneNode(true));
testing.expectEqual('<p>hello, world</p>', out.innerHTML);
</script>