ux icon indicating copy to clipboard operation
ux copied to clipboard

[Typed] Add a helper or use <template> to provide values

Open smnandre opened this issue 1 year ago • 2 comments

Today we use a lot of args, and strings must be an array

{{ stimulus_controller('symfony/ux-typed', {
    strings: typedStrings,
    loop: true,
    contentType: 'html'
}) }}

But as we now advice the "raw" attributes it becomes


data-controller="symfony--ux-typed"
data-symfony--ux-typed-loop-value="true"
data-symfony--ux-typed-content-type-value="html"
data-symfony--ux-typed-strings-value="{{ typedStrings|json_encode|e('html_attr') }}"

--

All solutions can be combined i guesss

Solution 1: ux_typed()

Ideally a small helper would avoid all those data-ux-symfony--typed--xxx-values=

<div {{ ux_typed({...}) }} >

</div>

--

Solution 2: <template>

As seen during @weaverryan live, it would be the perfect place to use some

Would be much better DX

Something like that ?

<div data-controller="typed">
  <template data-target="values">
    <p>One sentence</p>
    <p>Another</p>
  </template>
</div> 

--

Solution 3: targets as values

I'm wondering if the best choice, with accessibility in mind, would be simply to use HTML targets as values

<div data-controller="typed">
    <p data-ux-typed-target="value">One sentence</p>
    <p hidden data-ux-typed-target="value">Another</p>
</div> 

smnandre avatar Feb 20 '24 15:02 smnandre

One unfortunate thing about solutions (2) and (3) is that the real name of the controller is symfony--ux-typed... so a target would be <p data-symfony--ux-typed-target="value">... which is kinda ugly still :).

Long-term, I think the ux-typed component should be removed, and instead we provide an @symfony/ux-typed JavaScript package, which has this controller. Users would register this with the name typed. That makes solution(1) impossible. But perhaps a general-purpose helper could be added to help the escaping. For example, the current

data-controller="symfony--ux-typed"
data-symfony--ux-typed-loop-value="true"
data-symfony--ux-typed-content-type-value="html"
data-symfony--ux-typed-strings-value="{{ typedStrings|json_encode|e('html_attr') }}"

Could become something like this:


data-controller="typed"
data-typed-loop-value="true"
data-typed-content-type-value="html"
data-typed-strings-value="{{ typedStrings|json_encode }}"

Notice I did NOT add the |e('html_attr'). Is that really needed? The code behind html_attr is here - https://github.com/twigphp/Twig/blob/3.x/src/Extension/EscaperExtension.php#L337 - and there is a section on OWASP about it here - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-html-attribute-contexts

The normal HTML escaping transforms things like " and '... so a user can't "break out" of the attribute. I'm always very cautious about security, but what is the XSS vector if the user escapes using the normal vector? Maybe we don't need a solution for making it easier to use html_attr at all? Btw, here is the only test case for the special behavior of html_attr - https://github.com/twigphp/Twig/blob/b46e93c7257fb01b7c77768210997b1e00643b91/tests/Extension/EscaperTest.php#L33-L62

weaverryan avatar Feb 22 '24 17:02 weaverryan

So should we wait a couple of weeks. And décide when we have a better vision on what to do with this package ?

I’ll read the links you posted tonight !

smnandre avatar Feb 22 '24 18:02 smnandre