Skip to content

fix(html2md): preserve visible labels and literal preformatted text - #1591

Closed
lanyue-llk wants to merge 1 commit into
mainfrom
codex/webfetch-markdown
Closed

lanyue-llk wants to merge 1 commit into
mainfrom
codex/webfetch-markdown

Conversation

@lanyue-llk

@lanyue-llk lanyue-llk commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Problem

HTML-to-Markdown conversion could lose visible control labels and declared media addresses. Inside a pre block, appending a link destination also changed copyable source text: a linked String type became String (/types/String) inside the code sample.

Change

Preserve visible labels, whitespace, and media URLs already present in the supplied DOM. Keep pre content literal even when the page omits a nested code element. Named links found inside pre remain available after the closing fence, using the existing link writer, without altering the fenced text.

The converter reads the supplied DOM only. It performs no additional fetches. data: and blob: values remain excluded because they are run-local or potentially unbounded, while ordinary portable resource URLs are retained.

Reproduce and verify

Convert this fragment:

<pre class="language-rust">let value: <a href="/types/String">String</a> = String::new();</pre>

The fenced source must remain let value: String = String::new();; the named destination appears after the fence. Additional fixtures cover empty-link labels, directory listings, audio/video/source/track/poster URLs, unsafe script URLs, and inline code.

cargo test --locked -p moli-html2md

The media fixtures correspond to Web Fetch's embedded-media contract: return resource addresses already exposed by the page. No per-site or per-case branch is added. CI validates the exact PR branch.

Dependencies

Independent change targeting main; no other open PR is required.

Browser Eval integration reproduction

Build this branch, register the exact executable and SHA-256 as moli-candidate, then run the frozen embedded-media cases through Browser Eval's certified native-fetch entry point:

uv run --frozen python scripts/run_certified_benchmark.py \
  --dataset /absolute/path/to/frozen-webfetch-430.json \
  --output /tmp/moli-1591-browser-eval \
  --work-root /tmp/moli-1591-browser-eval-work \
  --providers moli-candidate \
  --case-ids image-01,video-01,video-03 \
  --provider-config /absolute/path/to/moli-candidate-providers.json \
  --workers 1 \
  --retrieval-mode native \
  --diagnostic

The exact Linux x86-64 artifact for 829f1989da7b passed all three frozen cases: responsive image sources (image-01), multiple video sources (video-01), and video poster/resource addresses (video-03). The observed call times were 6.62 s, 8.60 s, and 7.05 s. These cases exercise the public resource-address contract through the same adapter and scorer used by the 430-task report.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Spider Bench A/B

✅ All benchmark browser service runs completed; results are informational.

Public HEAD: 184 / 240 rows; 38 / 48 sites produced rows; 10 unexpected empty sites.

✅ Deterministic fixture contract is clean.

Common ancestor f702d9a65dc6 → HEAD 829f1989da7b; benchmark order: head-first; workflow: success.

Public 48-site run · informational

Metric Base HEAD Δ
Run status success success —
Extracted rows / contract 184 / 240 184 / 240 0 (0.00%)
Contract fill 76.67% 76.67% 0.00 pp (0.00%)
Sites with rows 38 / 48 38 / 48 0 (0.00%)
Sites meeting row contract 36 / 48 36 / 48 0 (0.00%)
Unexpected empty sites 10 10 0 (0.00%)
Partial-row sites 2 2 0 (0.00%)
Site outcomes extracted: 37; HTTP error + rows: 1; empty: 7; HTTP error + empty: 1; snapshot error + empty: 2 extracted: 36; HTTP error + rows: 2; empty: 7; HTTP error + empty: 1; snapshot error + empty: 2 —
Observed duration 44.91 s 44.05 s -0.85 s (-1.90%)
Estimated CPU 41.91 s 37.47 s -4.44 s (-10.60%)
Peak PSS 268.14 MiB 265.03 MiB -3.11 MiB (-1.16%)
Peak RSS 271.60 MiB 268.63 MiB -2.97 MiB (-1.09%)
Peak threads 26 27 +1 (+3.85%)
Mismatched sites 0 0 0
Timeout with items 0 0 0
Category rows Base HEAD Δ
news 35 / 40 35 / 40 0
stocks 20 / 40 20 / 40 0
tech 35 / 40 35 / 40 0
sports 27 / 40 27 / 40 0
games 37 / 40 37 / 40 0
life 30 / 40 30 / 40 0

