Commit Graph

765 Commits

Author SHA1 Message Date
Samuel Degueldre a93f015795 [FIX] app: allow mounting owl apps in iframe
Previously, attempting to mount an app in an iframe would crash, saying
that the target is not a valid DOM element, this is because instanceof
checks do not work cross-frame as global objects do not have the same
identity in frames as with the main window. This commit fixes that by
making sure the target is an instance of HTMLElement of the
corresponding window, and checks that the corresponding document body
contains it.
2022-08-17 10:05:46 +02:00
Samuel Degueldre 02a187d80b [FIX] compiler: fix falsy values for properties not keeping input empty
Recently, we made it so that when a component is rendered, it always
updates the property values for computed properties. This was done by
wrapping the value in a String or Boolean object. One issue with this is
that wrapping a falsy value in a String doesn't yield an empty string,
but a string containing the value as text (eg new String(undefined) ->
"undefined"), which causes the value to not remain empty as per the
spec. This commit fixes that by adding a fallback to the empty string
for falsy values before converting to a String object.

closes: #1236
2022-08-05 09:50:38 +02:00
Samuel Degueldre 163366997c [FIX] components: fix cause left unset when thrown object is not Error
Previously, when wrapping errors in wrapError, if the error was not an
actual error object, we wouldn't set the cause property on the wrapping
error correctly. The "instanceof Error" check is simply there so that we
can know whether we can add the original errors message to the wrapping
error, but the line that sets the error's cause was mistakenly moved
into that condition.

This commit also fixes the wrapping error's message in the case of
non-Error objects, to avoid having "the following error occurred in
hookname:" with nothing after the colon which is confusing/misleading.
2022-07-22 09:21:19 +02:00
Samuel Degueldre 7786077921 [IMP] *: use a custom error class for all errors thrown by owl
This commit makes all errors thrown in owl use a custom error class. The
main point of this is to always wrap user-code errors that happen during
the owl lifecycle so that they can be treated uniformly in onError by
checking the cause property, and also allows user code to differenciate
owl errors from non-owl errors reliably at runtime.
2022-07-18 15:40:14 +02:00
Aaron Bohy 30bc605c84 [FIX] lifecyle_hooks: correctly wrap errors in async code
Before this commit, wrapping an error occurring in async code
would result in an unhandledpromise exception, because we created
another promise, that would be rejected and that we didn't catch.
2022-07-18 15:40:14 +02:00
Géry Debongnie f8073cb153 [FIX] compiler: better handle update of properties with same value
Before this commit, owl would incorrectly skip patching html properties
when the new value is the same as the value used in the previous render.
However, this is incorrect, since the user may have changed the value by
clicking on a checkbox, or changing some text in an input.

So, to be more correct, owl has to force the update whenever it
encounters a prop.  This is however hard to do without impacting the
main update loop, so we kind of work around the problem by using String
and Boolean instance, instead of primitive values.
2022-07-08 15:58:49 +02:00
Géry Debongnie 382e3e4010 [FIX] compiler: properly handle t-set in t-if with no content
Before this commit, whenever Owl encounter a t-if, it generates an
anchor (a "hole") in the current block being compiled. However, in some
cases, the content of the t-if may not have any content at all, and the
anchor is then useless. Worse, the code generating the anchor generates
an index based on the number of sub blocks, but if there is no content,
the next anchor being created will have the same index, which then may
cause weird bugs.

A possible way to fix this could be to make sure we increment properly
the anchor index, but we could even do better: not having an anchor at
all.
2022-06-29 11:08:14 +02:00
Géry Debongnie b9ba0abf41 [FIX] test: run prettier 2022-06-28 15:26:55 +02:00
Géry Debongnie 4ca37be7f3 [FIX] tests: update wrong snapshot
oups
2022-06-28 15:20:53 +02:00
Géry Debongnie d6667ddf2e [FIX] fix some issues with t-out with falsy values, and with default value 2022-06-28 15:10:11 +02:00
Géry Debongnie 7f580a4e1d [IMP] compiler: add support for binary operators 2022-06-24 15:39:55 +02:00
Géry Debongnie c7459ef87b [IMP] add support for t-call-context directive 2022-06-22 16:15:54 +02:00
Géry Debongnie 5772b4e9e4 [FIX] properly get component reference instead of context
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.
2022-06-22 16:15:54 +02:00
Samuel Degueldre e57e2ee378 [FIX] blockdom: fix crash when class object key has leading spaces
Previously, having a leading or trailing space caused
HTMLElement.classList.add to be called with an empty string (because we
are splitting on whitespace), which is not allowed and caused a crash.
This commit fixes that by trimming the keys of the class object in the
same way that we already do it for class strings.
2022-06-22 15:48:45 +02:00
Aaron Bohy c16d7d52b1 [FIX] compiler: escape backticks in attributes
Before this commit, the generated code crashed if an attribute in
the template contained backticks. The compiler output something
like

```js
   let block1 = createBlock(`<div foo="`bar`"/>`);
```

The backticks are now properly escaped.
2022-06-22 10:22:31 +02:00
Géry Debongnie 9c4c3e3b83 [IMP] validation: add support for value types
This commit add supports for value types in prop validation. To describe
a value V type, one has to simply write {value: V}.

