In some very rare cases (such as the use of the t-foreach directive),
Owl did leak the values in the render context in the global context.
This was due to the fact that the compiled template looked like this:
let _3 = _4 = _5;
instead of
let _3 = _5;
let _4 = _5;
Have a t-call within a t-set-slot of a component.
The called template has a t-component directive.
It should be like:
```xml
<t t-name="Zero">
<Slotted>
<t t-call="someTemplate" />
</Slotted>
</t>
<t t-name="someTemplate">
<SomeComponent />
</t>
```
Before this commit, the parent of SomeComponent was the Zero component
After this commit, the parent of SomeComponent is the Slotted Component as it should be
closes#862
Whenever a top level t-call was made with some non empty body, Owl
complained that a template should not have more than one root node.
The reason was that the compilation context for the body of the t-call
directive was the same as the root compilation context, and it already
had a parentNode set.
To fix the issue, this commit simply use the subContext method to create
a different compilation context, which actually makes sense, because the
body of a t-call is really a different situation. Also, as a bonus, it
slightly improves the code for the t-call directive.
closes#760
Strangely, the _compile method required a CompilationContext whenever it
was compiled as a sub template, but this parent context was actually not
really needed. I guess that it was the case in the past, but this was
changed at some point.
This commit makes another significant change: the xml element is no
longer mandatory. It is actually only required for slots (because the
template is not registered to qweb).
Finally, the interface for the whole method has been changed to use an
option object, which makes more sense with 3 optional paremeters.
This is a rarely (if ever) used feature, but according to our qweb
reference implementation, it is possible to use the
t-call directive on an arbitrary html tag, like this:
<div t-call="my.template"/>
It is then interpreted as:
<div><t t-call="my.template"/></div>
So, with this commit, we make sure that the owl qweb implementation
matches that behaviour.
closes#706
The previous fix (overriding tostring of VDomArray) is actually more
general, and solves the same issue. So, let us simplify the code and
keep the more general solution.
This reverts commit 3bf91afc3f.
The body of a t-call directive may be used to define private variables
to the sub template call.
However, the code that handles t-call worked like this:
- compile sub template if necessary
- then compile body of t-call to extract variables
This means that the variables defined in the t-call body were not yet
processed and available in the context. Because of that, when the call
to t-esc is done, there is not internal qweb var, and the code simply
outputs a scope['varname'], which is in our case a VDOMArray, so it is
displayed as [object object]
What this fix does is changing the way t-esc works: if we are in the
context of a sub template, then it assumes that any outside variable may
or may not be a VDomArray, so it needs to check and eventually convert
it to a string, if necessary.
closes#719
Owl has to manage a lot of interesting situations. One of them is when
a rendering is initiated, which creates a sub component, but then
another rendering starts, which invalidate the previous one, and will
create another sub component. Since the first sub component was not
ever in the DOM, we cannot rely on the vdom patching process to remove
it, so we have to do it manually.
Sadly, this is actually a very tricky situation, since there are other
subtle situations where the code that remove an unmounted widget could
be executed, in particular when the parent component is unmounted, then
remounted, then modified to trigger yet another rendering.
In this commit, we handle this case more carefully by making sure that
the destroyed subcomponent properly configures its pvnode so the patch
process happens as expected.
joint work with the framework team, and in particular LPE for his work on
finding a testcase!
closes#724, #731
Have a t-call nested in a t-foreach nested in a t-foreach
```xml
<t t-name="template">
<t t-foreach="..." t-as="a">
<t t-foreach="..." t-as="b">
<t-call="templateCalled" />
</t>
</t>
</t>
```
Before this commit, the `a` variable was not accessible within the t-call.
That was because the way t-call protected its scope by hiding other protected scope
in this case, the first protected scope for the first `t-foreach` was hidden
After this commit, `a` and `b` are accessible in the t-call, whether the t-call
defines its own variables by `t-set` or not.
Also, as expected from other fixes, there is no leaks of variables defined within a `t-call`
fixes#695
With QWeb, we can register globally templates (using the xml tag or
the registerTemplate function). However, these templates, once
compiled, can generate sub template compiled functions. Before this
commit, these sub functions were local to a specific instance.
This means that creating a new QWeb instance and rendering a global
parent template would crash, since it was unable to find the actual sub
function.
This commit fixes the issue: the sub functions are now shared
statically, but with a unique ID, so we do not have issues with sub
functions having a same name in different QWeb instance.
closes#701
Before this commit, the generated code was incorrect, and crashed,
when there was a t-esc="abc" in a subtemplate, with t-set="abc"
done outside the subtemplate, with syntax <t t-set="abc">value</t>.
In a template, have t-set t-value outside a t-foreach
in the t-foreach, alter that variable by resetting it (as for a incrementation variable)
Before this commit, when printing the variable when the loop had finished
its value was the one set in the first place
After this commit, the value becomes the one altered by the loop iterations
closes#598
Before this commit, owl could crash in some specific situations:
multiple t-calls with sub components, outside a loop. The reason is
that the t-call did not generate a key, so from the point of view of the
children component, it had the same key, even though it was at a
different place in a template.
Also, with this fix, we can fix the playground responsive example.
closes#602
The way keys were handled in QWeb was mostly ok, but a little naive. It
is fine when we deal with a list of dom nodes, since the reconciliation
algorithm need only to be able to differentiate/reconcile nodes in that
list, but it is an issue with components, which needs to globally be
able to find themselves in their parent's children map.
Because of the way this was handled, there were situations were Owl
internal virtual dom would crash, since components wrongly assumed that
they were already rendered in a different place.
To fix this, we generalize the way keys are generated, by concatenating
all sub keys coming from each iteration loops.
closes#584
Since t-call is now a function call, we need to properly handle the
internal key used to find previous components. If a t-call is inside a
t-foreach, then we need to transfer the key to the sub template.
Otherwise, each component in the subtemplate will be associated to the
same key, which means that it will lead to big issues: components are
destroyed and reused...
closes#581
Before this commit, when template was t-call'ed and defined
t-component directive within it, there was a crash because extra.parent was never defined
After this commit, this use case works
While it is not tested, nor documented, the reference QWeb
implementation display the `false` value as "false". So, we have to
adapt the Owl implementation to match that behaviour.
At the same time, this commit uses 'let' instead of 'var' in various places,
to make the compiled code more consistant.
This commit is a significant refactoring of the internal of QWeb. It
simplifies the way variables/scoping and slots interact together. The
main idea is that we use a simple scope object instead of a
context/var/scope object.
This commit also implement the actual correct QWeb semantic for the
t-call directive with a sub body. Before, we simply extracted the
variables from the body and injected them at the top of the sub
template. We now simply compile the body before the sub template.
This is a joint work with Lucas (lpe).
closes#541closes#544closes#545closes#557closes#556
Have a t-call having a t-raw="0"
that call is made to a template of the same form
i.e. itself as a t-call t-raw="0" structure
Before this commit, there was recursion crash
This was because the caller to which a t-raw="0" referred to
was incorrect. The caller here is the node which makes the t-call.
In particular, the caller was always set to last caller of the context
After this commit, there is no crash and this imbrication
of t-call and t-raw="0" is well rendered.
To sum up, we count the recursive calls to t-raw="0" and fetch
the caller in the context accordingly
closes#510
With this rev., when a t-esc is not set on a <t> tag, we create
it inside the node on which it is set, to ensure that the t-esc
directive is always set on <t> tags.
Same applies for t-raw.
Closes#324
Before this commit, QWeb crashed when it had to deal with a t-call with
multiple sub nodes on the same line, and one text node:
<t t-call="SomeTemplate">
<span>hey</span> <span>hey</span>
</t>
This was because we need to compile the content to be able to extract
all possible t-set t-value statements. But doing so means that we had a
multiple root templates, which caused a crash in this case.
Solving this issue is simple: the sub template is compiled with the flag
allowMultipleRoots set to true.
This is a difficult part of owl: we need to be able to reconcile the
vdom generated (this is done with our virtual dom algorithm), but also
to be able to reconcile the proper components.
The issue here is that when we are in a list, with a t-key attribute on all
list nodes, and those list nodes contains sub component, then the
component system used the index of the list, and did not take into
account the key from the parent. The fix is to keep track of the
current key in the context, and uses that as a part of the templateId.