Public-site content, timing, and memory are noisy. This single A/B run reports evidence only; site outcome counts explain missing rows without treating them as a deterministic regression.

CPU and memory timelines

These are bounded 40-point views of the same complete process-tree samples used by the HTML report. CPU uses 100% per occupied logical core; memory lines are RSS first and PSS second when complete PSS samples are available.

Base

xychart-beta
    title "Base CPU"
    x-axis "Elapsed seconds" [1.036, 1.536, 2.537, 4.039, 5.041, 6.543, 7.545, 9.046, 10.047, 11.551, 12.552, 14.055, 15.058, 16.059, 16.56, 17.562, 19.065, 20.066, 21.568, 22.571, 24.073, 25.075, 26.577, 27.578, 29.08, 30.081, 31.584, 32.583, 34.085, 35.088, 36.588, 37.589, 39.09, 40.091, 41.591, 42.592, 44.094, 44.595]
    y-axis "CPU percent" 0 --> 200
    line [13.99, 129.84, 117.84, 153.72, 119.87, 139.75, 141.87, 78.01, 103.79, 107.75, 115.76, 3.99, 2, 0, 5.99, 83.85, 91.94, 43.92, 95.97, 101.78, 133.86, 105.7, 135.82, 109.86, 59.92, 117.87, 107.71, 98.17, 71.95, 65.85, 128.01, 133.92, 19.97, 9.99, 100.06, 13.99, 127.86, 173.64]
Loading
xychart-beta
    title "Base memory: RSS then PSS"
    x-axis "Elapsed seconds" [0.036, 1.036, 1.536, 2.537, 4.039, 5.041, 6.543, 7.545, 9.046, 10.047, 11.551, 12.552, 14.055, 15.058, 16.059, 16.56, 17.562, 19.065, 20.066, 21.568, 22.571, 24.073, 25.075, 26.577, 27.578, 29.08, 30.081, 31.584, 32.583, 34.085, 35.088, 36.588, 37.589, 39.09, 40.091, 41.591, 42.592, 44.094, 44.595, 44.908]
    y-axis "Memory MiB" 0 --> 500
    line [13.16, 73.45, 103.04, 104, 141.19, 156.29, 135.59, 161.41, 148.74, 142.86, 130.08, 131.96, 118.44, 119.73, 120.27, 119.07, 124.65, 148.75, 122.84, 153.5, 126.75, 143.46, 271.6, 188.21, 216.43, 142.98, 163.12, 154.55, 138.33, 129.28, 139.64, 239.11, 223.5, 149.98, 131.52, 131.75, 129.53, 159.68, 168.76, 0]
    line [9.79, 69.93, 98.62, 100.37, 135.86, 152.7, 131.9, 155.28, 145.19, 139.4, 126.52, 128.25, 114.87, 116.14, 116.69, 115.49, 121.2, 145.34, 119.48, 149.92, 123.19, 140.24, 268.14, 184.68, 212.97, 140.12, 155.71, 151.01, 134.63, 125.66, 136.03, 235.53, 219.97, 146.31, 127.9, 127.35, 125.96, 156.14, 166.13, 0]
Loading

HEAD

xychart-beta
    title "HEAD CPU"
    x-axis "Elapsed seconds" [1.037, 2.539, 3.541, 4.543, 5.044, 5.544, 6.045, 7.548, 8.549, 10.052, 11.054, 12.056, 13.557, 14.559, 16.06, 17.06, 18.062, 18.563, 19.564, 21.066, 22.067, 23.068, 24.57, 25.571, 27.074, 28.075, 29.577, 30.578, 32.08, 33.08, 34.082, 35.583, 36.585, 38.086, 39.087, 40.589, 41.591, 43.093]
    y-axis "CPU percent" 0 --> 200
    line [9.99, 109.79, 107.75, 149.63, 129.76, 131.96, 127.85, 119.76, 121.91, 69.85, 113.74, 83.85, 144.07, 13.97, 14, 2, 0, 19.96, 93.96, 119.7, 131.94, 105.84, 115.95, 123.93, 47.93, 109.88, 139.67, 47.92, 69.87, 90.02, 9.97, 143.86, 63.89, 4, 1.99, 107.98, 79.96, 109.86]
Loading
xychart-beta
    title "HEAD memory: RSS then PSS"
    x-axis "Elapsed seconds" [0.037, 1.037, 2.539, 3.541, 4.543, 5.044, 5.544, 6.045, 7.548, 8.549, 10.052, 11.054, 12.056, 13.557, 14.559, 16.06, 17.06, 18.062, 18.563, 19.564, 21.066, 22.067, 23.068, 24.57, 25.571, 27.074, 28.075, 29.577, 30.578, 32.08, 33.08, 34.082, 35.583, 36.585, 38.086, 39.087, 40.589, 41.591, 43.093, 44.054]
    y-axis "Memory MiB" 0 --> 500
    line [13.37, 69.88, 111.73, 122.49, 124.73, 150.12, 145.66, 139.99, 139.61, 134.99, 151.74, 158.75, 141.94, 147.38, 137.36, 117.42, 121.29, 120, 125.29, 162.24, 138.21, 147.26, 268.63, 202.88, 204.29, 142.39, 180.25, 142.3, 134.23, 139.23, 132.68, 127.63, 188.9, 147.11, 126.37, 126.43, 159.36, 138.79, 160.76, 0]
    line [10.23, 66.29, 108.23, 118.97, 121.19, 147.14, 142.16, 136.47, 136.44, 131.46, 148.21, 156.07, 138.38, 141.31, 133.8, 113.93, 117.72, 116.31, 121.62, 158.45, 134.6, 143.72, 265.03, 199.41, 200.63, 139.21, 176.89, 137.99, 130.48, 135.73, 129.11, 123.97, 186.07, 143.37, 122.63, 122.68, 155.64, 135.04, 156.89, 0]
Loading

Deterministic fixture · required contract

The fixture exercises 15 routes: 8 are expected to emit rows and 7 intentionally exercise empty, loading, or timeout behavior.

Metric Base HEAD Δ
Run status success success —
Extracted rows / contract 40 / 40 40 / 40 0 (0.00%)
Contract fill 100.00% 100.00% 0.00 pp (0.00%)
Sites with rows 8 / 15 8 / 15 0 (0.00%)
Sites meeting row contract 15 / 15 15 / 15 0 (0.00%)
Unexpected empty sites 0 0 0
Partial-row sites 0 0 0
Site outcomes extracted: 7; HTTP error + rows: 1; empty: 3; timeout + empty: 4 extracted: 7; HTTP error + rows: 1; empty: 3; timeout + empty: 4 —
Observed duration 19.86 s 19.89 s +0.03 s (+0.17%)
Estimated CPU 0.44 s 0.50 s +0.06 s (+13.09%)
Peak PSS 67.40 MiB 67.70 MiB +0.30 MiB (+0.44%)
Peak RSS 71.12 MiB 71.13 MiB +0.02 MiB (+0.02%)
Peak threads 18 19 +1 (+5.56%)
Mismatched sites 0 0 0
Timeout with items 0 0 0

Full HTML, JSON, CSV, logs, and page snapshots: workflow run and full spider-bench-results artifact.

The public-web A/B is informational. The exact HEAD fixture contract runs as a separate required CI check; timing and public-site content deltas remain non-blocking.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Sequential Navigation Soak A/B

✅ HEAD completed the 200-navigation resilience and memory observation.

One browser process, one target, and one CDP session navigate CSDN → SegmentFault → Huaban → example.com repeatedly. This run issued 200 Page.navigate commands per binary.

Common ancestor f702d9a65d → HEAD 829f1989da; benchmark order: head-first; workflow: success.

Session resilience

Metric Base HEAD
Attempted / planned 200 / 200 200 / 200
Direct observable pass 197 / 200 197 / 200
Failures / recovered 3 / 3 3 / 3
Recovery failures 0 0
Lifecycle order violations 0 0
Network order violations 0 0
Wall time 489.8 s 540.8 s

