Before this rev, using t-component on a div (for example) node
would silently ignore the div and replace it by the root node of
the component. A way to improve this was to create an extra div
node and to put the component inside it. However, it raised
questions: what do we do with other attributes set on this tag?
Do we apply them on the div, or on the component? In addition,
some of them only make sense on the component (e.g. props), so we
have to detect them. Whatever we would have decided, it wouldn't
have been obvious from the user point of view, so we chose not to
support it, and we thus now raise an error in this case.
Closes#487.
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
We learn something new every day, and today is no exception. Promise.all
of a pending promise does not actually resolve as fast as possible after
the initial promise is completed, but a small delay after, because it is
put on the macrotask queue or something like that (I assume)
closes#480
It could happen that a component would crash. But then, the __render
code tried to copy the class properties into the vnode, which does not
exist, creating a new error.
So, the solution is to process the classObj only in the successful part
of the render call, which then will not crash, so the normal error
handling will occur.
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).
Owl takes care of not rendering a component that will be unmounted
immediately after, and it works. However, it also should clean
up the newly added fiber.
Before this commit, a condition deemed always true made
the building crash. The happened with TypeScript == 3.7.2
After this commit, the required typescript version has been
changed, as well as the incriminated true condition
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
including:
- add a link to the tutorial in the main readme page
- remove learning page on 'env', move content on reference page
- add dynamic sub components section in component page
- add reference page on props
- split qweb page into engine/language pages
- move t-key information into qweb language page
There was some code to attempt to display the error in the right
pane, whenever it occured in the app early phase.
However, it made it much harder to properly handle all cases. It could
silently swallow some errors (if more than one was done), And it was
not behaving the same way in Firefox and in Chrome.
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
When we have default props, we do not need to allocate a new
props object and copy it. This commit simply modify the props
object in place, which is fine, since the props object is always
a new one any way, generated by the directive.
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.
v1.0alpha
The Alpha release!
Owl is finally getting stable. This relase is all about cleaning Owl
API. We
are pretty happy with the current state, and hopefully, we won't have to
make
any non trivial change for a while.
QWeb
- add an option to setup a translate function
- implement `t-key` with a directive (it now works on `t` tags)
Component
- properly handle errors in `mount` and `render`
- fix: make sure props are validated in all cases
- fix: make sure default props are applied at the proper time
- fix: better error handling with sub components
- imp: simplify constructor API: does not take an `env`
- imp: do not set `props` in root components
- remove `t-keepalive` directive
Context
- update components concurrently, instead of sequentially
Observer
- remove `revNumber` (and rename `deepRevNumber` into `revNumber`)
Router
- fix: preserve pathname in hash mode
Config
- create new config object, with `mode` and `env` keys
Playground
- log git commit hash in console
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