Before to this commit, the .trim modifier did not work correctly. The value
in the model is always trim at each input event but not the visual value
in the input. This difference between the visual and the model value cause
few strange bug.
After reflection, we think that we always want to be in .lazy when we use .trim.
Because we want to trim the final value during the onchange event and not
at each input event. If we do it at each input event, we can't write more then
one word easily.
So this commit change the behavior of the .trim modifier to always be in .lazy
For some reason the code of parseXML was duplicated, despite being
exactly the same except for some whitespace. Move it out into a common
utils file.
closes#1569
Previously, if a t-set-slot was inside a t-component itself inside a
t-set-slot the parser would crash, because the slot is removed from the
template before compiling its content, causing a further check's
assumption to be broken (the t-set-slot remains connected to the
component's xml node)
Firefox will not serialize the xmlns attributes of node inside
XMLDocuments, see https://bugzilla.mozilla.org/show_bug.cgi?id=175946
it will only output an xmlns attribute if the node being serialized has
a non-null namespaceURI.
When compiling templates, we currently use a special attribute,
"block-ns" to keep track of the namespace, but we do not make use of the
namespace to create the elements that will be serialized to the compiled
block string. This causes a difference in behaviour between Chrome and
Firefox: since we end up with an Element with two attributes: the
block-ns attribute and the xmlns attribute. Chrome will serialize both,
but Firefox will only serialize the block-ns because the Element does
not have a namespaceURI.
To fix this issue, we get rid of the block-ns magic attribute
completely, and use xmlns instead. We also use the namespace when
creating intermediate elements that will be used to create the
serialized block string: the namespace is only used to create the
elements but *not* set as an attribute, as this would cause chrome to
serialize it twice, causing a duplicate attribute error when parsing it
further down the line.
When creating the template element for the block at runtime, the xmlns
attribute is used both as the namespace with which to create the
element, and set as an attribute, this doesn't cause issues when
serializing later because the namespaceURI is never serialized as an
attribute when serializing an HTML document[1], so we avoid the
double-serialization in Chrome, and when doing HTML serialization,
Firefox will correctly serialize the attribute.
It's desirable that the xmlns is set as an attribute to allow users to
use owl to render SVG, and then use the HTML serialization of it as a
SVG even outside the context of an HTML document (eg to generate an SVG
file or an SVG data URL).
[1]: https://w3c.github.io/DOM-Parsing/#xml-serialization
Before this commit, the template parser would allow using t-esc on a
component tag (<MyComponent t-esc="expr"/>) but would incorrectly ignore
the component when parsing a t-out: <MyComponent t-out="expr"/> would be
parsed as <t t-out="expr"/>
This commit solves the issue, and also, moves the `t-out` parsing code
next to `t-esc` so they have the same priority relatively to other
directives.
closes#1483
Before this commit, owl parser would ignore the `.number` suffix on
<select> options. I do not see a good reason for that, and it prevents
some legitimate usecases.
closes#1444
Before this commit, the `t-on` directive assumed that the next character
would be a -, and ignored it, so if someone would write `t-onclick` by
mistake, Owl would then add an event handler on the `lick` event,
instead of `click`.
With this commit, we improve the parser to make it stricter and fail if
there is no dash.
closes#1441
Before this commit, the parser would remove all consecutive white spaces
for text nodes. After that, the code generator would call the translate
function with the resulting string, which then is different than what we
would expect.
With this commit, we make sure we apply the translation before removing
the additional whitespace. To do that, we have to move the code
processing the string from the parser into the code generator, which
actually makes sense, as the parser should only collect all useful
information without applying too much logic.
closes#1351
Currently, if a component has a default slot defined with t-set-slot,
and also content that compiles to something (eg, text or even a comment
node), the content takes priority over the t-set-slot. As t-set-slot is
more explicity, it should have priority.
This commit makes all errors thrown in owl use a custom error class. The
main point of this is to always wrap user-code errors that happen during
the owl lifecycle so that they can be treated uniformly in onError by
checking the cause property, and also allows user code to differenciate
owl errors from non-owl errors reliably at runtime.
Before this commit, a t-set-slot that has no content was not even compiled, and thus not passed
to the component for which it has was defined
After this commit, we allow a t-set-slot to have no content (because it can have slot props)
Before this commit, portal was a Component, now is a directive.
This commit also clean some unused code, and fix an issue on the clean
optimization when a portal is found in a condition or a loop.
The problem was that the compiler is based on the assumption that the
multi block received by the parser only occurs in some cases
where the structure of the template require a multi block, and it does
not work when we have random multiblock elsewhere.
We could fix the issue by modifying the code generator code to support
these usecases, or by simply removing these cases in the parser. Since
this seems more efficient, this is the approach taken by this commit.
Note that it was a good opportunity to simplify the parser.
The slot inner working has been reworked. A prop "slots" is now passed
explicitely to the component. It looks like
{ slotName_1: slotInfo_1, ..., slotName_m: slotInfo_m }
with the objects slotInfo_i with mandatory keys "__render", "__ctx",
and optional key "__scope" and possibly others.
Here is how a slotInfo object can be created:
A slotInfo object is normally created by setting in a template something
like
<div>
<t t-set-slot="foo" t-set-scope="scope" param_1="var" param_2="3">
content
<t t-esc="scope.bool"/>
<t t-esc="scope.num"/>
</t>
</div>
and it will be used somewhere like
<div>
<t t-esc="props.slots.foo.param_1"/>
<t t-slot="foo" bool="other_var" num="5">
</div>
In the above example, the function "__render" produces the block dom
element for the content of the t-set-slot.
The context "__ctx" will have a key "scope" with value { bool: ..., num: 5 }
and "__scope" will be set to "scope".
t-out automatically escaped content when it is a string not marked
with the `markup` function
t-out renders the raw content if it is a Block, or if it has been marked
with the `markup` funtion.
t-esc has been kept since it is safe and is optimized to render text nodes.
all t-raw calls are in fact the same as t-out.