-
-
Notifications
You must be signed in to change notification settings - Fork 408
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
Whitespace handling for <template>
tag
#982
Comments
cp issues/982 pulls/ |
This makes a lot of sense! Sorry if I'm kinda hijacking this for another use case, but it is very much related: when doing DOM-less rendering, it would be super useful to also have something like A simple imaginary example of 3D rendering: <template whitespace="none">
<ThreeJsCanvas>
<Mesh/>
<PerspectiveCamera/>
<PointLight/>
</ThreeJsCanvas>
</template>
This gets even worse when doing more dynamic and complex things with e.g. Note that this is equally true for classic hbs files as well as |
I was also thinking if we should at least support something like this for the Chinese (etc) use case:
But it further eats into the "is it still HTML" budget... plus I am not sure what would be the rationalization for this to have no spaces at all. Perhaps |
Also pointing out that if we were to do this, it would have to be a feature in the wire-format compiler, not a feature of content-tag, since you can only do it when you have parsed (knowing what's html text content, etc). Just stripping leading indentation, on the other hand, can be done in content-tag. |
#779 does not specify the whitespace handling semantics for
<template>
tag, as a result the current implementation leaves all the whitespace intact as they appear in the source code. This causes several refactoring hazards:.hbs
the indentation level likely will change, since<template>
is typically nested inside a class, and even for template-only component, the content is customarily indented after the opening<template>
tagIt appears that there are broad consensus that this is a problem, and at a minimum, we need to strip the leading indentation.
However, I would like to go a step further, and consider taking the opportunity and collapsing whitespaces by default.
The reason we care about preserving whitespace is for HTML compatibility. The guiding principle for Ember template is that "things that look like HTML should behave like HTML", however, I am not sure if in this particular case it is worth it. Generally, the browser collapses whitespace so it rarely matters, but in the cases where it does, I think the extra leading indentation from the
<template>
tag will make things too finicky/confusing to rely on whether we strip leading indention or not.Since the
<template>
tag makes it easy to access the JavaScript scope, a more reliable and more readable thing to do, IMO, would be to do this in JavaScript:Since you can always extract any whitespace sensitive text into JavaScript, I think that is sufficient for the
white-space: pre
kind of use cases.So I think we can specify that whitespace
<template>
haswhite-space: normal
semantics by default – or more preciselytemplate("...", { ... })
apply the equivalent ofwhite-space: normal
collapsing to its content by default.In addition to the regular HTML/browser white space collapsing semantics, we have to specify:
template("\n\x20\x20[👈 these 👉]\n\x20\x20")
template("\n\x20\x20[these 👉]\n\x20\x20\x20\x20{{#if this.isAdmin}}\n\x20\x20\x20\x20\x20\x20[👈 and these 👉]\n\x20\x20\x20\x20{{/if}}\n\x20\x20[👈 and these]\n")
In languages that separate words with spaces, such as English:
"Here is an English paragraph that is broken into multiple lines in the source code so that it can be more easily read and edited in a text editor."
Where the chunks joined by spaces.
On the other hand, in languages that do not separate words, such as Chinese:
"這個段落是那麼長,在一行寫不行。最好用三行寫。"
...which is what the CSS spec recommends. However, "historically" browsers unconditionally treated
\n
the same as spaces, which results in this well-known broken behavior:"這個段落是那麼長,\x20在一行寫不行。最好\x20用三行寫。"
This behavior is ultimately left in the spec as browser defined. In my testing today, at least on Safari and Chrome they still have the "historical" broken behavior.
So, my proposal is:
.trim()
the template text for maximal composability, i.e. the template content begins with and end at the first/last none-whitespace character. Invoking a component should not introduce extra whitespace by default, the caller can easily add whitespace (and typically do) on the outside as needed.{{~
,{{~#
etc.\t
is replaced by\x20
,\x20
on the line are trimmed,\x20
.\r\n
becomes\n
\r
becomes\n
\n
are replaced with a single\n
\n
alone for the browser to decide what to doWe should make it possible to overridable locally:
template("...", { whitespace: "collapse" | "preserve" = "collapse")
We could also consider having a way to change the global default, but it gets complicated:
The text was updated successfully, but these errors were encountered: