Skip to content

fix: CSS vars perf, scrollbar styles, SVG image inline, nested line-clamp, iframe pseudos & isolation, Tailwind border (#334 #341 #348 #362 #371 #372 #386)#387

Merged
tinchox5 merged 35 commits intomainfrom
dev
Mar 17, 2026

Conversation

@tinchox5
Copy link
Member

@tinchox5 tinchox5 commented Mar 17, 2026

Summary

This PR bundles several bugfixes and small improvements:

Testing


Note

Medium Risk
Touches core DOM capture/clone/style inlining paths (including iframe, font embedding, and sizing heuristics), so regressions could affect output fidelity across browsers despite added test coverage.

Overview
Improves capture fidelity and performance by changing style snapshotting to ignore CSS custom properties by default, adding excludeStyleProps, and normalizing inline styles to their computed (cascade-resolved) values so stylesheet !important can override authored inline styles.

Fixes multiple rendering edge cases: inlines SVG <image href> resources, preserves custom ::-webkit-scrollbar styling by collecting and injecting scrollbar rules, applies line-clamp to nested descendants via lineClampTree, and isolates the <foreignObject> wrapper with all:initial to prevent iframe CSS cascade bleed.

Adds Safari/WebKit workarounds (configurable safariWarmupAttempts, improved warmup + logging) and introduces bounded FIFO caches via EvictingMap to avoid unbounded memory growth. Also includes targeted fixes for Tailwind border: 0 solid normalization, root/body sizing using scrollHeight, relative background URL resolution, Firefox checkbox/radio replacements, and expanded unit test coverage plus minor docs/demo updates.

Written by Cursor Bugbot for commit b49323d. This will update automatically on new commits. Configure here.

tinchox5 added 30 commits March 10, 2026 12:32
…horthand for url() when background-image is empty. Closes #343
…lementation for consistent rendering and improved styling. Closes #290
…adioReplacement functions for better accuracy and consistency. Closes #321. See #378
…ylesheets correctly override inline styles in clones. Fixes #328.
…asuring scroll dimensions and using a temporary container for accurate height and width calculations
…dress WebKit Bug #219770, enhancing capture reliability
…image decoding for improved capture performance
…t from cache module for improved code organization
… support margin collapsing and enhance layout stability
…uding exporters, utils, and modules to improve overall code reliability
…bleshooting, enhancing error visibility during capture processes
…functions into a loop for improved maintainability
…s in Safari to enhance style snapshot accuracy. Closes #340
… CSS fetching, enhancing font loading capabilities. Closes #309, closes #370
…s function, verifying correct handling of custom CDN stylesheets. Closes #309
…pplying padding only when necessary based on bounding box transforms. Closes #333
…-elements in cloned styles to prevent double rendering. Closes #359
…d iframe support and consistency across style retrieval. Closes #371
@tinchox5 tinchox5 merged commit 1e5c978 into main Mar 17, 2026
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

// Tags that size to text content; grid/flex blockify them but we should not constrain
// width (causes wrap when font-weight makes text wider than captured width, e.g. "Timestamp demo")
const INLINE_SIZED_TAGS = new Set(['span', 'small', 'p', 'em', 'strong', 'b', 'i', 'u', 's', 'code', 'cite', 'mark', 'sub', 'sup'])
const skipWidth = isInline || INLINE_SIZED_TAGS.has(tagName)
Copy link

Choose a reason for hiding this comment

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

INLINE_SIZED_TAGS includes block-level p tag, skipping width

Medium Severity

The INLINE_SIZED_TAGS set includes 'p', which is a block-level element by default. The skipWidth condition is isInline || INLINE_SIZED_TAGS.has(tagName), meaning width, min-width, and max-width are unconditionally skipped for all <p> elements regardless of their actual display value. Block-level paragraphs normally fill their container width, and stripping width from their style key can cause layout differences in the captured output.

Fix in Cursor Fix in Web

]
for (const p of BORDER_PROPS) delete out[p]
out['border'] = 'none'
}
Copy link

Choose a reason for hiding this comment

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

Border normalization deletes border-radius styling unintentionally

Medium Severity

The border normalization for Tailwind's border: 0 solid sets out['border'] = 'none', which in CSS shorthand resets border-radius-related properties too when the browser expands it. More directly, the BORDER_PROPS list doesn't include border-radius, border-image, or border-collapse/border-spacing, so those remain in the snapshot — but the shorthand border: none can conflict with them during rendering. Also, elements using border-image with zero-width borders (valid CSS for decorative purposes) will lose their border-image since the shorthand override takes precedence.

Fix in Cursor Fix in Web

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