Skip to content

fix(extract): respect content-visibility hidden subtrees - #453

Open
ch-z-hc wants to merge 1 commit into
Tencent:mainfrom
ch-z-hc:fix/extract-content-visibility
Open

ch-z-hc wants to merge 1 commit into
Tencent:mainfrom
ch-z-hc:fix/extract-content-visibility

Conversation

@ch-z-hc

@ch-z-hc ch-z-hc commented Oct 14, 2026 •

Copy link
Copy Markdown

Bug

bsk extract includes text and links from subtrees hidden with CSS content-visibility: hidden. Discovery also returns tables and lists inside those subtrees, and explicit extraction accepts them instead of returning extract_target_hidden.

For example, extracting this table currently returns Visible\nHidden text:

<table id="t"><tr><td>Visible
  <div style="content-visibility: hidden">Hidden text</div>
</td></tr></table>

Chrome renders only Visible. The collector already excludes display-none and zero-opacity subtrees, but its cached ancestor check does not handle content visibility.

Fix

Add the missing rule to that existing ancestor check. Preserve rendered content on display types where Chromium ignores the property, and keep offscreen content-visibility: auto content extractable. No protocol, dependencies or page mutations are added.

Verification

  • Final regression tests against unchanged main: 38 passed, 4 failed. With the fix: 42 passed, including all 11 real-Chrome extraction tests.
  • Browser cases cover hidden text, links and containers, descendants trying to restore visibility, offscreen auto content, hidden cells, and ignored inline/contents/table display types.
  • Default extension suite: 2,661 passed, 245 existing opt-in skips. Rechecked at head d87ca6798b647107a3c7bbf79902397e72e90269 with two workers; all 11 real-Chrome extraction tests also passed in a separate opt-in run.
  • Extension TypeScript and production build passed again at the current head. Changed-file Biome, repository Biome with formatting disabled, Stylelint, DSH typecheck, localization tests (64) and VOM tests (82) passed.

The browser suite serializes the production collector into an isolated renderer world; it is not an installed-extension CLI end-to-end run. Other opt-in browser suites and Rust tests were not run. The DSH runtime suite was subsequently checked: 536 passed, 2 failed. An isolated checkout of unchanged base d9a78aed47874459ae1e44523a597e42dd9acf99, using the same dependencies and two workers, has the same 536 passed, 2 failed result. Both failures are the existing runner kill-grace cases (settles after the kill grace when neither exit nor close ever fires and settles killAll and killFor children that never report back); this PR does not change the DSH package. This does not claim the full pnpm lint command passed.

Implemented and tested with assistance from OpenAI Codex. No independent human review is claimed.

@NianJiuZst NianJiuZst left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, approving.

Putting the content-visibility: hidden check in the existing isSubtreeHidden ancestor walk is the right place. It covers text, links, discovery and explicit table/list targets in one spot, and the result is cached per element like the other hidden checks. The tests also cover two cases I'd have asked for: a descendant can't opt back in with content-visibility: visible / visibility: visible, and offscreen content-visibility: auto content stays extractable.

What I checked:

  • Ran src/tools/extract/ with BSK_CLICK_CHROME against Chromium 141: 42/42 pass, including the 3 new real-browser cases.
  • Swapped main's collector.ts back in with the new tests: 4 tests fail (3 real-browser plus the happy-dom hidden case), so the tests catch the bug.
  • Biome is clean on the changed files. CI already runs extract.browser.test.ts in real Chrome, so the display-type exemptions will keep being checked against the browser.

Nit (non-blocking): the display-type regex is hard to read inline. Consider pulling it into a named constant with a short comment or a link to the CSS Containment spec section on which boxes it doesn't apply to, so future edits know where the list comes from.

This branch has not been deployed

No deployments
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.

2 participants