element: innerText which must return rendered text

This commit is contained in:
Pierre Tachoire
2025-12-06 19:09:20 +01:00
parent f5d3dede6b
commit a673eb89b6
2 changed files with 48 additions and 1 deletions

View File

@@ -1,6 +1,12 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=d1>hello <em>world</em></div>
<div id=d2>
<style>h1 { font-size: 1em; }</style>
<!-- this is a comment -->
This is a <br>
text
</div>
<script id=innerHTML>
const d1 = $('#d1');
@@ -20,6 +26,9 @@
d1.innerHTML = '<script src=inner.js>';
testing.expectEqual('<script src="inner.js"><\/script>', d1.innerHTML);
testing.expectEqual(false, inner_loaded);
const d2 = $('#d2');
testing.expectEqual("\n <style>h1 { font-size: 1em; }</style>\n <!-- this is a comment -->\n This is a <br>\n text\n", d2.innerHTML);
</script>
<script id=ids>
@@ -160,4 +169,8 @@
d1.innerText = 'new content';
testing.expectEqual('new content', d1.innerText);
testing.expectEqual(null, $('#link2'));
// TODO innerText is not rendered correctly for now.
//testing.expectEqual("This is a\ntext", d2.innerText);
testing.expectEqual(" This is a \n text", d2.innerText);
</script>

View File

@@ -223,10 +223,44 @@ pub fn getNamespaceURI(self: *const Element) []const u8 {
return self._namespace.toUri();
}
// innerText represents the **rendered** text content of a node and its
// descendants.
pub fn getInnerText(self: *Element, writer: *std.Io.Writer) !void {
var it = self.asNode().childrenIterator();
while (it.next()) |child| {
try child.getTextContent(writer);
switch (child._type) {
.element => |e| switch (e._type) {
.html => |he| switch (he._type) {
.br => try writer.writeByte('\n'),
.script, .style, .template => continue,
else => try e.getInnerText(writer), // TODO check if elt is hidden.
},
.svg => {},
},
.cdata => |c| switch (c._type) {
.comment => continue,
.text => {
const data = c.getData();
if (std.mem.trim(u8, data, &std.ascii.whitespace).len != 0) {
// Trim all whitespaces except spaces.
// TODO this is not the correct way to render text, this is
// a temp approximation.
const text = std.mem.trim(u8, data, &[_]u8{
'\t',
'\n',
'\r',
std.ascii.control_code.vt,
std.ascii.control_code.ff,
});
try writer.writeAll(text);
}
},
},
.document => {},
.document_type => {},
.document_fragment => {},
.attribute => |attr| try writer.writeAll(attr._value),
}
}
}