Skip to content

fix: implement CSP-compatible SVG icon rendering using Path mode#3319

Open
Alexzjt wants to merge 3 commits intonextfrom
fix/csp
Open

fix: implement CSP-compatible SVG icon rendering using Path mode#3319
Alexzjt wants to merge 3 commits intonextfrom
fix/csp

Conversation

@Alexzjt
Copy link
Contributor

@Alexzjt Alexzjt commented Feb 9, 2026

👀 PR includes

✨ Feature

  • New feature

Enhance

  • Code style optimization
  • Refactoring
  • Change the UI
  • Improve the performance
  • Type optimization

🐛 Bugfix

🔧 Chore

  • Test case
  • Docs / demos update
  • CI / workflow
  • Release version
  • Other ()

📝 Description

背景 (Background)
在使用严格内容安全策略(CSP img-src 'self',禁用 data: 协议)的环境下,S2 内置的 SVG 图标无法正常显示。
Built-in SVG icons fail to load in strict CSP environments (where data: URI scheme is blocked in img-src).

改动 (Changes)

  1. 重构图标渲染 (Refactor Icon Rendering):

    • Path Mode (Primary): 解析 SVG 的 d 属性,使用 G 引擎的 Path 直接绘制矢量图形。此方式天然兼容 CSP。
      (Parse SVG paths and render directly using G.Path. Fully CSP compliant.)
    • Image Mode (Fallback): 对于复杂 SVG(如含 <text>/<polygon>),回退使用 Blob URL 加载(比 data: 更安全且兼容)。
      (Fallback to Blob URL for complex SVGs, replacing data: URIs.)
  2. 交互优化 (Interaction Improvement):

    • 在 Path 模式下增加透明热区 (HitArea),修复了点击范围过小和 cursor: pointer 样式不生效的问题。
      (Added transparent HitArea Rect to ensure correct click region and cursor style in Path mode.)

测试 (Tests)

  • 新增单元测试,覆盖 Path 模式渲染、回退机制及交互逻辑。覆盖率 > 86%。
    (Added unit tests covering Path mode, fallback logic, and interaction. Coverage > 86%.)

🖼️ Screenshot

Before (Strict CSP) After (Strict CSP)
image image

🔗 Related issue link

🔍 Self-Check before the merge

  • Add or update relevant docs.
  • Add or update relevant demos.
  • Add or update test case.
  • Add or update relevant TypeScript definitions.

@github-actions github-actions bot added the pr(fix) bug fix label Feb 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

你好 @Alexzjt,非常感谢你的贡献.
为了让代码更健壮, 请根据 贡献指南 补充相应单元测试 (文档改动或其他特殊场景除外), 如果有 API 改动, 请修改 相应的文档.
同时请检查 linttest 相关 CI 是否通过, 如果失败, 请点击 [Details] 按钮查看, 并根据日志修复.

Hello, @Alexzjt, Thanks for your contribution. In order to make the code more robust, please add the corresponding unit tests, and update the docs if there are API changes.
At the same time, please check whether the CI related to lint and test passes. If the CI fails, please click [Details] button to check and repair according to the log.

@github-actions github-actions bot added the next 2.0-next 版本的问题 label Feb 9, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Alexzjt, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where built-in SVG icons failed to display in environments with strict Content Security Policies. It introduces a robust dual-mode rendering system for icons: a primary Path mode that directly draws SVG paths for maximum CSP compatibility, and a refined Image mode that leverages Blob URLs as a secure fallback. This ensures that icons render correctly across various security configurations while also improving user interaction by fixing click area and cursor styling.

Highlights

  • CSP Compatibility: Implemented a new "Path mode" for SVG icon rendering that directly parses SVG 'd' attributes and draws them using 'G.Path', making it fully compatible with strict Content Security Policy (CSP) environments.
  • Fallback Mechanism: For complex SVGs not suitable for direct path rendering, a fallback "Image mode" now uses Blob URLs instead of 'data:' URIs, which is a more secure and CSP-friendly approach.
  • Improved Interaction: Added a transparent 'HitArea' rectangle for icons rendered in Path mode to ensure correct click detection and proper application of cursor styles, addressing previous interaction issues.
  • Enhanced Test Coverage: New unit tests have been added to validate the Path mode rendering, the fallback logic, and interaction behaviors, achieving over 86% coverage for the icon component.