Note that this commit also improves the validation typing.

closes #1198
closes #910
2022-06-15 08:56:44 +02:00
Géry Debongnie 55ac43c1db [IMP] app: add fast path for when component has no prop 2022-06-13 09:51:31 +02:00
Géry Debongnie 0e6059467f [REF] move component function to app, improve some code 2022-06-13 09:51:31 +02:00
Géry Debongnie 51538c2fea [IMP] compiler: remove useless ; in compiled output 2022-06-13 09:51:31 +02:00
Géry Debongnie 385e118e58 [FIX] compiler: add support for #{...} in string interpolation 2022-06-08 10:54:30 +02:00
Géry Debongnie a3111eb9ca [FIX] t-out: allow expressions evaluating as number 2022-06-07 13:23:29 +02:00
Géry Debongnie 1fc88f626f [IMP] slots: add support for t-props on slots props 2022-06-07 09:30:45 +02:00
Géry Debongnie 5d5a530505 [FIX] component: props values are own property of props object 2022-06-03 16:41:31 +02:00
Géry Debongnie c7bd0ab85c [FIX] component: fix wrong behaviour when using t-on on t-component
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
2022-06-03 16:12:56 +02:00
Géry Debongnie 31b57cbb40 [FIX] component: fix props comparison code
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.
2022-06-03 15:51:58 +02:00
Géry Debongnie 31fce0926c [FIX] event: no crash when using t-on + modifier on slots/components
closes #1185
2022-06-01 09:58:49 +02:00
Géry Debongnie a7daef380a [REF] runtime: rename handler.ts -> event_handling.ts 2022-05-31 14:00:01 +02:00
Géry Debongnie 22a79cdedd [REF] reorganize file structure
in order to separate compiler/ and runtime/ code
2022-05-31 14:00:01 +02:00
Géry Debongnie b10a700381 [REF] add static App.registerTemplate and update Portal to use it
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.
2022-05-31 14:00:01 +02:00
Géry Debongnie 2b4d8874c7 [REF] simplify template definition 2022-05-31 14:00:01 +02:00
Géry Debongnie 98b58b505b [IMP] app: add setting to warn if no static props object
This can be helpful to track components that miss a static prop
description.

closes #1191
2022-05-24 13:52:42 +02:00
Géry Debongnie 586033fd95 [FIX] app: validate props for root component in dev mode
Before this commit, only sub components were validated.
2022-05-24 13:52:42 +02:00
Géry Debongnie 4779707923 [IMP] component: rewrite props validation code
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
2022-05-24 13:52:42 +02:00
Samuel Degueldre d917af4614 [IMP] compiler: add better support for "in" and "new" operators
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.
2022-05-19 10:08:48 +02:00
Samuel Degueldre 4c77132ae2 [IMP] component: only useState on props that are already reactive
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.
2022-05-18 08:46:27 +02:00
Paul Morelle 32d8b23b9d [IMP] props_validation: have clearer error messages
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.
2022-05-17 09:35:15 +02:00
Lucas Lefèvre 5c71744e19 [IMP] component: display nice error for wrong child component
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
2022-05-06 17:09:30 +02:00
Géry Debongnie d09771b04b [FIX] compiler: fix issue with identifiers with same name
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.
2022-05-04 14:19:42 +02:00
Géry Debongnie 7137130c38 [FIX] portal: allow use of expression to describe portal target
Before this commit, the value of the `t-portal` directive was inserted
in the compiled template without being processed.
2022-05-04 09:07:58 +02:00
Samuel Degueldre 5d9cff0331 [IMP] app: allow duplicate templates iff they are the same
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.
2022-04-27 10:40:19 +02:00
Samuel Degueldre 41f1262eb7 [FIX] concurrency: do not render delayed fibers when cancelled
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.
2022-04-19 12:07:35 +02:00
Géry Debongnie 7d14db7d31 [FIX] component: strict check of deep argument truth value
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
2022-04-11 10:58:44 +02:00
Géry Debongnie 24b1ea7604 [FIX] components: prevent rendering destroyed children in some cases 2022-04-01 15:02:57 +02:00
Géry Debongnie 859748aed9 [FIX] concurrency issue (more robust handling of children per render)
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.
2022-04-01 13:40:24 +02:00
Géry Debongnie fd13277e1d [FIX] component: protect against user code executing in critical section
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!
2022-04-01 13:40:24 +02:00
Géry Debongnie 7fb166bd50 [FIX] component: protect against errors in onWillDestroy 2022-04-01 13:40:24 +02:00
Lucas Perais (lpe) decf42c742 [FIX] compiler, component: dynamic t-slot with scope
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.
2022-03-31 16:15:47 +02:00
Géry Debongnie 989b0d6709 [REF] improve children handling in components/fibers 2022-03-31 08:54:59 +02:00
Géry Debongnie 9b93521da4 [FIX] issue with delayed renders being left pending forever 2022-03-31 08:54:59 +02:00
Lucas Perais (lpe) de240b1ebc [FIX] compiler, components: allow empty slot
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)
2022-03-29 16:24:05 +02:00