Repository navigation
fix(template): correct table-mode detection after closed table elements - #318
Conversation
An expression that is direct content of a table element needs a comment placeholder, otherwise the HTML parser moves it in front of the table. createContents() detected this only right after an opening table tag, and it reset the mode after the first placeholder whenever the signature contained any closing table tag, also one of an element closed earlier. So the second of two expressions in <tbody> after a <thead>, or an expression after </tr> or </td>, was moved out of the table, and the following expressions of the template were not rendered. Carrying the mode over other text could also put a comment placeholder into an attribute value. Table mode is now decided for each expression: after an opening table tag, after a closing cell, row or section tag in the static text before the expression, or when only whitespace or HTML comments separate it from the previous table-mode expression.
|
I very rarely (if ever) use table elements in my projects, so I am open to table fixes if they are correct. Does your change affect the limitation section of the template engine? (https://hybrids.js.org/#/component-model/templates?id=table-family-elements) |
|
Thanks for taking a look! No, the documented limitation stays exactly as it is. The limitation is about additional text in table family elements with expressions: the browser moves it out of the table while parsing. Several expressions are already allowed there (the docs list This PR only changes when table mode applies. On
So the limitation section stays valid as written; the PR makes its "works fine" case hold in more templates (the shapes from #244). If you'd like, I can add a sentence there saying that several expressions per element are fine as long as there is no other text. |
Fixes #317.
createContents()gives an expression a comment placeholder when it is direct content of a table element, so that the HTML parser does not move it in front of the table. The detection had three gaps (details in #317): since ed333a5 (#212) the reset after a placeholder tests the whole signature, so any table element closed earlier ends table mode after the first expression; a placeholder after</tr>,</td>, … is not detected at all; and the mode is carried over any text, so an attribute expression after a cell expression gets<!--…-->in its value. As markers are assigned in placeholder order, a placeholder moved in front of the table also drops every later expression of the template, without an error.This change decides table mode for every placeholder: after an opening table tag (regex unchanged), after a closing cell, row or section tag (not
</table>) in the static text before the placeholder, or when only whitespace or HTML comments separate it from the previous table-mode placeholder. The reset is removed. Common templates like<tbody><tr>…</tr>${rows}</tbody>or<tbody>${rows}${emptyState}</tbody>under a<thead>now work, and so does the template from #244. Reverting the reset to testparts[index]again would fix the first gap only, and would make the third apply regardless of earlier closed elements. Compile time is on par withmain.Regression tests: four cases in the
tableblock oftest/spec/html.js(two expressions in<tbody>after a<thead>, the same separated by a comment, an expression after</td>, an attribute expression after a cell expression). All four fail onmainand pass with the change. Full suite in Chrome Headless and WebKit: 608 of 612 passing without the change, 612 of 612 with it. Lint and prettier clean.Side effect: in a cell with text between expressions, such as
<td>${a} items ${b}</td>(already unsupported per the docs), the second expression now always gets a text placeholder. Rendering is unchanged. With localization, the runtime key of that text is now alwaysitems ${0}instead ofitemsoritems ${0}depending on the rest of the template;hybrids extractgives${0} items ${1}in both cases.