A public-page failure is reported separately from an unrecoverable session. The soak requires all navigation attempts, zero failed recovery, zero lifecycle/network ordering violations, and complete resource evidence.

Process-tree memory

Metric Base HEAD Δ
Boundary samples 200 200 0
Boundary RSS samples 200 200 0
Boundary PSS samples 200 200 0
Periodic peak RSS 229.7 MiB 228.5 MiB -1.2 MiB
Periodic peak PSS 226.4 MiB 226.2 MiB -0.2 MiB
RSS · first 10 avg 160.8 MiB 166.2 MiB +5.3 MiB
RSS · last 10 avg 172.8 MiB 173.3 MiB +0.5 MiB
RSS · last − first window +12.0 MiB +7.1 MiB -4.8 MiB
RSS · warm slope / 100 nav +7.2 MiB +6.5 MiB -0.7 MiB
PSS · first 10 avg 158.2 MiB 163.1 MiB +5.0 MiB
PSS · last 10 avg 169.3 MiB 171.0 MiB +1.7 MiB
PSS · last − first window +11.1 MiB +7.8 MiB -3.3 MiB
PSS · warm slope / 100 nav +6.4 MiB +6.7 MiB +0.3 MiB
Peak file descriptors 62 60 -2
Peak threads 31 29 -2

HEAD memory by 50-navigation quarter

HEAD range Avg RSS Final RSS Peak RSS Avg PSS Final PSS Peak FD
1–50 163.7 MiB 147.9 MiB 206.3 MiB 160.3 MiB 144.3 MiB 52
51–100 165.7 MiB 156.3 MiB 204.7 MiB 162.8 MiB 154.1 MiB 53
101–150 168.1 MiB 157.9 MiB 207.6 MiB 165.3 MiB 153.8 MiB 52
151–200 172.2 MiB 161.0 MiB 206.5 MiB 169.1 MiB 158.9 MiB 53

Raw reports and per-navigation boundary samples: workflow run and full sequential-navigation-soak-results artifact.

Public-site timing and memory are observational. Use the A/B deltas and trend shape as evidence, not as a deterministic performance threshold.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

CI Regression Report

Source CI run · source state at render: in_progress · artifacts: 6/6

Check Status Signal
Release regression ✅ HEAD/base failures 0/0; raw binary +0.002787%
Frontend differential ✅ 1,020/1,020 cases matched; 0 issues
Agent episodes ✅ 8/8 Moli episodes passed; 0 failures
Runtime/CDP contracts ✅ 26 contract cases; 0 failures
CDP smoke ✅ 52/52 groups passed; 621 scenarios
WebMainBench ✅ 545/545 completed; 0 unexpected failures
Release regression — ✅ HEAD/base failures 0/0; raw binary +0.002787%

Package and image size

Metric Base HEAD Delta Delta %
Raw binary 153.30 MiB 153.30 MiB +4.38 KiB +0.002787%
Stripped binary 106.57 MiB 106.57 MiB +4.00 KiB +0.003666%
gzip binary 52.81 MiB 52.81 MiB +1.55 KiB +0.002862%
Rootfs 160.20 MiB 160.21 MiB +10.00 KiB +0.006096%
gzip rootfs 61.86 MiB 61.86 MiB +1.43 KiB +0.002265%

Startup latency and PSS

Case Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta
Serve ready 29.27 ms 27.11 ms −2.15 ms 4.21 MiB 4.73 MiB +524.50 KiB
CDP first page 94.34 ms 48.95 ms −45.40 ms 4.37 MiB 5.44 MiB +1.07 MiB
CDP warm page 20.20 ms 12.00 ms −8.21 ms 50.98 MiB 51.71 MiB +755.50 KiB
CLI about:blank 48.77 ms 38.18 ms −10.60 ms 4.21 MiB 5.47 MiB +1.26 MiB
CLI local JS 42.38 ms 46.11 ms +3.73 ms 4.73 MiB 3.77 MiB −978.00 KiB

Concurrency matrix

