Webcomponents: [templates] Allow removal of boolean attributes

Created on 10 Nov 2017  ·  22Comments  ·  Source: WICG/webcomponents

<input type="checkbox" checked={{falseVal}}>

Treating falseVal as the string "false" will result in the checkbox being checked. How should developers express "remove or do-not-add the checked attribute".

templates

Most helpful comment

Not for long, if I have my way... https://github.com/whatwg/dom/pull/449

All 22 comments

Options I can recall:

  • Treat particular falsey values magically. One or more of false/undefined/null should, if they're the only value of the attribute, remove/not-add the attribute.
  • Invent special syntax to enable special treatment of the value, eg {{falseVal?}}, otherwise always treat as string.
  • Invent special parser behaviour, such as checked={{falseVal}} vs checked="{{falseVal}}", where only the former would allow the special treatment of the value.
  • Invent special syntax outside the template part, e.g. checked?={{falseVal}}, which is interpreted by the default processor as creating, or not creating, a checked attribute, as according to ToBoolean(falseVal).

@domenic I guess checked?="{{foo}} {{bar}}" would throw?

Right, same as your first bullet.

@domenic do you mean the second bullet?

In the "Treat particular falsey values magically" case, checked="{{foo}} {{bar}}" would treat both foo and bar as strings.

That seems really weird, but OK. In that case we could do the same for checked?="{{foo}} {{bar}}".

@domenic

That seems really weird, but OK.

I'm missing something.

class="{{foo}} {{bar}}" should set class to `${foo} ${bar}`, I don't think any proposal should change that behaviour.

According to "Treat particular falsey values magically", class={{foo}} would remove/not-add class if foo === false.

If foo and bar are booleans, I think class="{{foo}} {{bar}}" should throw, under a proposal that treats booleans specially. Since in such a proposal, class="{{foo}}" is already not setting class to ${foo}.

My mindset was that false is treated specially only if the attribute value is "fully templatized". I guess that doesn't need to be the case.

@jakearchibald are you talking about the default template processor? or in general? just curious.

We are facing the same issue today with our current template engine, and we went for a solution that distinguish between non-interpolation vs interpolated values:

checked={{falseVal}} vs class="{{falseVal}}"

The meaning is different if you're using quotes around it. If the parser can distinguish between them, that can be a clear indication to the processor to remove the attribute when needed.

@caridy we're talking about the default processor. I believe the "Treat particular falsey values magically" and {{falseVal?}} proposals can already be built as a custom processor. The others require parser changes.

The parser can't distinguish. It's stripped out at the tokenizer level, I believe. It doesn't exist in the data model at all. I think a quotes vs. no-quotes approach is a non-starter.

checked?= can also be done without parser changes.

Ah, didn't realise ? was valid in an attribute name.

? throws with setAttribute.

Not for long, if I have my way... https://github.com/whatwg/dom/pull/449

Rather than "boolean" I think this feature should focus on the attribute being absent vs present with the empty string as value. That's the underlying primitive you seem to be getting at.

So, is this waiting for whatwg/dom/pull/449? Is ?= the current consensus?

No, I don't think there's general agreement on anything.

checked="{{ falseVal }}"

Should output:

checked="false"

IMO. (false.toString())

Call me strange, but I prefer to quote all my attributes, so I'm not really fond of using that to determine whether or not to drop the attribute.

Out of the 4 options mentioned so far, my current preference is #4 from Domenic, assuming you are still allowed to quote the value ...

checked?="{{ falseVal }}"

@glen-84 if i'm not mistaken the discussion is on boolean attributes. checked="false" is considered an antipattern and actually resolves to checked=true since boolean attributes are parsed existentially. More on this in the spec notes. Pardon my assumption if you knew this already. I just know that example is a footgun. Hope this helps!

https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes

@snuggs,

Yes, I'm aware of that. I wouldn't actually use "{{ falseVal }}" for boolean attributes, I just think that it makes sense for it to behave that way by default (i.e. when not using ?=).

Was this page helpful?
0 / 5 - 0 ratings