With QWeb, we can register globally templates (using the xml tag or
the registerTemplate function). However, these templates, once
compiled, can generate sub template compiled functions. Before this
commit, these sub functions were local to a specific instance.
This means that creating a new QWeb instance and rendering a global
parent template would crash, since it was unable to find the actual sub
function.
This commit fixes the issue: the sub functions are now shared
statically, but with a unique ID, so we do not have issues with sub
functions having a same name in different QWeb instance.
closes#701
# v1.0.8
- qweb fix: do not override t-att-class with class attribute in some cases
- component fix: refuse to mount a destroyed component
- hooks type improvement: useRef is now generic, and can capture the type of a component
- qweb fix: t-esc inside t-call using outside t-set
Before this commit, the generated code was incorrect, and crashed,
when there was a t-esc="abc" in a subtemplate, with t-set="abc"
done outside the subtemplate, with syntax <t t-set="abc">value</t>.
With this commit, we can get the type for the target component for a
ref.
By default, if the generic type is not given, the ref will simply use
the base Component type.
There was some code in qweb to make sure that we support setting class
and t-att-class on the same html element:
<div class="some class" t-att-class="{b: true}">...</div>
But the code did not work in the other direction:
<div t-att-class="{b: true}" class="some class">...</div>
With this commit, we just add the missing if statement
closes#664
This could be done by each application, but it does cost only a few
lines of code, and it helps standardizing the Owl ecosystem.
For example, some library (such as o_spreadsheet) needs to mock side
effects, and Odoo also needs to do that, so this prevents duplicated effort.
closes#686
Before this commit, Env was an indexed type, this means that one could
write env.anything, and it would accept it as a valid type. This is
actually quite dangerous, because we lose the typing advantages for all
keys that are properly defined.
For example, if a component is defined as:
class MyComponent extends Component<Props> {
...
}
Then Typescript will let it use anything from the environment, even if
it is wrong. So, most properly typed Typescript applications should use
instead a sub environment:
interface MyAppEnv extends Env {
someKey: someValue
}
Then, the component should be defined this way:
class MyComponent extends Component<Props, MyAppEnv> {
...
}
Before this commit, any typos in the environment accesses would not be
noticed by typescript.
It is possible that a Component is extended dynamically and if this is
the case, the class that extends it can be anonymous, with property
name=''. If this is the case, current implementation interprets the empty
string to be false so the while loop is terminated without further
scanning the super classes.
In this proposal, we allow anonymous class to be scanned until its
Component ancestor. Basically, the anonymous class assumes the name of
it super.
This new t-set-slot directive is meant to replace t-set when we need to
define the content of a sub slot. All new code should use that
directive.
The old t-set directive is still supported for now, but this should be
removed when we publish Owl 2.0.
Unfortunately, we chose to use the directive `t-set` to define sub slot
contents in a template.
The goal was to reuse a directive for a similar use case: defining sub
template is almost the same as defining a slot content.
Obviously, this introduces a name conflict: the inner content of a
component cannot use t-set t-value anymore (nor t-set with a body
value), since they are interpreted as slot names.
We mitigate the issue here by only interpreting as slot content the
`t-set` statement located immediately below the parent component tag
name and with a body content.
However, a real fix need to introduce an additional directive to resolve
the ambiguity.
Have something like
```xml
<div t-name="Parent">
<t t-call="nodeTemplate">
<t t-set="recursive_idx" t-value="1"/>
<t t-set="node" t-value="root"/>
</t>
</div>
<div t-name="nodeTemplate">
<t t-set="recursive_idx" t-value="recursive_idx + 1"/>
<p><t t-esc="node.val"/> <t t-esc="recursive_idx"/></p>
<t t-foreach="node.children or []" t-as="subtree">
<t t-call="nodeTemplate">
<t t-set="node" t-value="subtree"/>
</t>
</t>
</div>
```
Where we want to propagate a recursion index through recursive t-calls
Before this commit, it did not work as we protected the scope in order
to not leak, in the wronf manner. Namely the protected scope only took
firt level prototype properties of the original scope.
After this commit, this case works as we mark the scope as read only
solves #672
Have
```xml
<body t-name="webclient" />
```
and
```js
const comp = new WebClient();
comp.mount(document.body, {position: 'self'});
```
Before this commit, the body that was there before anything had happened
was *replaced* by the new body node created by the WebClient OWL component
After this commit, we ensure that the element body is the same at reference level
Since ee956a197, the rendering is skipped if the currentFiber is
completed. Unfortunately, cancelled fibers remain set in __owl__,
so when a fiber is cancelled, subsequent calls to render are
skipped.
It would be nice to reset __owl__.currentFiber to null when the
fiber is cancelled, but when trying to do so, a lot of tests fail.
Part of issue #622Closes#665
In this commit, we uses the "!" as suffix to designate an event that
should be captured. This is inspired by the Vue source code.
This solves the issue of communicating additional information to the
underlying virtual dom. However, this will most likely disappear when
we rewrite the vdom as a virtual block system.
closes#650
Before this commit, creating a sub component with
t-att-style/t-att-class attributes or with t-on- event handlers would
override the *hook* object rendered by the sub component.
This is an issue for some directives, such as t-ref, which defines
hook functions.
This commit fixes the issue by checking for an override, and wrapping
the hooks in a function that calls each defined hook.
closes#638
Asynchronous rendering is subtle. Before this commit, it was possible
(though not easy) to get into a situation where the Owl rendering
pipeline decremented twice the counter of a fiber that indicates that
its work is complete.
The situation occurs in the `render` method, where we create a fiber,
wait for a micro tick before starting the actual rendering (the goal was
to batch all changes coming from a single call stack). However, in this
microtask tick, it was possible that the fiber was cancelled, and we did
not have a check for that.
In most cases, we just want Component<any, Env>. But since it was so
annoying to have always the type Env, we actually used
Component<any,any> everywhere.
With this commit, the generic types have a default (and their order is
swapped), so we can simply use Component in most cases, and
Component<Props> when we want to type the props.