Concurrency Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta HEAD failures Unstable B/H
1 45.41 ms 43.10 ms −2.31 ms 444.00 KiB 441.00 KiB −3.00 KiB 0 0/0
5 50.30 ms 46.78 ms −3.52 ms 1.24 MiB 1.29 MiB +48.00 KiB 0 0/0
10 46.90 ms 47.62 ms +0.72 ms 1.24 MiB 1.27 MiB +40.00 KiB 0 0/0
25 45.98 ms 49.63 ms +3.65 ms 3.99 MiB 1.27 MiB −2.71 MiB 0 0/0
100 42.87 ms 48.33 ms +5.46 ms 5.84 MiB 1.28 MiB −4.57 MiB 0 0/0
Frontend differential — ✅ 1,020/1,020 cases matched; 0 issues
Match DOM mismatch Diagnostic mismatch Moli error Reference error Infrastructure error Mismatched frames Duration
1,020 0 0 0 0 0 0 6m 33.91s
Agent episodes · Moli vs Chromium — ✅ 8/8 Moli episodes passed; 0 failures
Fast contract Episodes Passed Assertions Ready p50 Episode p50
Moli 8 8 47/47 29.08 ms 30.21 ms
Chromium 8 8 47/47 301.64 ms 114.47 ms
Operation p50 Chromium Moli Delta Delta %
navigate 58.50 ms 10.44 ms −48.06 ms −82.15%
observe 1.60 ms 1.45 ms −0.16 ms −9.83%
fill 5.74 ms 4.57 ms −1.17 ms −20.33%
click 9.27 ms 5.16 ms −4.11 ms −44.34%
Idle-resource episode Peak RSS Peak PSS Average CPU Peak CPU Peak processes Sampler
Moli 67.02 MiB 64.85 MiB 0.76% 14.03% 1 ✅
Chromium 1322.80 MiB 430.42 MiB 1.17% 54.03% 13 ⚠️ PSS partial
Runtime and CDP session contracts — ✅ 26 contract cases; 0 failures
Suite Cases Failures Median case p50 Median case p95 Median peak PSS p50
Synthetic fetch 13 0 41.55 ms 42.26 ms 1.18 MiB
Long-lived CDP session 13 0 17.91 ms 18.37 ms —
CDP smoke — ✅ 52/52 groups passed; 621 scenarios

Workers: 4 · cumulative group time: 204.39 s · failed groups: 0

Slowest group Scenarios Duration Status
scrollbar-visibility 22 32.63 s ✅
target-lifecycle 24 17.14 s ✅
dom-input 27 13.38 s ✅
multi-page 45 11.79 s ✅
chromium-cdp 56 11.60 s ✅
WebMainBench · 545 pages — ✅ 545/545 completed; 0 unexpected failures
Completed Successful Expected DNS failure Unexpected failures Panics Crashes Timeouts Empty output
545/545 544 1 0 0 0 0 0

Frozen HTML · Linux · --wait done · 45 seconds per page · no retries. Content quality is evaluated separately.

Diagnostics: webmainbench-results — every page's Markdown, stderr, and exit status. Source run and artifacts

All artifact fields are parsed by the trusted default-branch renderer; missing or invalid inputs remain visible as unavailable.

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复核提交 266117486817,未发现本次改动新增的明确阻断问题。

保留 pre 的字面文本,同时把链接目的地址放到代码块外,能兼顾代码复制和目录下载链接;aria-label 只补空链接,不覆盖已有文字,这两个处理方向合理。媒体地址沿现有 writer 输出,新增 URL 过滤也没有放行 javascript/vbscript 一类主动执行地址。

实际将该提交的 moli-html2md 原码编译为 WASI,运行了 13 个独立 DOM 场景,并对父提交做了相同对照:当前提交 13 项断言全部通过,其中 7 项输出相对父提交变化。覆盖空/非空链接标签、表格、块级子节点、pre 中的类型链接和目录、媒体与 picture、危险 URL、换行保真。这是转换器实测,不是完整仓库测试。

@lanyue-llk
lanyue-llk force-pushed the codex/webfetch-markdown branch from 2661174 to 829f198 Compare October 20, 2026 10:43

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR does three things in moli-html2md: an empty <a> gets its aria-label as the link text, <video>/<audio>/<source>/<track> emit their src/poster URLs as links, and anchors inside <pre> are collected and printed as a link list after the closing fence.

