From e46964e261bfecb9bf869ffdef7a706dd693bbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Wed, 26 Aug 2026 15:31:11 +0200 Subject: [PATCH] markdown: reuse dump's shouldStripElement --- src/browser/dump.zig | 14 +++++++------- src/browser/markdown.zig | 11 +++++------ src/help.zon | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/browser/dump.zig b/src/browser/dump.zig index 1a6bc1344..89bd6fd64 100644 --- a/src/browser/dump.zig +++ b/src/browser/dump.zig @@ -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; } diff --git a/src/browser/markdown.zig b/src/browser/markdown.zig index ca9cecc81..da701b028 100644 --- a/src/browser/markdown.zig +++ b/src/browser/markdown.zig @@ -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(), "

Text \"A\" more

"); + try Frame.parse.htmlAsChildren(frame, div.asNode(), "

Text \"A\" morefallback

"); var aw: std.Io.Writer.Allocating = .init(testing.allocator); defer aw.deinit(); diff --git a/src/help.zon b/src/help.zon index 364685310..eb1261899 100644 --- a/src/help.zon +++ b/src/help.zon @@ -97,8 +97,8 @@ \\ of the whole document. Fails if nothing matches. \\ --strip-mode \\ 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].