It is common in Owl components to have anonymous function as props.
However, since each rendering create a different (but equivalent)
closure, Owl will consider the props different, so will update the child
component, but this is (often) not necessary.
This commit will help reduce the problem by introducing a new `.alike`
prop suffix, that will let Owl know that each version of that specific
prop should be considered the same, so, will be ignored by the props
comparison code.
closes#1360
Previously, refs could get set to null incorrectly, or could stay set
when they shouldn't. This was caused by the fact that singleRefSetter
and multiRefSetters are created on every render, meaning that any render
that did not affect the status of the ref (mounted or not), would
overwrite the previous ref setter, including its closure, causing the
captured `_el` or `count` to be lost. This means that on a subsequent
render that did affect the status of the ref, the singleRefSetter would
consider that it did not set the ref, and so shouldn't unset it, causing
it to incorrectly stay keep the element, while in multiRefSetter, the
opposite problem occured: the count would be 0 on removal, causing it to
believe that it was the first call in the corresponding patch that
affected the ref, when in fact, the closure is already stale, because it
was created from the previous render, and the fresh multiRefSetter from
the latest render may already have been called by an element with that
ref that came earlier in the template.
This commit changes the ref setting strategy to work around the issue of
stale closures: we define a setRef method on ComponentNode that is
always called, this method ignores calls with `null`, meaning that the
refs object on the ComponentNode never reverts to a null value for any
key. Instead, the useRef hook will check whether the element that the
ref points to is still mounted, and return null if not.
Have a t-ref on a DOM node with a t-key.
Change the t-key.
Before this commit, the old block removed its element from the component's refs *after*
the new block had been mounted, meaning that in effect, the resulting
ref at the end of the whole patch was null.
After this commit, we only remove an element from the component's ref if that very same
element was indeed the ref. (otherwise it means someone else has changed the ref.)
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.
Before this commit, the generated code for the component directive was
using the current context as the place to look for static informations
(such as the sub components). However, it is not entirely correct, since
the current context may be different than the current component (which
is easily accessed by using the this variable).
Also, while doing this, we fix some issues in the t-set directive, which
as calling lazy values with the wrong this.
Before this commit, if the effect function would throw, then the cleanup
function would not be properly assigned, which caused additional errors
later, when the cleanup code would try to call it.
closes#1149
This means that unrelated ids (eg the id of a template, variable or key)
not longer share the same incrementing counter, meaning that you no
longer see a variable named "v2" unless another variable "v1" was
generated previously, this is also true for block data.
Before this commit, when defining a getter in the env passed to useSubEnv,
the value was read, losing the definition of the property.
After this commit, declaring a getter in the env works as expected:
the property stays a getter.
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.