diff --git a/src/browser/tests/element/inner.html b/src/browser/tests/element/inner.html
index 7c59ea14d..f8088357f 100644
--- a/src/browser/tests/element/inner.html
+++ b/src/browser/tests/element/inner.html
@@ -11,6 +11,10 @@
Hello
World
+
+aXbYc
+
+
diff --git a/src/browser/webapi/Element.zig b/src/browser/webapi/Element.zig
index 42f00be7b..4f2d62db1 100644
--- a/src/browser/webapi/Element.zig
+++ b/src/browser/webapi/Element.zig
@@ -453,9 +453,9 @@ pub fn getLocalName(self: *Element) []const u8 {
}
// Wrapper methods that delegate to Html implementations
-pub fn getInnerText(self: *Element, writer: *std.Io.Writer) !void {
+pub fn getInnerText(self: *Element, writer: *std.Io.Writer, frame: *Frame) !void {
const he = self.is(Html) orelse return error.NotHtmlElement;
- return he.getInnerText(writer);
+ return he.getInnerText(writer, frame);
}
pub fn setInnerText(self: *Element, text: []const u8, frame: *Frame) !void {
@@ -1913,9 +1913,9 @@ pub const JsApi = struct {
pub const namespaceURI = bridge.accessor(Element.getNamespaceURI, null, .{});
pub const innerText = bridge.accessor(_innerText, Element.setInnerText, .{ .ce_reactions = true });
- fn _innerText(self: *Element, frame: *const Frame) ![]const u8 {
+ fn _innerText(self: *Element, frame: *Frame) ![]const u8 {
var buf = std.Io.Writer.Allocating.init(frame.call_arena);
- try self.getInnerText(&buf.writer);
+ try self.getInnerText(&buf.writer, frame);
return buf.written();
}
diff --git a/src/browser/webapi/element/Html.zig b/src/browser/webapi/element/Html.zig
index 6549384ab..4571d71cb 100644
--- a/src/browser/webapi/element/Html.zig
+++ b/src/browser/webapi/element/Html.zig
@@ -216,13 +216,14 @@ pub fn asEventTarget(self: *HtmlElement) *@import("../EventTarget.zig") {
return self._proto._proto._proto;
}
-pub fn getInnerText(self: *HtmlElement, writer: *std.Io.Writer) !void {
+pub fn getInnerText(self: *HtmlElement, writer: *std.Io.Writer, frame: *Frame) !void {
const tag = self.asElement().getTag();
switch (innerTextDisplay(self, tag)) {
.skip, .replaced => return,
else => {},
}
- var state = InnerTextState{ .writer = writer, .preserve = tag == .pre };
+
+ var state = InnerTextState{ .writer = writer, .frame = frame, .preserve = tag == .pre };
try self.collectInnerText(&state);
}
@@ -1326,6 +1327,13 @@ pub fn reflectEnumerated(
const InnerTextState = struct {
writer: *std.Io.Writer,
+
+ // Needed to reach the StyleManager for CSS-driven visibility (display:none).
+ frame: *Frame,
+
+ // Tree-local visibility cache shared across the whole walk (see getInnerText).
+ cache: Element.VisibilityCache = .{},
+
// number of line breaks we've accumulated for the block. Emitted lazily that
// leading/trailing breaks aren't written and so that we can emit the max
// requested, which can change as we render children.
@@ -1450,6 +1458,10 @@ fn handleChildElement(
return;
}
+ if (state.frame._style_manager.isHidden(he.asElement(), &state.cache, .{})) {
+ return;
+ }
+
switch (innerTextDisplay(he, tag)) {
// Not rendered: skip the subtree entirely (script/style/metadata/...).
.skip => {},
@@ -1632,9 +1644,9 @@ pub const JsApi = struct {
pub const constructor = bridge.constructor(HtmlElement.construct, .{ .new_target = true });
pub const innerText = bridge.accessor(_innerText, _setInnerText, .{ .ce_reactions = true });
- fn _innerText(self: *HtmlElement, frame: *const Frame) ![]const u8 {
+ fn _innerText(self: *HtmlElement, frame: *Frame) ![]const u8 {
var buf = std.Io.Writer.Allocating.init(frame.call_arena);
- try self.getInnerText(&buf.writer);
+ try self.getInnerText(&buf.writer, frame);
return buf.written();
}
fn _setInnerText(self: *HtmlElement, value: js.Value, frame: *Frame) !void {
diff --git a/src/cdp/AXNode.zig b/src/cdp/AXNode.zig
index 23b2c2bfe..d74073228 100644
--- a/src/cdp/AXNode.zig
+++ b/src/cdp/AXNode.zig
@@ -1011,7 +1011,7 @@ fn writeName(
if (doc.getElementById(trimmed_id, frame)) |referenced_el| {
// Get the text content of the referenced element
- try referenced_el.getInnerText(&buf.writer);
+ try referenced_el.getInnerText(&buf.writer, frame);
try buf.writer.writeByte(' ');
has_content = true;
}
@@ -1262,7 +1262,7 @@ fn writeLabelInnerText(
w: anytype,
) !bool {
var buf: std.Io.Writer.Allocating = .init(scratchAllocator(temp_arena, frame));
- try label_el.getInnerText(&buf.writer);
+ try label_el.getInnerText(&buf.writer, frame);
const text = std.mem.trim(u8, buf.written(), &std.ascii.whitespace);
if (text.len == 0) return false;
try writeString(text, w);