A component can now be mounted in different positions: either 'before' (at
the start), 'after' (at the end), or 'attach' (take possession of a target
element)
closes#539
The component Portal is used to teleport the content
in its slot as a child of an element
somewhere else in the DOM, usually 'body'
It is designed to be transparent and is just here to do the teleportation task
OwlEvents (with method `Component.trigger`) are redirected from
any Component instanciated within the Portal (and therefore teleported
somewhere else) to the place it would have been without teleportation
i.e. they are re-triggered onto the Portal root node
Co-authored-by: Aaron Bohy <aab@odoo.com>
closes#184closes#466
It is important to reset the isRendered flag to false to ensure
that other (subsequent) simultaneous calls to render will be
skipped, as the currentFiber is actually no yet (re-)rendered.
Closes#483
Following 2922cee6ea
Previous commit was not correct: used children with a cancelled
fiber (for instance, with a new currentFiber) could be destroyed.
This commit fixes the issue differently, by directly detecting
children that are not used anymore (and not mounted), and destroy
them directly (no need to wait for willStart promise to be resolved
anymore).
This rev. moves the logic of batching the notifications of changes
occurring in the same microtask tick, from the observer, to the
listeners (the context, and the render function of components).
By doing so in render, we ensure that similar renderings are
batched in a single one, wherever they come from (state change,
store change, direct call...).
Whenever a rendering is completed, we need to reset the currentFiber
to null to make sure all subsequent renderings will not be
confused.
However, the way it was done before this commit was wrong in a
specific situation: we resetted the currentFiber to null in the
patch method. The idea was that this method was called every time
the component completes a rendering. But this is not true: it
can happen that a component is unmounted and remounted without
changes. Then the component will be patched, but if there is no
change, it will not call recursively the patched methods of its
children.
So, we need to choose a better place to reset it to null.
closes#454