-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[vector_graphics_compiler] Fix rgb/rgba color parsing to support modern CSS syntax #10538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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 refactors the color parsing logic for rgb() and rgba() to support modern CSS syntax, including space-separated values, percentage-based values, and the slash separator for the alpha channel. The implementation is consolidated, and the old rgb parsing logic is removed. Comprehensive tests have been added to cover the new parsing capabilities.
The changes are well-structured and the added tests are thorough. I have one suggestion to improve the strictness of the parsing to better align with CSS standards.
| .map((indexedColor) { | ||
| var (index, rawColor) = indexedColor; | ||
| if (rawColor.endsWith('%')) { | ||
| rawColor = rawColor.substring(0, rawColor.length - 1); | ||
| return (parseDouble(rawColor)! * 2.55).round(); | ||
| } | ||
| if (index == 3) { | ||
| // if alpha is not percentage, it means it's a double between 0 and 1 | ||
| final double opacity = parseDouble(rawColor)!; | ||
| if (opacity < 0 || opacity > 1) { | ||
| throw StateError('Invalid "opacity": $opacity'); | ||
| } | ||
| return (opacity * 255).round(); | ||
| } | ||
| // If rgb is not percentage, it means it's an integer between 0 and 255 | ||
| return int.parse(rawColor); | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of the custom parseDouble from numbers.dart is not ideal for parsing color components. This function is designed to strip units like px or em, but according to the CSS specification, color components in rgb() or rgba() functions should not have units. This could lead to incorrect parsing of invalid color strings (e.g., rgb(50px, 0, 0) would be parsed as rgb(50, 0, 0)).
To ensure stricter adherence to the CSS standard, you should use double.parse from dart:core instead, which will correctly throw an error for values with units.
| .map((indexedColor) { | |
| var (index, rawColor) = indexedColor; | |
| if (rawColor.endsWith('%')) { | |
| rawColor = rawColor.substring(0, rawColor.length - 1); | |
| return (parseDouble(rawColor)! * 2.55).round(); | |
| } | |
| if (index == 3) { | |
| // if alpha is not percentage, it means it's a double between 0 and 1 | |
| final double opacity = parseDouble(rawColor)!; | |
| if (opacity < 0 || opacity > 1) { | |
| throw StateError('Invalid "opacity": $opacity'); | |
| } | |
| return (opacity * 255).round(); | |
| } | |
| // If rgb is not percentage, it means it's an integer between 0 and 255 | |
| return int.parse(rawColor); | |
| }) | |
| .map((indexedColor) { | |
| var (index, rawColor) = indexedColor; | |
| if (rawColor.endsWith('%')) { | |
| rawColor = rawColor.substring(0, rawColor.length - 1); | |
| return (double.parse(rawColor) * 2.55).round(); | |
| } | |
| if (index == 3) { | |
| // if alpha is not percentage, it means it's a double between 0 and 1 | |
| final double opacity = double.parse(rawColor); | |
| if (opacity < 0 || opacity > 1) { | |
| throw StateError('Invalid "opacity": $opacity'); | |
| } | |
| return (opacity * 255).round(); | |
| } | |
| // If rgb is not percentage, it means it's an integer between 0 and 255 | |
| return int.parse(rawColor); | |
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parseDouble usage was retained from the existing rbg parsing implementation.
| final List<int> rgba = colorString | ||
| .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) | ||
| .split(',') | ||
| .split(RegExp(r'[,/\s]')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
valid delimiters are: ,, (empty space) and / (used to delimit the opacity)
Thanks for the contribution! Once you've completed the checklist, please mark the PR as ready for review.
Please make sure to follow the linked style guide. |
…rn CSS syntax - Consolidate rgb() and rgba() parsing into single implementation - Add support for space-separated color values - Add support for percentage-based RGB values - Add support for slash (/) separator before alpha channel - Handle both comma and space delimiters - Add comprehensive test coverage for various color formats
057153b to
16bf81a
Compare
|
@stuartmorgan-g Completed the checklist. This is my first PR to any flutter/dart repo. If anything is not exactly correct, please let me know and I'll address. |
This PR solves flutter/flutter#179261
Pre-Review Checklist
[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.mdto add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2 ↩3