Assessment: request changes. The individual mechanisms are small and the tests are deterministic. The problems are the scope, a URL policy that differs between code paths, duplicate link output, and heavy overlap with the open html2md stack #1334-#1336.

PR description vs code

  • The stated problem, String (/types/String) appearing inside a fenced block, does not appear to reproduce in moli-html2md on main (if it came from another conversion path, please name it). raw_node on main already collects only text, so <pre> content was already literal; links inside <pre> were simply dropped. What the PR actually adds is the trailing link list. The fenced part of the new preformatted_* tests already passes on main; only the appended [label](href) lines exercise new behaviour. Please restate the problem as "destinations inside <pre> were dropped".
  • The title says "visible labels", but aria-label is an accessible name, not a visible label.
  • Media URLs are a third feature that the title does not mention.
  • The Browser Eval note says image-01 ("responsive image sources") passed. Nothing in this diff touches img/srcset (main has no srcset handling), so that case does not show anything this PR changed.
  • The body says fixtures cover "inline code". No test covers a link inside inline <code>, and such links are still dropped (inline == true skips EndPreLink).

Overlap and conflicts with the open stack #1334-#1336 (refs/review/pr-1334..1336)

  • Media, duplicated. #1334 adds moli-html2md/src/media.rs. It has safe_url (the same control-stripping, scheme-allowlist logic as this PR's resource_url, plus a data:image/ exception for images), sources() (direct src plus child <source> with dedup), a title-based label(), and Machine::media handling iframe|video|audio. This PR re-implements the same thing more narrowly, as a second private function in machine.rs with different rules: no dedup, hard-coded English labels, separate <source> visits, and posters labelled "Video poster" where #1334 uses an empty alt. Merging both gives two URL-safety policies and two media renderers. One will silently shadow the other's video|audio match arm, or the merge will conflict at the same match position.
  • Accessible-name fallback, duplicated. #1334's content::fallback_text (aria-label, then title, then svg <title>) applies to any element whose subtree has no readable content, including <a>. This PR adds an anchor-only aria-label path through a new Writer::end_link(serial, fallback) parameter and a second last_link_content counter. Both answer "what text does an empty link get" and would conflict in end_link, which #1335 also edits to add flush_pending_text().
  • Link-safety filter. #1334 applies safe_url to <a href> itself. This PR leaves top-level <a href="javascript:..."> unfiltered but filters the same URL inside <pre> and in media elements.
  • raw_node / <pre> traversal. #1335 adds early returns in raw_node for form controls, role=button and script/style. #1336 adds anchor-target emission for pre. Both edit the same hunk where this PR inserts EndPreLink. The conflicts are mechanical, but the ordering matters: a control-skipping early return placed before the a check could change which links get collected.
  • Recommendation: rebase this onto the stack, or split it. Keep only the <pre> link list here, and reuse #1334's media::safe_url and media::sources and its fallback_text instead of adding parallel implementations. If #1334-#1336 are being abandoned, say so explicitly and close them, so the repo does not end up with two competing designs.

Other

  • The moli-html2md/README.md "Supported output" list (around line 77) does not mention media resource links or the after-fence link list.
  • CI: the Spider Bench A/B comment is neutral (184/240 on both sides). I could not get the check rollup (the GitHub API timed out). I also could not compile locally (no linker in this sandbox), so the findings below come from reading the code at head, not from running it.

Verdict: changes requested (posted as a comment because GitHub does not allow requesting changes on your own PR).

Automated review by Claude Code.

Comment thread moli-html2md/src/machine.rs
Comment thread moli-html2md/src/machine.rs
Comment thread moli-html2md/src/machine.rs
Comment thread moli-html2md/src/machine.rs
Comment thread moli-html2md/src/writer.rs
Comment thread moli-html2md/src/machine.rs
@lanyue-llk

Copy link
Copy Markdown
Contributor Author

Superseded by the existing #1334–#1337 stack. That stack already owns accessible fallback text, shared destination safety, media/resource extraction and links inside literal preformatted content, with broader tests and consistent semantics. #1592 has now been rebased directly onto #1337, so no open PR depends on this branch. Closing this duplicate avoids merging a second URL policy and a second media implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant