Skip to content

[Validator] Add the HexColor constraint and validator #35626

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

Closed
wants to merge 1 commit into from

Conversation

fancyweb
Copy link
Contributor

@fancyweb fancyweb commented Feb 6, 2020

Q A
Branch? master
Bug fix? no
New feature? yes
Deprecations? no
Tickets -
License MIT
Doc PR TODO

From my experience, having this constraint in the core would be very useful to use it with the ColorType form type.


$value = (string) $value;

if (!preg_match('/^#[0-9a-f]{6}$/i', $value)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

The definition of color is really broad, so I don't think it's fair to only validate a hex color this way (ignoring #FFF definitions). if this class would be called HexColorValidator with a HexColor constraint, it would make a lot more sense to me.

In the current scenarios, I would think "red", "green", "blue" etc would also be valid, or rgb(255, 0, 0) for example.

@norkunas
Copy link
Contributor

norkunas commented Feb 7, 2020

Would be nice to have support for rgb/rgba formats also 🙏

@javiereguiluz
Copy link
Member

I agree with @norkunas. The <input type="color"> only supports the #rrggbb hexadecimal format, so this validator would be enough for it. However, in my opinion this validator should be able to validate any valid CSS color.

In case it's useful, check this Gist: https://gist.github.com/olmokramer/82ccce673f86db7cda5e The comments at the end show the regexp needed to match all CSS color formats (including the CSS 4 colors) and even all named CSS colors.

@nicolas-grekas
Copy link
Member

if we want to accept other formats, it must be optional to me and disabled by default. Otherwise, it means every app will have to check the format to be able to interpret the color. Having only one format simplifies things a lot, especially when it's the only possible format for the input type.

@nicolas-grekas nicolas-grekas added this to the next milestone Feb 7, 2020
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

Supporting other formats would mean this validation could not be used properly with the input type=color field.

@norkunas
Copy link
Contributor

norkunas commented Feb 7, 2020

Not everyone uses form component, so for the apis this could be a diferrent type of input. But I agree that it should be opt in.

@fabpot
Copy link
Member

fabpot commented Feb 7, 2020

I agree that validators are not just for forms

@plozmun
Copy link
Contributor

plozmun commented Feb 7, 2020

Maybe it's better to name it SimpleColor ( or HexColor ) as the definition of W3C

@przemyslaw-bogusz
Copy link
Contributor

Maybe you could add an option to allow only valid lowercase simple color, since it's mentioned in the W3C recommendation? I also opt for changing the name to HexColor.

@fancyweb
Copy link
Contributor Author

Maybe you could add an option to allow only valid lowercase simple color, since it's mentioned in the W3C recommendation

From what I understood, uppercase is authorized: The value sanitization algorithm is as follows: If the value of the element is a valid simple color, then set it to the value of the element in ASCII lowercase; otherwise, set it to the string "#000000".

Let's rename it to HexColor then? My initial goal is clearly to stick to the color input.

@javiereguiluz
Copy link
Member

I don't think it's a good idea to restrict this validator to only check one specific way of defining colors. This would be for example as if LanguageValidator only validated languages without any variant (e.g. validate zh but not zh-Hant).

Moreover, validating all valid CSS colors is a matter of applying a single regexp and we now which regexp to use ... so making this an all-purpose validator doesn't seem impossibly hard.

@przemyslaw-bogusz
Copy link
Contributor

I meant an only-lowercase option, if somebody wanted a more strict validation. Another option, on the other hand, could allow a short version, e.g.#fff - it may not be an official recommendation, but it is still a valid, working CSS color. In general, as Javier pointed out, the purpose would be to create a more versatile constraint, which will make sure, that a given string is not just any string, but it represents a color.

@fancyweb
Copy link
Contributor Author

Moreover, validating all valid CSS colors is a matter of applying a single regexp and we now which regexp to use ... so making this an all-purpose validator doesn't seem impossibly hard.

Supporting CSS colors makes things complicated because of the large variety of formats:

  1. Named colors
  2. transparent keyword
  3. currentcolor Keyword
  4. 3-Digit hex codes
  5. 4-Digit hex codes
  6. 6-Digit hex codes
  7. 8-Digit hex codes
  8. rgb() function
  9. rgba() function
  10. hsl() function
  11. hsla() function
  12. hwb() function
  13. System colors
  14. probably more that I did not found

The linked gist does not take into account all the possibilities.

Moreover, I guess browsers interpret the value as they wish: are there norms for allowed spaces, extra/missing characters, bad values, etc.? I think that validating properly all the possibilities is not easy.

I think that the CSSColor constraint is a different feature than the one I'm proposing.

Could we maybe move this Color constraint in the Form component, as an useful implementation dedicated to the ColorType form type? However, that would prevent the standalone Validator component users to benefit from it.

Or can't we rename it to something very clear like InputTypeColor?

@javiereguiluz
Copy link
Member

@fancyweb yes, you are right that this is not trivial, but let's see if we can implement it:

Named colors

Use this regex or use an in_array()

transparent keyword
currentColor Keyword

These ones are easy.

3-Digit hex codes
4-Digit hex codes
6-Digit hex codes
8-Digit hex codes
rgb() function
rgba() function
hsl() function
hsla() function

Use this regex

hwb() function

I wasn't aware of this one (because is CSS4) ... but it looks very similar to hsl()

System colors

Use this regex:

(ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowTex)

I think it's doable and worth it ... but I won't insist anmore. Now, let's make a decision. Thanks!

@fabpot
Copy link
Member

fabpot commented Feb 15, 2020

Based on the discussion, we should either not merge it if we want a universal validator or merge it with only what the input supports. In that second case, we should make it very clear that this is the only supported use case.

@nicolas-grekas
Copy link
Member

if this class would be called HexColorValidator with a HexColor constraint, it would make a lot more sense to me.

let's take this suggestion from @linaori!

@javiereguiluz
Copy link
Member

javiereguiluz commented Feb 15, 2020

One minor comment: if we call it "HexColorValidator" ... should we validate only 6-Digit hex color (which is the only one used by <input type="color">) ... or all the following variants of "hex colors"?

  • 3-Digit hex codes
  • 4-Digit hex codes
  • 6-Digit hex codes
  • 8-Digit hex codes

I guess we need to support all "hex colors" (because the validator is called HexColorValidator). We may add an html5 option (like we do in Email, etc.) to restrict to only accept 6-Digit colors.

@przemyslaw-bogusz
Copy link
Contributor

I think it would be best, if this was configurable through an option. I guess there are many cases, when forms are not used, but constraints are applied, e.g. to validate JSON in an API endpoint.

@fabpot
Copy link
Member

fabpot commented Feb 16, 2020

The more I read about this one, the more I think that this should not belong to core. Of we really want it, let’s stay focus on the initial use case and name it accordingly to avoid confusion and tons of follow up PRs trying to support more formats.

@fancyweb fancyweb force-pushed the validator-color-constraint branch 2 times, most recently from 382bf2a to 487f73e Compare February 17, 2020 17:36
@fancyweb fancyweb changed the title [Validator] Add the Color constraint and validator [Validator] Add the HexColor constraint and validator Feb 17, 2020
@fancyweb fancyweb force-pushed the validator-color-constraint branch from 487f73e to 22b67cf Compare February 17, 2020 17:36
Copy link
Contributor Author

@fancyweb fancyweb left a comment

Choose a reason for hiding this comment

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

I renamed the constraint to HexColor + created an html5 option.

If the html5 option is true (default is true), then the expected hexadecimal color must be 6 characters long. Otherwise, it can be 3, 4, 6 or 8 characters long.

@nicolas-grekas
Copy link
Member

I'm totally missing the point of all the discussion that happened after the PR was submitted:

to me, we should be driven by actual use cases. Here @fancyweb has a clear one, driven by experience: validating color input as generated by html5 color fields.

We don't need to solve the problem in a more generic way. Opensource dynamics is about listening to users and giving them a platform to solve realworld use cases more efficiently. It is not to over-engineer a solution to fit a supposed generic problem.

With this approach in mind, I'm asking for the PR to get rid of any option and stick to what HTML5-driven use cases need. That'd be immediately helpful.

Later on if, maybe, when, unless, until someone comes with a use case and is willing to contribute it to Symfony, then we will have some concrete food for thoughts. For now, that's not the case and we'd better move on. IMHO

@norkunas
Copy link
Contributor

I'm totally missing the point of all the discussion that happened after the PR was submitted:

to me, we should be driven by actual use cases. Here @fancyweb has a clear one, driven by experience: validating color input as generated by html5 color fields.

We don't need to solve the problem in a more generic way. Opensource dynamics is about listening to users and giving them a platform to solve realworld use cases more efficiently. It is not to over-engineer a solution to fit a supposed generic problem.

With this approach in mind, I'm asking for the PR to get rid of any option and stick to what HTML5-driven use cases need. That'd be immediately helpful.

Later on if, maybe, when, unless, until someone comes with a use case and is willing to contribute it to Symfony, then we will have some concrete food for thoughts. For now, that's not the case and we'd better move on. IMHO

We have an actual use case that we support hex and rgb/rgba formats currently with a custom constraint validator.

@nicolas-grekas
Copy link
Member

@norkunas great, then you might like to contribute the code once we decided what to do here?

@norkunas
Copy link
Contributor

I've used spatie/color package in constraint for quick solution, so it wouldnt fit to the core

@plozmun
Copy link
Contributor

plozmun commented Feb 18, 2020

I've used spatie/color package in constraint for quick solution, so it wouldnt fit to the core

Maybe it could be suggested as egulias/email-validator in EmailValidator

@fancyweb
Copy link
Contributor Author

@fabpot As the project leader I will wait for your decision:

  1. HexColor, no option, one goal: validating input type="color" inputs
  2. HexColor, html5 option, more generic
  3. Close the PR
  4. Another decision

@nicolas-grekas
Copy link
Member

Let's name this Html5Color?

* @see https://www.w3.org/TR/html52/sec-forms.html#color-state-typecolor
*/
public $html5 = true;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: add $errorNames

@fancyweb
Copy link
Contributor Author

@fabpot What's your decision on this one? 🙏

@ro0NL
Copy link
Contributor

ro0NL commented Feb 24, 2020

i dont see much value in a Html5Color constraint, for the validation component. IMHO, that's just a regex constraint which the form type can set by default using its constraints option.

For the validator component a full-featured Color constraint is better IMHO.

@fancyweb
Copy link
Contributor Author

IMHO, that's just a regex constraint which the form type can set by default using its constraints option.

That's a good idea but it doesn't make the constraint reusable at all + if someone overrides the constraints option, the hex color validation is lost without knowing it. That fits my case however. If we create a new dedicated constraint, we can still set it by default on the ColorType.

Why we just don't put this new Color constraint in the Form component? That would make everything easier.

@nicolas-grekas
Copy link
Member

Why we just don't put this new Color constraint in the Form component? That would make everything easier.

I think so, also. Anyone else would object before @fancyweb spends time on it?

@fancyweb
Copy link
Contributor Author

fancyweb commented Apr 1, 2020

Closing here in favor of #36302.

@fancyweb fancyweb closed this Apr 1, 2020
@nicolas-grekas nicolas-grekas modified the milestones: next, 5.1 May 4, 2020
fabpot added a commit that referenced this pull request May 5, 2020
…he input (fancyweb)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[Form] Add the html5 option to ColorType to validate the input

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | no
| License       | MIT
| Doc PR        | TODO

Continuation of #35626.

I'm resubmitting the initial implementation, this time in the Form component.

This `Color` constraint is dedicated to the HTML5 input type="color".

Commits
-------

454b6ff [Form] Add the html5 option to ColorType to validate the input
symfony-splitter pushed a commit to symfony/form that referenced this pull request May 5, 2020
…he input (fancyweb)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[Form] Add the html5 option to ColorType to validate the input

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | no
| License       | MIT
| Doc PR        | TODO

Continuation of symfony/symfony#35626.

I'm resubmitting the initial implementation, this time in the Form component.

This `Color` constraint is dedicated to the HTML5 input type="color".

Commits
-------

454b6ff48b [Form] Add the html5 option to ColorType to validate the input
symfony-splitter pushed a commit to symfony/framework-bundle that referenced this pull request May 5, 2020
…he input (fancyweb)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[Form] Add the html5 option to ColorType to validate the input

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | no
| License       | MIT
| Doc PR        | TODO

Continuation of symfony/symfony#35626.

I'm resubmitting the initial implementation, this time in the Form component.

This `Color` constraint is dedicated to the HTML5 input type="color".

Commits
-------

454b6ff48b [Form] Add the html5 option to ColorType to validate the input
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.