Changelog
  • packages/s2-core/tests/unit/common/icons/gui-icon-spec.ts
    • Added comprehensive unit tests for the new CSP-compatible Path mode rendering.
    • Verified correct rendering of built-in SVG icons in Path mode.
    • Confirmed proper application of cursor styles to Path mode icons via a transparent 'HitArea'.
    • Ensured tree icons render without errors in tree mode tables.
    • Validated fill color updates, re-rendering with new names, and position updates in Path mode.
    • Tested visibility toggling for Path mode icons.
  • packages/s2-core/src/common/icons/gui-icon.ts
    • Introduced 'Path' and 'Rect' imports from '@antv/g' for direct SVG path rendering.
    • Implemented 'parseSvgPaths' utility to extract 'viewBox' and 'd' attributes from SVG strings.
    • Added 'PathDataCache' for parsed SVG path data to optimize performance.
    • Refactored 'GuiIcon' to support two rendering modes: Path Mode (prioritized using 'G.Path' objects with a transparent 'Rect' for hit detection) and Image Mode (modified to use Blob URLs instead of 'data:' URIs).
    • Updated 'render', 'reRender', 'updatePosition', 'setImageAttrs', and 'toggleVisibility' methods to conditionally apply logic based on the active rendering mode (Path or Image).
    • Adjusted SVG 'fill' attribute stripping regex for robustness.
Activity
  • The pull request was created by Alexzjt.
  • It includes a feature, refactoring, bugfix (for 🙏 Change SVG icon loading format #3125), and test cases.
  • The author provided detailed background, changes, and testing information in the PR description.
  • Screenshots comparing "Before (Strict CSP)" and "After (Strict CSP)" were provided, visually demonstrating the fix.
  • The PR closes issue 🙏 Change SVG icon loading format #3125.
  • The author has self-checked for adding or updating test cases.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

这个 PR 通过引入 Path 渲染模式,很好地解决了严格 CSP 环境下 SVG 图标的渲染问题,并提供了 Image 模式作为回退,方案考虑得很周全。代码重构清晰,并且增加了全面的单元测试,值得称赞。

我发现了一些可以改进的地方:

  1. setImageAttrs 方法中存在一个 bug,它会错误地给透明的点击热区(hit area)上色,导致其变得可见。
  2. 为了增强类型安全,iconPathShapes 数组的类型定义可以更精确,避免不安全的类型转换。
  3. 代码中有一处不必要的非空断言可以移除,以提升代码的可读性。

详细的修改建议请见具体的 review comments。

@codecov-commenter
Copy link

codecov-commenter commented Feb 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.69%. Comparing base (ecdc9c8) to head (f453aac).
⚠️ Report is 784 commits behind head on next.

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #3319      +/-   ##
==========================================
+ Coverage   75.77%   78.69%   +2.92%     
==========================================
  Files         257      224      -33     
  Lines       11994    12469     +475     
  Branches     2464     2830     +366     
==========================================
+ Hits         9088     9813     +725     
+ Misses       1398      950     -448     
- Partials     1508     1706     +198     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Size Change: +1.74 kB (+0.23%)

Total Size: 742 kB

Filename Size Change
./packages/s2-core/dist/s2-extends.min.js 208 kB +904 B (+0.44%)
./packages/s2-core/dist/s2.min.css 583 B +2 B (+0.34%)
./packages/s2-core/dist/s2.min.js 309 kB +833 B (+0.27%)
ℹ️ View Unchanged
Filename Size
./packages/s2-react-components/dist/s2-react-components.min.css 2.55 kB
./packages/s2-react-components/dist/s2-react-components.min.js 123 kB
./packages/s2-react/dist/s2-react.min.css 1.3 kB
./packages/s2-react/dist/s2-react.min.js 38.5 kB
./packages/s2-vue/dist/s2-vue.min.css 3.8 kB
./packages/s2-vue/dist/s2-vue.min.js 54.2 kB

compressed-size-action

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

你好, @Alexzjt CI 执行失败, 请点击 [Details] 按钮查看, 并根据日志修复。

Hello, @Alexzjt CI run failed, please click the [Details] button for detailed log information and fix it.

@github-actions github-actions bot added the 🚨 test failed 单元测试挂了 label Feb 9, 2026
@Alexzjt
Copy link
Contributor Author

Alexzjt commented Feb 9, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant improvement by implementing CSP-compatible SVG icon rendering. The new 'Path mode' directly renders SVG paths, bypassing data: URI restrictions, with a robust fallback to 'Blob URL' for more complex SVGs. The addition of comprehensive unit tests for the new rendering modes, including interaction and error handling, is commendable. The solution effectively addresses issue #3125, enhancing the library's compatibility in strict CSP environments.

@github-actions github-actions bot added 🚨 test failed 单元测试挂了 and removed 🚨 test failed 单元测试挂了 labels Feb 9, 2026
@github-actions github-actions bot added 🚨 test failed 单元测试挂了 and removed 🚨 test failed 单元测试挂了 labels Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

next 2.0-next 版本的问题 pr(fix) bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🙏 Change SVG icon loading format

2 participants

Comments