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
Re-render the component all the time before remounting it, which
seems safer anyway.
In the test, we had to add a nextTick to wait for the changes to
be notified (before, we waited thanks to the additional call to
mount). If we don't do the nextTick, mount is called, and render
is called right after (before the promise returned by mount is
resolved). This scenario doesn't work right now (see #441).
Closes#381
This is a partial revert of commit 7d249d6f09.
The reason is that this changes made it much harder to unit test
components. Before, we could simply instantiate a component
like this:
const my|Comp = new MyComponent(null, props);
and then simply test it. This commit reestablish that possibility.
For an unknown reason, it looks like the way ticks, micro task ticks or other subtle scheduling issues are different on a windows machine (it may be because of other difference, such as a specific version of nodejs).
Anyway, I could not find the cause of the issue, but
simply waiting an extra microtask tick seems to work.
We don't see any usecase for it, it makes the code more complex,
and there were still potential unresolved concurrency issues with
it.
Part of task #295
It now takes two arguments: parent (optional, only for non-root
components) and props (optional). In the case of the root component,
the env is taken from the config (config.defaultEnv). If it doesn't
exists, the default env is created on the fly.
Closes#306
This commit also changes the behaviour of willPatch and patched: they no
longer transfer data from one to the other, because it can be done
cleanly by hooks and a closure.
closes#307
If we want to generate dynamically svg components, it is useful to be
able to define components with a <g> tag as root, and then getting the
correct namespace.
closes#302
With this commit, we can now do this:
const SUBTEMPLATE = xml`<span><t t-esc="state.n"/></span>`
class Parent extends Widget {
static template = xml`<div><t t-call="${SUBTEMPLATE}"/></div>`
state = {n: 42};
}
Big change! This commit introduces an xml function tag to easily define
inline templates.
This is a pretty big change toward single file owl components
Part of #284
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.