Before this commit, when using a dynamic t-call, it was possible to have
a collision between subcomponent keys. This would cause hard to
understand owl crash, because owl would incorrectly use the same
component instance for two different template location. From
owl point of view, one of these component has to be destroyed and the
other one should be mounted, so a crash would occur.
The fix is to simply properly key sub components.
t-call-context is a feature that's supposed to mask the rendering
context completely, but currently the component remains available
through `this`.
This commit stops treating `this` as a reserved word, so that it's
compiled to a lookup in the rendering context, and adds `this` to the
rendering context when binding the component's rendering function. With
these changes, `this` behaves the same as before when outside a
t-call-context, but when the rendering context is overriden, the
template can no longer access `this`. `this` still represents the
instance of the component inside of the rendering function since it's
needed by owl internally.
A side-effect of this change is that now the rendering context is no
longer the instance of the component by default, but is always an object
with the component in its prototype chain. This was already the case
before in some contexts (eg inside t-foreach, or inside components with
a t-set/t-call anywhere in its template). This can cause issues in rare
cases when a component method was called directly on the rendering
context, as before this change, the method's bound this would be the
component instance (except in a t-foreach, component with a
t-set/t-call, etc), while after this change it is now never the
component instance. When the method only reads on `this` there is no
issue as all the components properties are available on the rendering
contexts, but setting a value on `this` will write on the rendering
context and not the component which is likely a mistake.
While this is a breaking change, simply adding a t-set/t-call to any
template would break components that would be broken by this change,
with this in mind we decided to make this change anyway so that
developers get the error as early as possible in the development cycle
rather than having a seemingly inocuous change break code under them.
Previously, when using a component with a slot within a t-call with
t-call-context, the component would become available again inside the
slot despite the t-call-context. This was caused by the fact that the
capture helper function creates an object with the component as its
prototype which is incorrect. It should just use the previous context as
its prototype.
With the introduction of t-call-context, there is now no guarantee that
the ComponentNode can be found in the rendering context, any attempt to
do so can crash when combined with t-call-context. This commit fixes
that by using `this` instead, which in compiled templates refers to the
component that is being rendered.
The code for props validation assumed that the rendering context was a
component. This was actually true when it was written, but is no longer
true since t-call-context was introduced.
Because of that, it would crash when trying to access the internals of
the component, such as the static components object.
The fix is simple: instead of passing the context to the props
validation code, which can now be anything, we pass the component node,
which is guaranteed to give a reference to the component (and also to
the app). This also make the code slightly simpler.
closes#1261
Have a Component which has a Component node, and a dynamic t-call itself having
a Component node.
Before this commit, both children had the same `key`, (as in the key in parent.children, which registers on the parent all its children).
As a result, the scheduler was endlessly hanging.
After this commit, it works as expected.