markdown: reuse dump's shouldStripElement

This commit is contained in:
Adrià Arrufat committed 2026-08-26 15:32:25 +02:00
1 parent c78c1d3823
commit e46964e261
3 files changed
+14 -15

No files matched your search

+7 -7
View File
@@ -111,7 +111,7 @@ fn _deep(node: *Node, opts: Opts, comptime force_slot: bool, writer: *std.Io.Wri
},
.element => {
const el = node.subtype(Node.Element);
if (shouldStripElement(el, opts, frame)) {
if (shouldStripElement(el, opts.strip, frame)) {
return;
}
@@ -338,15 +338,15 @@ fn isVoidElement(el: *const Node.Element) bool {
};
}
fn shouldStripElement(el: *Node.Element, opts: Opts, frame: *Frame) bool {
pub fn shouldStripElement(el: *Node.Element, strip: Opts.Strip, frame: *Frame) bool {
// Fast path: with no strip flags set (every innerHTML/outerHTML call)
if (@as(u4, @bitCast(opts.strip)) == 0) {
if (@as(u4, @bitCast(strip)) == 0) {
return false;
}
const tag_name = el.getTagNameDump();
if (opts.strip.js) {
if (strip.js) {
if (std.mem.eql(u8, tag_name, "script")) return true;
if (std.mem.eql(u8, tag_name, "noscript")) return true;
@@ -364,7 +364,7 @@ fn shouldStripElement(el: *Node.Element, opts: Opts, frame: *Frame) bool {
}
}
if (opts.strip.css or opts.strip.ui) {
if (strip.css or strip.ui) {
if (std.mem.eql(u8, tag_name, "style")) return true;
if (std.mem.eql(u8, tag_name, "link")) {
@@ -374,7 +374,7 @@ fn shouldStripElement(el: *Node.Element, opts: Opts, frame: *Frame) bool {
}
}
if (opts.strip.ui) {
if (strip.ui) {
if (std.mem.eql(u8, tag_name, "img")) return true;
if (std.mem.eql(u8, tag_name, "picture")) return true;
if (std.mem.eql(u8, tag_name, "video")) return true;
@@ -384,7 +384,7 @@ fn shouldStripElement(el: *Node.Element, opts: Opts, frame: *Frame) bool {
if (std.mem.eql(u8, tag_name, "iframe")) return true;
}
if (opts.strip.invisible and frame._style_manager.hasAuthorDisplayNone(el, .scan)) {
if (strip.invisible and frame._style_manager.hasAuthorDisplayNone(el, .scan)) {
return true;
}
+5 -6
View File
@@ -28,12 +28,11 @@ const Slot = @import("webapi/element/html/Slot.zig");
const isAllWhitespace = @import("../string.zig").isAllWhitespace;
const LimitedWriter = @import("../LimitedWriter.zig");
const Strip = @import("dump.zig").Opts.Strip;
const dump_html = @import("dump.zig");
const Strip = dump_html.Opts.Strip;
pub const Opts = struct {
max_bytes: ?u32 = null,
// Only `ui` (images) applies: scripts, styles and hidden elements are
// never rendered.
strip: Strip = .{},
};
@@ -217,6 +216,7 @@ const Context = struct {
const tag = el.getTag();
if (el.asNode() != self.root and !isVisibleElement(el, self.frame)) return;
if (dump_html.shouldStripElement(el, self.strip, self.frame)) return;
if (!force_slot) {
if (el.getAttributeSafe(comptime .wrap("slot")) != null) {
@@ -323,7 +323,6 @@ const Context = struct {
return;
},
.img => {
if (self.strip.ui) return;
try self.writer.writeAll("![");
if (el.getAttributeSafe(comptime .wrap("alt"))) |alt| {
try self.escape(alt);
@@ -865,14 +864,14 @@ test "browser.markdown: scoped dump of a hidden subtree still renders it" {
try testing.expectString("\ndialog text\n", aw.written());
}
test "browser.markdown: strip.ui drops images" {
test "browser.markdown: strip.ui drops images and other visual elements" {
const frame = try testing.createFrame();
defer testing.test_session.closeAllPages();
frame.url = "http://localhost/";
const doc = frame.window._document;
const div = try doc.createElement("div", null, frame);
try Frame.parse.htmlAsChildren(frame, div.asNode(), "<p>Text <img src=\"a.png\" alt=\"A\"> more</p>");
try Frame.parse.htmlAsChildren(frame, div.asNode(), "<p>Text <img src=\"a.png\" alt=\"A\"> more<canvas>fallback</canvas></p>");
var aw: std.Io.Writer.Allocating = .init(testing.allocator);
defer aw.deinit();
+2 -2
View File
@@ -97,8 +97,8 @@
\\ of the whole document. Fails if nothing matches.
\\ --strip-mode <STRIP>
\\ Tag group to remove from dump. Can be passed multiple times.
\\ Markdown never contains scripts, styles or hidden elements, so
\\ only 'ui' (images) applies to it.
\\ In markdown only 'ui' changes the output: scripts, styles and
\\ hidden elements are never rendered.
\\ Defaults to no-strip.
\\ Allowed values:
\\ js Script and link[as=script, rel=preload].