Before this commit, using t-on on t-component was not correctly
implemented by owl: when more than one component shared the same
parentelement and have an handler with the same name, the second handler
would override the first (using an internal key). With this commit, we
simply recreate event handler for each instance of a catcher block. Note
that it means that using t-on on components is slightly slower now.
Also, this commit fixes an additional issue that was noticed: the
catcher block would not update its internal handler properly, so it
would not behave properly after being patched.
closes#1199
Before this commit, Owl had a bad interaction with the static
defaultProps code. The props comparison would be done with the new props
object (unmodified) and the current props object (with default props
applied), so the comparison would always return false, which in turn,
causes additional useless renderings.
This commit modifies component node to keep a reference to the
(unmodified) props object so we can compare it as expected.
# v2.0.0-beta-8
Fixes
- portal: allow use of expression to describe portal target
- compiler: fix issue with identifiers with same name
- reactivity: fix memory leak
- app: validate props for root component in dev mode
Improvements
- component: display nice error for wrong child component
- props_validation: have clearer error messages
- component: only useState on props that are already reactive
- compiler: add better support for "in" and "new" operators in templates
- misc: export the validate function
- app: add setting to warn if no static props object
- add static App.registerTemplate and update Portal to use it
- add basic infrastructure to buid owl-runtime without compiler
The goal is to get closer to the possibility of using Owl without the
compiler. This commit removes Portal dependency on the compiler, and
opens the way to register pre-compiled template functions.
The props validation code is actually quite difficult to get right.
Also, it is sometimes useful to be able to validate an object against a
specified schema. Therefore, this commit exports the standalone validate
function as an utility function.
This commit reworks the props validation code in order to extract a
generic validate utility function. The validation should be more robust,
with better error messages, and at the same time, it supports `*` in a
shape object.
And as a bonus, it is now typesafe, and the static props object is now
typed.
closes#1190
Previously, the support for the "in" operator was iffy, and "new" was
not supported at all, "in" would fail when checking if a nested property
was in something else, as the leading space would be stripped, and "new"
would fail because the following space would be stripped.
This commit fixes that by preserving the significant whitespace where
necessary.
Previously, components would automatically call useState on their props,
so that changes deeply within props would automatically cause the
component to be rendered. This can be useful when passing a piece of
state to children or descendants.
One problem with this is that all props implicitly become reactive, even
if the object that was passed as a props was not. The problem with that
being that since the original object is not reactive, any change made by
the parent will not go through the reactivity system and the children
won't be notified of the change, in essence, this reactive object is
essentially useless, while having a real cost: traversing reactive
objects creates more reactive objects, and those objects are all
proxies. This is expensive for basically no benefit, while also making
it more difficult to debug code that involves those objects.
This commit fixes that by only calling useState on objects that are
already reactive, allowing the usecase described in the first paragraph
without the drawbacks described in the second.
The Context api was retired in owl 2.0, but a documentation file was
kept alive. This commit removes it, to prevent confusion in the future.
Thanks zerone40 for the issue
closes#1180
With this commit, props validation error messages will include a more
developer-friendly error message, avoiding the need to investigate in
the Developer Tools why a complex props structure is invalid.
The reactive cache should be a WeakMap from targets to another WeakMap
that associates callbacks to target. The second WeakMap was in fact a
map, and typescript did not complain because Map has compatible typing
with WeakMap. This commit fixes that.
If you declare a child component which is not actually a Component,
the error message is not very friendly and not very helpfull to find
what happens and which child component is wrong.
```
const ChildComponent = "not a component constructor";
class MyComponent extends Component {
static components = { ChildComponent };
}
```
This commit improves the type declaration for those working with Typescript
and adds a runtime check for javascript codebases
Before this commit, there were 2 different ways of generating variable
identifiers. And it was possible to have a situation with two different
variable in a template with the same identifier, which caused a crash.
This commit ensures that we go through a unique helper method, so this
cannot occur anymore. Also, the code is slightly simpler.
Previously, we used an option to allow duplicate templates, if that
option was passed, we would always replace the existing template with
the new template, and if it wasn't, we would always throw an error even
if the template's content was the same.
Allowing to replace a template with a different one is problematic, as
it may or may not have already been compiled, which may cause various
problems. On the other hand, if the template is the same, there is no
point in throwing an error, as we can just silently ignore the second
addition.
Previously, if a fiber was delayed because one of its ancestors was
rendering, and that fiber was not a root fiber, it would be rendered
after all its ancestors had finished rendering even if one of those
ancestor renderings cancelled it.
This commit fixes that by simply checking that a delayed fiber is still
its component node's current fiber before rendering it.
With this commit, we make sure that the `render` method was explicitely
called with the deep === true argument, instead of assuming that it is a
boolean. This prevents errors when some unrelated value is given to the
render method. This could happen in some cases, such as
useBus(someBus, 'someevent', this.render)
In that case, the `useBus` code would simply call the this.render with a
customevent, which would be considered truthy before, and not anymore
# v2.0.0-beta-5
- fix: compiler, components: allow empty slots with default content
- fix: issue with delayed renders being left pending forever
- fix: dynamic t-slot with scope bug
- fix: protect against errors in onWillDestroy
- fix: protect against user code executing in critical sections
- fix: concurrency issue (more robust handling of children per render)
- fix: prevent rendering destroyed children in some cases
Before this commit, the list of all children was managed at the level of
the root fiber, but this could cause issue when subfibers would be
reused. With this commit, we use the childrenMap object that exists on
each fiber instead.
Canceling a fiber may cause user code to be run, which means that some
new renderings could be scheduled, but this could interfere with the
current renderings!
A little typo was preventing a dynamic t-slot with a scope
(`<t t-slot="{{ state.name }}" myScope="someValue" />`)
to work properly.
This commit corrects this.
Before this commit, a t-set-slot that has no content was not even compiled, and thus not passed
to the component for which it has was defined
After this commit, we allow a t-set-slot to have no content (because it can have slot props)
# v2.0.0-beta.4
- fix: useEffect properly handle errors in effect function
- imp: reactivity: add missing support for forEach method
- imp: component: add name property on nodes for debug purposes
- imp: component: emit warning when async hooks take too long
- fix: blockdom: t-att- correcltly sets the value to zero
- fix: reactivity: do not crash when reading reactive frozen objects
- fix: utils: fix calls to batched callback from within the callback
- imp: component: wait for parent rendering to be complete before rendering child
This is a breaking semantic change. With this commit, the UI is frozen
whenever owl is waiting for a parent to change
Also, this allows Owl not to render components that will be removed
later.
Previously, calling the batched function from within the callback being
batched would fail as it would be treated as part of the same batch.
This commit fixes that by scheduling the reset of the "called" flag
before calling the callback. This means that all microtasks that were
already in the microtask queue when a batch is about to run are treated
as part of the batch, and all microtasks that will be added by the
callback are not.
This crash was caused by the fact that Proxies *must* return the value of the
property on the target when that property is non-writeable and
non-configurable. Since the reactivity system always attempts to proxify the
value from the target, this crashes.
This commit fixes that by not proxifying such values. This however means that
from that point on, we have escaped the reactivity system and will not
subscribe to any changes in that object or its children.
In 3536f41f00 we added a fallback when setting a
property to a falsy value so that the property was set to the empty string. The
objective being to not get the string "undefined"/"null"/"false" as property
value. However, using t-att- to set a property to 0 is perfectly reasonable and
in fact quite common.
This commit adds a warning when an async hook
(onWillUpdateProps/onWillStart) takes longer than 3 seconds, as these
hooks block the rendering and patching of the application, it is rarely
desirable and often a sign of a deadlock. This warning will contain the
stack trace of the call to the hook to help in debugging.
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