Compare commits

..

1 Commits

Author SHA1 Message Date
Lucas Perais (lpe) 45fa6745dd [FIX] component: fiber, don't render a destroyed component 2022-04-04 16:01:32 +02:00
160 changed files with 5612 additions and 17363 deletions
-47
View File
@@ -1,47 +0,0 @@
{
"env": {
"browser": true,
"node": true,
"es2022": true
},
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"parserOptions": {
"sourceType": "module"
},
"root": true,
"rules": {
"no-restricted-globals": ["error", "event", "self"],
"no-const-assign": ["error"],
"no-debugger": ["error"],
"no-dupe-class-members": ["error"],
"no-dupe-keys": ["error"],
"no-dupe-args": ["error"],
"no-dupe-else-if": ["error"],
"no-unsafe-negation": ["error"],
"no-duplicate-imports": ["error"],
"valid-typeof": ["error"],
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false, "caughtErrors": "all" }],
"no-restricted-syntax": [
"error",
{
"selector": "MemberExpression[object.name='test'][property.name='only']",
"message": "test.only(...) is forbidden",
},
{
"selector": "MemberExpression[object.name='describe'][property.name='only']",
"message": "describe.only(...) is forbidden",
}
],
},
"globals": {
"describe": true,
"expect": true,
"test": true,
"beforeEach": true,
"beforeAll": true,
"afterEach": true,
"afterAll": true,
"jest": true,
},
}
+1 -2
View File
@@ -22,8 +22,7 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm install
- run: npm run test
- run: npm run check-formatting
- run: npm run lint
- run: npm run build
+3
View File
@@ -14,6 +14,9 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
yarn.lock
#ide's
.vscode
.idea
+1 -2
View File
@@ -93,7 +93,6 @@ Are you new to Owl? This is the place to start!
- [Loading Templates](doc/reference/app.md#loading-templates)
- [Mounting a component](doc/reference/app.md#mount-helper)
- [Portal](doc/reference/portal.md)
- [Precompiling templates](doc/reference/precompiling_templates.md)
- [Props](doc/reference/props.md)
- [Props Validation](doc/reference/props.md#props-validation)
- [Reactivity](doc/reference/reactivity.md)
@@ -124,5 +123,5 @@ npm install @odoo/owl
If you want to use a simple `<script>` tag, the last release can be downloaded here:
- [owl](https://github.com/odoo/owl/releases/latest)
- [owl-1.4.10](https://github.com/odoo/owl/releases/tag/v1.4.10)
+5 -10
View File
@@ -174,9 +174,9 @@ class Root extends Component {
```
The template contains a [`t-foreach`](../reference/templates.md#loops) loop to iterate
through the tasks. It can find the `tasks` list from the component, since the rendering
context contains the properties of the component. Note that we use the `id` of each task
as a `t-key`, which is very common. There are two css classes: `task-list` and `task`,
through the tasks. It can find the `tasks` list from the component, since the
component is the rendering context. Note that we use the `id` of each task as a
`t-key`, which is very common. There are two css classes: `task-list` and `task`,
that we will use in the next section.
Finally, notice the use of the `t-att-checked` attribute:
@@ -502,10 +502,6 @@ deleteTask(task) {
Notice that the `onDelete` prop is defined with a `.bind` suffix: this is a special
suffix that makes sure the function callback is bound to the component.
Notice also that we have two functions named `deleteTask`. The one in the Task
component just delegates the work to the Root component that owns the task list
via the `onDelete` property.
## 10. Using a store
Looking at the code, it is apparent that all the code handling tasks is scattered
@@ -774,11 +770,10 @@ For reference, here is the final code:
<meta charset="UTF-8" />
<title>OWL Todo App</title>
<link rel="stylesheet" href="app.css" />
</head>
<body>
<script src="owl.js"></script>
<script src="app.js"></script>
</body>
</head>
<body></body>
</html>
```
-1
View File
@@ -45,5 +45,4 @@ Utility/helpers:
- [`loadFile`](reference/utils.md#loadfile): an helper to load a file from the server
- [`markup`](reference/templates.md#outputting-data): utility function to define strings that represent html (should not be escaped)
- [`status`](reference/component.md#status-helper): utility function to get the status of a component (new, mounted or destroyed)
- [`validate`](reference/utils.md#validate): validates if an object satisfies a specified schema
- [`whenReady`](reference/utils.md#whenready): utility function to execute code when DOM is ready
-2
View File
@@ -61,8 +61,6 @@ The `config` object is an object with some of the following keys:
templates (see [translations](translations.md))
- **`templates (string | xml document)`**: all the templates that will be used by
the components created by the application.
- **`warnIfNoStaticProps (boolean, default=false)`**: if true, Owl will log a warning
whenever it encounters a component that does not provide a [static props description](props.md#props-validation).
## `mount` helper
+1 -2
View File
@@ -76,8 +76,7 @@ The `Component` class has a very small API.
By default, the render initiated by this method will stop at each child
component if their props are (shallow) equal. To force a render to update
all child components, one can use the optional `deep` argument. Note that the
value of the `deep` argument needs to be a boolean, not a truthy value.
all child components, one can use the optional `deep` argument.
## Static Properties
+105
View File
@@ -0,0 +1,105 @@
# 🦉 Context 🦉
## Content
- [Overview](#overview)
- [Example](#example)
- [Reference](#reference)
- [`Context`](#context)
- [`useContext`](#usecontext)
## Overview
The `Context` object provides a way to share data between an arbitrary number
of components. Usually, data is passed from a parent to its children component,
but when we have to deal with some mostly global information, this can be
annoying, since each component will need to pass the information to each children,
even though some or most of them will not use the information.
With a `Context` object, each component can subscribe (with the `useContext` hook)
to its state, and will be updated whenever the context state is updated.
## Example
Assume that we have an application with various components which needs to render
differently depending on the size of the device. Here is how we could proceed
to make sure that the information is properly shared. First, let us create a
context, and add it to the environment:
```js
const deviceContext = new Context({ isMobile: true });
App.env.deviceContext = deviceContext;
```
If we want to make it completely responsive, we need to update its value whenever
the size of the screen is updated:
```js
const isMobile = () => window.innerWidth <= 768;
window.addEventListener(
"resize",
owl.utils.debounce(() => {
const state = deviceContext.state;
if (state.isMobile !== isMobile()) {
state.isMobile = !state.isMobile;
}
}, 15)
);
```
Then, each component that want can subscribe and render differently depending on the
fact that we are in a mobile or desktop mode.
```js
class SomeComponent extends Component {
static template = xml`
<div>
<t t-if=device.isMobile>
some simplified user interface
</t>
<t t-else="">
a more advanced user interface
</t>
</div>`;
device = useContext(this.env.deviceContext);
}
```
## Reference
### `Context`
A `Context` object should be created with a state object:
```js
const someContext = new Context({ some: "key" });
```
Its state is now available in the `state` key:
```js
someContext.state.some = "other key";
```
This is the way some global code (such as the responsive code above) should
read and update the context state. However, components should not ever read the
context state directly from the context, they should instead use the `useContext`
hook to properly register themselves to state changes.
Note that the `Context` hook is different from the React version. For example,
there is no concept of provider/consumer. So, the `Context` feature does not
by itself allow the use of a different context state depending on the component
place in the component tree. However, this functionality can be obtained, if
necessary, with the use of sub environment.
### `useContext`
The `useContext` hook is the normal way for a component to register themselve
to context state changes. The `useContext` method returns the context state:
```js
device = useContext(this.env.deviceContext);
```
It is a simple observed state (with an owl `Observer`), which contains the shared
information.
+1 -2
View File
@@ -234,8 +234,7 @@ are defined by a function instead of just the dependencies.
The `useEffect` hook takes two function: the effect function and the dependency
function. The effect function perform some task and return (optionally) a cleanup
function. The dependency function returns a list of dependencies, these dependencies
are passed as parameters in the effect function . If any of these
function. The dependency function returns a list of dependencies. If any of these
dependencies changes, then the current effect will be cleaned up and reexecuted.
Here is an example without any dependencies:
-30
View File
@@ -1,30 +0,0 @@
# 🦉 Precompiling templates 🦉
Owl is designed to be used by the Odoo javascript framework. Since Odoo handles
its assets in its own non standard way, it was decided/assumed that Owl would
compile templates at runtime.
However, in some cases, it is not optimal, or even worse, not possible to do that.
For example, browser extensions do not allow javascript code to create a new
function (using the `new Function(...)` syntax).
Therefore, in these cases, it is required to compile templates ahead of time. It
is possible to do that in Owl, but the tooling is still rough. For now, the
process is the following:
1. write your templates in xml files (with a `t-name` directive to declare the name
of the template)
2. Compile them in a `templates.js` file
3. get the `owl.iife.runtime.js` file (which is a owl build without the compiler)
4. bundle `owl.iife.runtime.js` and `template.js` with your assets (owl needs to
be positioned before the templates)
Here is a more detailed explanation on how to compile xml files into a js file:
1. clone the owl repository locally
2. `npm install` to install all the required tooling
3. `npm run build:runtime` to build the `owl.iife.runtime.js` file
4. `npm run build:compiler` to build the template compiler
5. `npm run compile_templates -- path/to/your/templates` will scan your target
folder, find all xml files, get all templates, compile them, and generate a
`templates.js` file.
-4
View File
@@ -159,7 +159,6 @@ For each key, a `prop` definition is either a boolean, a constructor, a list of
- a boolean: indicate that the props exists, and is mandatory.
- a constructor: this should describe the type, for example: `id: Number` describe
the props `id` as a number
- an object describing a value as type. This is done by using the `value` key. For example, `{value: false}` specifies that the corresponding value should be equal to false.
- a list of constructors. In that case, this means that we allow more than one
type. For example, `id: [Number, String]` means that `id` can be either a string
or a number.
@@ -241,12 +240,9 @@ class ComponentB extends owl.Component {
size: {
validate: e => ["small", "medium", "large"].includes(e)
},
someId: [Number, {value: false}], // either a number or false
};
```
Note: the props validation code is done by using the [validate utility function](utils.md#validate).
## Good Practices
A `props` object is a collection of values that come from the parent. As such,
+64 -328
View File
@@ -2,394 +2,130 @@
## Content
- [Introduction](#introduction)
- [Overview](#overview)
- [`useState`](#usestate)
- [`reactive`](#reactive)
- [`Escape hatches`](#escape-hatches)
- [`Advanced usage`](#advanced-usage)
- [`markRaw`](#markraw)
- [`toRaw`](#toraw)
## Introduction
## Overview
Reactivity is a big topic in javascript frameworks. The goal is to provide a
simple way to manipulate state, in such a way that the interface updates automatically
according to state changes, and to do so in a performant manner.
simple way to manipulate state, in such a way that the interface automatically
update accordingly to state changes. Also, we obviously want this to happen in
a performant way.
To this end, Owl provides a proxy-based reactivity system, based on the `reactive` primitive.
The `reactive` function takes an object as a first argument, and an optional callback as its second
argument, it returns a proxy of the object. This proxy tracks what properties are read
through the proxy, and calls the provided callback whenever one of these properties is changed
through any reactive version of the same object. It does so in depth, by returning reactive versions
of the subobjects when they are read.
To solve this issue, Owl provides two reactivity primitives:
- `reactive`, which returns a proxy to its first argument, and tracks all read/update
operation going through it,
- `useState`: a hook, that internally uses `reactive`, and is linked to its
owner component: any read operation will be tracked (key by key), and any
updates to these tracked values will cause the component to be rerendered.
Most of the time, the `useState` hook is the best solution.
Since version 2.0, Owl applies the fine grained reactivity at the component
level: props are automatically turned into reactive object, so Owl can track
which part of these props are consumed by each component, and is therefore able
to only rerender the impacted components.
## `useState`
While the `reactive` primitive is very powerful, its usage in components follow a very standard pattern:
components want to be rerendered when part of the state which they depend on for rendering changes. To
this end, owl provides a standard hook: `useState`. To put it simply, this hook simply calls reactive
with the provided object, and the current component's render function as its callback. This will cause
it to rerender whenever any part of the state object that has been read by this component is modified.
Here is a simple example of how `useState` can be used:
Let us start by an example of how `useState` could be used:
```js
class Counter extends Component {
static template = xml`
<div t-on-click="() => this.state.value++">
<div t-on-click="increment">
<t t-esc="state.value"/>
</div>`;
setup() {
this.state = useState({ value: 0 });
}
}
```
This component reads `state.value` when it renders, subscribing it to changes to that key. Whenever
the value changes, Owl will update the component. Note that there is nothing special about the
`state` property, you can name your state variables whatever you want, and you can have multiple of
them on the same component if it makes sense to do so. This also allows `useState` to be used in custom
hooks that may require state that is specific to that hook.
### Reactive props
Since version 2.0, Owl renders are no longer "deep" by default: a component is only rerendered by its
parent if its props have changed (using a simple equality test). What if the contents of a props have
changed in a deeper property? If that prop is reactive, owl will rerender the child components that
need to be updated automatically, and only those components, it does so by reobserving reactive
objects passed as props to components. Consider the following example:
```js
class Counter extends Component {
static template = xml`
<div t-on-click="() => props.state.value++">
<t t-esc="props.state.value"/>
</div>`;
}
class Parent extends Component {
static template = xml`
<Counter state="this.state"/>
<button t-on-click="() => this.state.value = 0">Reset counter</button>
<button t-on-click="() => this.state.test++" t-esc="this.state.test"/>`;
setup() {
this.state = useState({ value: 0, test: 1 });
increment() {
this.state.value++;
}
}
```
When clicking on the counter button, only the Counter rerenders, because the Parent has never read
the "value" key in the state. When clicking on the "Reset Counter" button, the same thing happens:
only the Counter component rerenders. What matters is not _where_ the state is updated, but which
parts of the state are updated, and which components depend on them. This is achieved by Owl by
automatically calling `useState` on reactive objects passed as props to a child component.
When clicking on the last button, the parent is rerendered, but the child does not care about the
`test` key: it has not read it. The props that we give it (`this.state`) have also not changed,
as such, the parent updates but the child doesn't.
For most day-to-day operations, `useState` should cover all of your needs. If
you are curious about more advanced use cases and technical details, read on.
### Debugging subscriptions
Owl provides a way to show which reactive objects and keys a component is subscribed to: you can
look at `component.__owl__.subscriptions`. Note that this is on the internal `__owl__` field, and
should not be used in any type of production code as the name of this property or any of its properties
or methods are subject to change at any point, even in stable versions of Owl, and may become available
only in debug mode in the future.
If one were to use a simple state object, Owl would not be aware that the value
was changed and that the component should be rerendered. With the `useState`
hook, `this.state` is now a reactive object, so this component works as expected.
## `reactive`
The `reactive` function is the basic reactivity primitive. It takes an object
or an array as first argument, and optionally, a function as the second argument.
The function is called whenever any tracked value is updated.
The function will be called whenever any tracked value is updated.
```js
const obj = reactive({ a: 1 }, () => console.log("changed"));
obj.a = 2; // does not log anything: the 'a' key has not been read yet
console.log(obj.a); // logs 2 and reads the 'a' key => it is now tracked
obj.a = 3; // logs 'changed' because we updated a tracked value
obj.a = 2; // does not log anything: the 'a' key was not read
console.log(obj.a); // log 2, and reads the 'a' key => it is now tracked
obj.a = 3; // log 'changed' because we updated a tracked value
```
An important property of reactive objects is that they can be reobserved: this
will create an independent proxy that tracks another set of keys:
will create an independant proxy that tracks another set of keys:
```js
const obj1 = reactive({ a: 1, b: 2 }, () => console.log("observer 1"));
const obj2 = reactive(obj1, () => console.log("observer 2"));
console.log(obj1.a); // logs 1, and reads the 'a' key => it is now tracked by observer 1
console.log(obj2.b); // logs 2, and 'b' is now tracked by observer 2
obj2.a = 3; // only logs 'observer1', because observer2 does not track a
obj2.b = 3; // only logs 'observer2', because observer1 does not track b
console.log(obj2.a, obj1.b); // logs 3 and 3, while the object is observed independently, it is still a single object
console.log(obj1.a); // log 1, and reads the 'a' key => it is now tracked by observer 1
console.log(obj1.b); // log 2, and 'b' is now tracked by observer 1
console.log(obj2.b); // log 2, and 'b' is now tracked by observer 1
obj2.a = 3; // log 'observer1', because observer2 does not track a
obj2.b = 3; // log 'observer1' and 'observer2'
```
Because `useState` returns a normal reactive object, it is possible to call `reactive` on the result
of a `useState` to observe changes to that object while outside the context of a component, or to
call `useState` on reactive objects created outside of components. In those cases, one needs to be
careful with regards to the lifetime of those reactive objects, as holding references to these
objects may prevent garbage collection of the component and its data even if Owl has destroyed it.
Obviously, one can use `reactive` on the result of a `useState` if wanted, this
is the proper way to watch for some state changes.
### Subscriptions are ephemereal
## `markRaw`
Subscription to state changes are ephemereal, whenever an observer is notified that a state object
has changed, all of its subscriptions are cleared, meaning that if it still cares about it, it
should read the properties it cares about again. For example:
Marks an object so that it is ignored by the reactivity system. This function returns its argument.
```js
const obj = reactive({ a: 1 }, () => console.log("observer called"));
console.log(obj.a); // logs 1, and reads the 'a' key => it is now tracked by the observer
obj.a = 3; // logs 'observer1' and clears the subscriptions of the observer
obj.a = 4; // doesn't log anything, the key is no longer observed
```
This may seem counter-intuitive, but it makes perfect sense in the context of components:
```js
class DoubleCounter extends Component {
static template = xml`
<t t-esc="state.selected + ': ' + state[state.selected].value"/>
<button t-on-click="() => this.state.count1++">increment count 1</button>
<button t-on-click="() => this.state.count2++">increment count 2</button>
<button t-on-click="changeCounter">Switch counter</button>
`;
setup() {
this.state = useState({ selected: "count1", count1: 0, count2: 0 });
}
changeCounter() {
this.state.selected = this.state.selected === "count1" ? "count2" : "count1";
}
}
```
In this component, if we increment the value of the second counter, the component will not rerender,
which makes sense as rerendering will have no effect, as the second counter is not displayed. If we
toggle the component to display the second counter, we now no longer want the component to rerender
when the value of the first counter changes, and this is what happens: a component only rerenders
when there are changes to pieces of state that have been read during or after the previous render.
If a piece of state has not been read in the last render, we know that its value won't influence the
rendered output, and so we can ignore it.
### reactive `Map` and `Set`
The reactivity system has special support built-in for the standard container types `Map` and `Set`.
They behave like one would expect: reading a key subscribes the observer to that key, adding or
removing an item to them notifies observers that have used any of the iterators on that reactive
object, such as `.entries()` or `.keys()`, likewise with clearing them.
## Escape hatches
Sometimes, it is desirable to bypass the reactivity system. Creating proxies when interacting with
reactive objects is expensive, and while on the whole, the performance benefit that we get by
rerendering only the parts of the interface that need it outweighs that cost, in some cases, we want
to be able to opt out of creating them in the first place. This is the purpose of `markRaw`:
### `markRaw`
Marks an object so that it is ignored by the reactivity system, meaning that if this object is ever
part of a of a reactive object, it will be returned as is, and no keys in that object will be
observed.
```js
const someObject = markRaw({ b: 1 });
const someObject = markRaw(...);
const state = useState({
a: 1,
obj: someObject,
obj: someObject
});
console.log(state.obj.b); // attempt to subscribe to the "b" key in someObject
state.obj.b = 2; // No rerender will occur here
console.log(someObject === state.obj); // true
// here, state.obj === someObject
```
This is useful in some rare cases. One such example would be if you want to use an array of objects
that is potentially large to render a list, but those objects are known to be immutable:
```js
this.items = useState([
{ label: "some text", value: 42 },
// ... 1000 total objects
]);
```
in the template:
```xml
<t t-foreach="items" t-as="item" t-key="item.label" t-esc="item.label + item.value"/>
```
Here, on every render, we go and read one thousand keys from a reactive object, which causes
one thousand reactive objects to be created. If we know that the content of these objects
cannot change, this is wasted work. If instead all of these objects are marked as raw, we avoid
all of this work while keeping the ability to lean on the reactivity to track the presence and
identity of these objects:
```js
this.items = useState([
markRaw({ label: "some text", value: 42 }),
// ... 1000 total objects
]);
```
This is useful in some rare cases. For example, some complex and large object such
that going through the reactivity system may cause a non trivial performance slowdown.
However, use this function with caution: this is an escape hatch from the reactivity
system, and as such, using it may cause subtle and unintended issues! For example:
system, and as such, using it may cause subtle and unintended issues!
## `toRaw`
Given a reactive object, this function returns the underlying, non-reactive,
corresponding object.
```js
// This will cause a rerender
this.items.push(markRaw({ label: "another label", value: 1337 }));
// in setup
const state = useState({ value: 1 });
// THIS WILL NOT CAUSE A RENDER!
this.items[17].value = 3;
// The UI is now desynced from component's state until the next render caused by something else
// later:
const rawState = toRaw(this.state);
rawState.value = 3; // will NOT be picked up by the reactivity system!!!
```
In short: only use `markRaw` if your application is slowing down noticeably and profiling reveals
that a lot of time is spent creating useless reactive objects.
Here again, this is useful in some situations where we want to explicitely bypass
Owl, but using this function means that the responsability of coordinating
state update is given to the user code, instead of Owl. Subtle bugs may arise!
### `toRaw`
While `markRaw` marks an object so that it is never made reactive, `toRaw` takes an object and
returns the underlying non-reactive object. It can be useful in some niche cases. In particular,
because the reactivity system returns a proxy, the returned object does not compare equal to the
original object:
Also, normal (non-reactive objects) will be directly returned by `toRaw`:
```js
const obj = {};
const reactiveObj = reactive(obj);
console.log(obj === reactiveObj); // false
console.log(obj === toRaw(reactiveObj)); // true
const obj = { a: 1 };
console.log(toRaw(obj) === obj); // true
```
It can also be useful during debugging, as unfolding proxies recursively in debuggers can be confusing.
## Advanced usage
The following is a collection of small snippets that leverage the reactivity system in
"non-standard" ways to help you understand its power and where using it might make your code simpler.
### Notification manager
Showing notifications is a pretty common need in web applications, you may want to show a
notification from any other component within the application, and the notifications should stack on
top of one another regardless of which component spawned them, here is how we can leverage the
reactivity to accomplish this:
```js
let notificationId = 1;
const notifications = reactive({});
class NotificationContainer extends Component {
static template = xml`
<t t-foreach="notifications" t-as="notification" t-key="notification_key" t-esc="notification"/>
`;
setup() {
this.notifications = useState(notifications);
}
}
export function addNotification(label) {
const id = notificationId++;
notifications[id] = label;
return () => {
delete notifications[id];
};
}
```
Here, the `notifications` variable is a reactive object. Notice how we didn't give `reactive` a
callback: this is because in this case, all we care about is that adding or removing notifications
in the `addNotification` function goes through the reactivity system. The `NotificationContainer`
component reobserves this object with `useState`, and is updated whenever notifications are
added or removed.
### Store
Centralizing application state is a pretty common want/need in web applications. Because of the way
the reactivity system works, you can treat any reactive object as a store, and if you call `useState`
on it, components automatically observe only the part of the store that they're interested in:
```js
export const store = reactive({
list: [],
add(item) {
this.list.push(item);
},
});
export function useStore() {
return useState(store);
}
```
In any component:
```js
import { useStore } from "./store";
class List extends Component {
static template = xml`
<t t-foreach="store.list" t-as="item" t-key="item" t-esc="item"/>
`;
setup() {
this.store = useStore();
}
}
```
Anywhere in the application:
```js
import { store } from "./store";
// Will cause any instance of the List component in the app to update
store.add("New list item!");
```
Notice how we can make objects with methods into reactive objects, and when these methods are used
to mutate the store contents, it works as expected. And while stores are generally one-off objects,
it is entirely possible to make class instances reactive:
```js
class Store {
list = [];
add(item) {
this.list.push(item);
}
}
// Essentially equivalent to the previous code
export const store = reactive(new Store());
```
Which can be useful to unit test the class separately.
### Local storage synchronization
Sometimes, you want to persist some state accross reloads, you can do this by storing it in the
`localStorage`, but what if you want to update the `localStorage` item every time the state changes,
so that you don't have to manually synchronize the states? Well, you can use the reactivity system
to write a custom hook that will do that for you:
```js
function useStoredState(key, initialState) {
const state = JSON.parse(localStorage.getItem(key)) || initialState;
const store = (obj) => localStorage.setItem(key, JSON.stringify(obj));
const reactiveState = reactive(state, () => store(reactiveState));
store(reactiveState);
return useState(state);
}
class MyComponent extends Component {
setup() {
this.state = useStoredState("MyComponent.state", { value: 1 });
}
}
```
One important thing to notice is that both times we call `store`, we call it with `reactiveState`,
not `state`: we need `store` to read the keys through a reactive object for it to correctly
subscribe to state changes. Notice also that we call `store` the first time by hand, as otherwise it
will not be subscribed to anything, and no amount of change in the object will cause the reactive
callback to be invoked.
-6
View File
@@ -239,12 +239,6 @@ And the child component that includes the slot can provide values like this:
<t t-slot="foo" bool="other_var" num="5">
```
or this:
```xml
<t t-slot="foo" t-props="someObject">
```
In the case of the default slot, you may declare the slot scope directly on the
component itself:
+3 -12
View File
@@ -115,7 +115,7 @@ It is useful to explain the various rules that apply on these expressions:
<div><p t-if="console.log(1)">NOT valid</p></div>
```
2. it can use anything in the rendering context (which typically contains the properties of the component):
2. it can use anything in the rendering context (typically, the component):
```xml
<p t-if="user.birthday === today()">Happy bithday!</p>
@@ -290,11 +290,10 @@ If an expression evaluates to a falsy value, it will not be set at all:
It is sometimes convenient to format an attribute with string interpolation. In
that case, the `t-attf-` directive can be used. It is useful when we need to mix
literal and dynamic elements, such as css classes. The dynamic elements can be
specified with either `{{...}}` or `#{...}`:
literal and dynamic elements, such as css classes.
```xml
<div t-attf-foo="a {{value1}} is #{value2} of {{value3}} ]"/>
<div t-attf-foo="a {{value1}} is {{value2}} of {{value3}} ]"/>
<!-- result if values are set to 1,2 and 3: <div foo="a 0 is 1 of 2 ]"></div> -->
```
@@ -540,14 +539,6 @@ This can be used to define variables scoped to a sub template:
<!-- "var" does not exist here -->
```
Note: by default, the rendering context for a sub template is simply the current
rendering context. However, it may be useful to be able to specify a specific
object as context. This can be done by using the `t-call-context` directive:
```xml
<t t-call="other-template" t-call-context="obj"/>
```
### Dynamic sub templates
The `t-call` directive can also be used to dynamically call a sub template,
-22
View File
@@ -8,7 +8,6 @@ functions are all available in the `owl.utils` namespace.
- [`whenReady`](#whenready): executing code when DOM is ready
- [`loadFile`](#loadfile): loading a file (useful for templates)
- [`EventBus`](#eventbus): a simple EventBus
- [`validate`](#validate): a validation function
## `whenReady`
@@ -57,24 +56,3 @@ bus.addEventListener("event", () => console.log("something happened"));
bus.trigger("event"); // 'something happened' is logged
```
## `validate`
The `validate` function is a function that validates if a given object satisfies a
specified schema. It is actually used by Owl itself to perform
[props validation](props.md#props-validation). For example:
```js
validate(
{ a: "hey" },
{
id: Number,
url: [Boolean, { type: Array, element: Number }],
}
);
// throws an error with the following information:
// - unknown key 'a',
// - 'id' is missing (should be a number),
// - 'url' is missing (should be a boolean or list of numbers),
```
-5711
View File
File diff suppressed because it is too large Load Diff
+10 -13
View File
@@ -1,10 +1,11 @@
{
"name": "@odoo/owl",
"version": "2.0.7",
"version": "2.0.0-beta-4",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js",
"browser": "dist/owl.iife.js",
"module": "dist/owl.es.js",
"types": "dist/types/owl.d.ts",
"types": "dist/types/index.d.ts",
"files": [
"dist"
],
@@ -13,8 +14,6 @@
},
"scripts": {
"build:bundle": "rollup -c --failAfterWarnings",
"build:runtime": "rollup -c --failAfterWarnings runtime",
"build:compiler": "rollup -c --failAfterWarnings compiler",
"build": "npm run build:bundle",
"test": "jest",
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand --watch --testTimeout=5000000",
@@ -25,10 +24,8 @@
"playground:watch": "npm-run-all --parallel playground:serve \"build:* -- --watch\"",
"prettier": "prettier {src/*.ts,src/**/*.ts,tests/*.ts,tests/**/*.ts,doc/*.md,doc/**/*.md} --write",
"check-formatting": "prettier {src/*.ts,src/**/*.ts,tests/*.ts,tests/**/*.ts,doc/*.md,doc/**/*.md} --check",
"lint": "eslint src/**/*.ts tests/**/*.ts",
"publish": "npm run build && npm publish",
"release": "node tools/release.js",
"compile_templates": "node tools/compile_xml.js"
"release": "node tools/release.js"
},
"repository": {
"type": "git",
@@ -43,25 +40,25 @@
"devDependencies": {
"@types/jest": "^27.0.1",
"@types/node": "^14.11.8",
"@typescript-eslint/eslint-plugin": "5.48.1",
"@typescript-eslint/parser": "5.48.1",
"chalk": "^3.0.0",
"cpx": "^1.5.0",
"current-git-branch": "^1.1.0",
"eslint": "8.31.0",
"git-rev-sync": "^3.0.2",
"git-rev-sync": "^1.12.0",
"github-api": "^3.3.0",
"jest": "^27.1.0",
"jest-diff": "^27.3.1",
"jest-environment-jsdom": "^27.1.0",
"live-server": "^1.2.1",
"npm-run-all": "^4.1.5",
"prettier": "2.4.1",
"rollup": "^2.56.3",
"rollup-plugin-dts": "^4.2.2",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.31.1",
"sass": "^1.16.1",
"source-map-support": "^0.5.10",
"ts-jest": "^27.0.5",
"typescript": "4.5.2"
"typescript": "4.5.2",
"uglify-es": "^3.3.9"
},
"jest": {
"testEnvironment": "jsdom",
+23 -4
View File
@@ -1,9 +1,28 @@
# 🦉 OWL Roadmap 🦉
- Current version: 2.X
- Current version: 1.4.10
- Status: stable
Owl is currently stable. No (large) improvements is expected in the near future.
This roadmap is only an attempt at predicting Owl's future. Everything may
change!
### 1.x
- add chrome and firefox devtools,
- fix every bugs,
- improve documentation,
- small backward compatible improvements.
### 2.x (2020? 2021? 2022?)
- stop support for `t-set` directive to define the content of a slot
Maybe:
- reimplement vdom to use *block* system, like Vue 3, which should make Owl
much faster
- refactor `QWeb` to use an intermediate representation (some kind of AST) to
allow additional optimisations.
Note that we intend to keep maintaining owl, and as such, improvements and/or
breaking changes may require a version bump in the future.
+35 -58
View File
@@ -2,18 +2,14 @@ import pkg from "./package.json";
import git from "git-rev-sync";
import typescript from 'rollup-plugin-typescript2';
import { terser } from "rollup-plugin-terser";
import dts from "rollup-plugin-dts";
let input, output;
const IIFE_FILENAME = "dist/owl.iife.js";
const CJS_FILENAME = "dist/owl.cjs.js";
const ES_FILENAME = "dist/owl.es.js";
if (pkg.module !== ES_FILENAME || pkg.main !== CJS_FILENAME) {
throw new Error("package.json has been modified. Build script should be updated accordingly");
}
const name = "owl";
const extend = true;
/**
* Meta data to be added on the __info__ object.
* Used to let external tools know the current owl version.
*/
const outro = `
__info__.version = '${pkg.version}';
__info__.date = '${new Date().toISOString()}';
@@ -21,39 +17,13 @@ __info__.hash = '${git.short()}';
__info__.url = 'https://github.com/odoo/owl';
`;
switch (process.argv[4]) {
case "compiler":
input = "src/compiler/index.ts",
output = [
getConfigForFormat('cjs', 'dist/compiler.js', ''),
]
break;
case "runtime":
input = "src/runtime/index.ts";
output = [
getConfigForFormat('esm', addSuffix(ES_FILENAME, 'runtime'), outro),
getConfigForFormat('cjs', addSuffix(CJS_FILENAME, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(IIFE_FILENAME, 'runtime'), outro),
getConfigForFormat('iife', addSuffix(IIFE_FILENAME, 'runtime'), outro, true),
]
break;
default:
input = "src/index.ts",
output = [
getConfigForFormat('esm', ES_FILENAME, outro),
getConfigForFormat('cjs', CJS_FILENAME, outro),
getConfigForFormat('iife', IIFE_FILENAME, outro),
getConfigForFormat('iife', IIFE_FILENAME, outro, true),
]
}
/**
* Generate from a string depicting a path a new path for the minified version.
* @param {string} pkgFileName file name
*/
function addSuffix(pkgFileName, suffix) {
function generateMinifiedNameFromPkgName(pkgFileName) {
const parts = pkgFileName.split('.');
parts.splice(parts.length - 1, 0, suffix);
parts.splice(parts.length - 1, 0, "min");
return parts.join('.');
}
@@ -63,12 +33,12 @@ function addSuffix(pkgFileName, suffix) {
* @param {string} generatedFileName generated file name
* @param {boolean} minified should it be minified
*/
function getConfigForFormat(format, generatedFileName, outro, minified = false) {
function getConfigForFormat(format, generatedFileName, minified = false) {
return {
file: minified ? addSuffix(generatedFileName, "min") : generatedFileName,
file: minified ? generateMinifiedNameFromPkgName(generatedFileName) : generatedFileName,
format: format,
name: "owl",
extend: true,
name: name,
extend: extend,
outro: outro,
freeze: false,
plugins: minified ? [terser()] : [],
@@ -76,19 +46,26 @@ function getConfigForFormat(format, generatedFileName, outro, minified = false)
};
}
export default [
{
input,
output,
plugins: [
typescript({
useTsconfigDeclarationDir: true
}),
]
},
{
input: "dist/types/index.d.ts",
output: [{ file: "dist/types/owl.d.ts", format: "es" }],
plugins: [dts()],
},
];
export default {
input: "src/index.ts",
output: [
/**
* Read about module formats:
* https://auth0.com/blog/javascript-module-systems-showdown/
* https://medium.com/@kelin2025/so-you-wanna-use-es6-modules-714f48b3a953
*/
getConfigForFormat('esm', pkg.module),
getConfigForFormat('esm', pkg.module, true),
getConfigForFormat('cjs', pkg.main),
getConfigForFormat('cjs', pkg.main, true),
getConfigForFormat('iife', pkg.browser),
getConfigForFormat('iife', pkg.browser, true),
],
plugins: [
typescript({
useTsconfigDeclarationDir: true
}),
]
};
+120
View File
@@ -0,0 +1,120 @@
import { Component, ComponentConstructor } from "../component/component";
import { ComponentNode } from "../component/component_node";
import { MountOptions } from "../component/fibers";
import { Scheduler } from "../component/scheduler";
import { TemplateSet, TemplateSetConfig } from "./template_set";
import { nodeErrorHandlers } from "../component/error_handling";
import { validateTarget } from "../utils";
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
export interface Env {
[key: string]: any;
}
export interface AppConfig<P, E> extends TemplateSetConfig {
props?: P;
env?: E;
test?: boolean;
}
let hasBeenLogged = false;
export const DEV_MSG = () => {
const hash = (window as any).owl ? (window as any).owl.__info__.hash : "master";
return `Owl is running in 'dev' mode.
This is not suitable for production use.
See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;
};
export class App<
T extends abstract new (...args: any) => any = any,
P extends object = any,
E = any
> extends TemplateSet {
static validateTarget = validateTarget;
Root: ComponentConstructor<P, E>;
props: P;
env: E;
scheduler = new Scheduler();
root: ComponentNode<P, E> | null = null;
constructor(Root: ComponentConstructor<P, E>, config: AppConfig<P, E> = {}) {
super(config);
this.Root = Root;
if (config.test) {
this.dev = true;
}
if (this.dev && !config.test && !hasBeenLogged) {
console.info(DEV_MSG());
hasBeenLogged = true;
}
const env = config.env || {};
const descrs = Object.getOwnPropertyDescriptors(env);
this.env = Object.freeze(Object.create(Object.getPrototypeOf(env), descrs));
this.props = config.props || ({} as P);
}
mount(target: HTMLElement, options?: MountOptions): Promise<Component<P, E> & InstanceType<T>> {
App.validateTarget(target);
const node = this.makeNode(this.Root, this.props);
const prom = this.mountNode(node, target, options);
this.root = node;
return prom;
}
makeNode(Component: ComponentConstructor, props: any): ComponentNode {
return new ComponentNode(Component, props, this);
}
mountNode(node: ComponentNode, target: HTMLElement, options?: MountOptions) {
const promise: any = new Promise((resolve, reject) => {
let isResolved = false;
// manually set a onMounted callback.
// that way, we are independant from the current node.
node.mounted.push(() => {
resolve(node.component);
isResolved = true;
});
// Manually add the last resort error handler on the node
let handlers = nodeErrorHandlers.get(node);
if (!handlers) {
handlers = [];
nodeErrorHandlers.set(node, handlers);
}
handlers.unshift((e) => {
if (isResolved) {
console.error(e);
} else {
reject(e);
}
throw e;
});
});
node.mountComponent(target, options);
return promise;
}
destroy() {
if (this.root) {
this.scheduler.flush();
this.root.destroy();
}
}
}
export async function mount<
T extends abstract new (...args: any) => any = any,
P extends object = any,
E = any
>(
C: T & ComponentConstructor<P, E>,
target: HTMLElement,
config: AppConfig<P, E> & MountOptions = {}
): Promise<Component<P, E> & InstanceType<T>> {
return new App(C, config).mount(target, config);
}
+203
View File
@@ -0,0 +1,203 @@
import { BDom, multi, text, toggler, createCatcher } from "../blockdom";
import { validateProps } from "../component/props_validation";
import { Markup } from "../utils";
import { html } from "../blockdom/index";
import { TARGET } from "../reactivity";
/**
* This file contains utility functions that will be injected in each template,
* to perform various useful tasks in the compiled code.
*/
function withDefault(value: any, defaultValue: any): any {
return value === undefined || value === null || value === false ? defaultValue : value;
}
function callSlot(
ctx: any,
parent: any,
key: string,
name: string,
dynamic: boolean,
extra: any,
defaultContent?: (ctx: any, node: any, key: string) => BDom
): BDom {
key = key + "__slot_" + name;
const slots = ctx.props[TARGET].slots || {};
const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = Object.create(__ctx || {});
if (__scope) {
slotScope[__scope] = extra;
}
const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
if (defaultContent) {
let child1: BDom | undefined = undefined;
let child2: BDom | undefined = undefined;
if (slotBDom) {
child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
} else {
child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
}
return multi([child1, child2]);
}
return slotBDom || text("");
}
function capture(ctx: any): any {
const component = ctx.__owl__.component;
const result = Object.create(component);
for (let k in ctx) {
result[k] = ctx[k];
}
return result;
}
function withKey(elem: any, k: string) {
elem.key = k;
return elem;
}
function prepareList(collection: any): [any[], any[], number, any[]] {
let keys: any[];
let values: any[];
if (Array.isArray(collection)) {
keys = collection;
values = collection;
} else if (collection) {
values = Object.keys(collection);
keys = Object.values(collection);
} else {
throw new Error("Invalid loop expression");
}
const n = values.length;
return [keys, values, n, new Array(n)];
}
const isBoundary = Symbol("isBoundary");
function setContextValue(ctx: { [key: string]: any }, key: string, value: any): void {
const ctx0 = ctx;
while (!ctx.hasOwnProperty(key) && !ctx.hasOwnProperty(isBoundary)) {
const newCtx = ctx.__proto__;
if (!newCtx) {
ctx = ctx0;
break;
}
ctx = newCtx;
}
ctx[key] = value;
}
function toNumber(val: string): number | string {
const n = parseFloat(val);
return isNaN(n) ? val : n;
}
function shallowEqual(l1: any[], l2: any[]): boolean {
for (let i = 0, l = l1.length; i < l; i++) {
if (l1[i] !== l2[i]) {
return false;
}
}
return true;
}
class LazyValue {
fn: any;
ctx: any;
node: any;
constructor(fn: any, ctx: any, node: any) {
this.fn = fn;
this.ctx = capture(ctx);
this.node = node;
}
evaluate(): any {
return this.fn(this.ctx, this.node);
}
toString() {
return this.evaluate().toString();
}
}
/*
* Safely outputs `value` as a block depending on the nature of `value`
*/
export function safeOutput(value: any): ReturnType<typeof toggler> {
if (!value) {
return value;
}
let safeKey;
let block;
if (value instanceof Markup) {
safeKey = `string_safe`;
block = html(value as string);
} else if (value instanceof LazyValue) {
safeKey = `lazy_value`;
block = value.evaluate();
} else if (value instanceof String || typeof value === "string") {
safeKey = "string_unsafe";
block = text(value);
} else {
// Assuming it is a block
safeKey = "block_safe";
block = value;
}
return toggler(safeKey, block);
}
let boundFunctions = new WeakMap();
function bind(ctx: any, fn: Function): Function {
let component = ctx.__owl__.component;
let boundFnMap = boundFunctions.get(component);
if (!boundFnMap) {
boundFnMap = new WeakMap();
boundFunctions.set(component, boundFnMap);
}
let boundFn = boundFnMap.get(fn);
if (!boundFn) {
boundFn = fn.bind(component);
boundFnMap.set(fn, boundFn);
}
return boundFn;
}
type RefMap = { [key: string]: HTMLElement | null };
type RefSetter = (el: HTMLElement | null) => void;
function multiRefSetter(refs: RefMap, name: string): RefSetter {
let count = 0;
return (el) => {
if (el) {
count++;
if (count > 1) {
throw new Error("Cannot have 2 elements with same ref name at the same time");
}
}
if (count === 0 || el) {
refs[name] = el;
}
};
}
export const helpers = {
withDefault,
zero: Symbol("zero"),
isBoundary,
callSlot,
capture,
withKey,
prepareList,
setContextValue,
multiRefSetter,
shallowEqual,
toNumber,
validateProps,
LazyValue,
safeOutput,
bind,
createCatcher,
};
@@ -1,11 +1,12 @@
import { compile, Template, TemplateFunction } from "../compiler";
import { comment, createBlock, html, list, multi, text, toggler } from "./blockdom";
import { getCurrent } from "./component_node";
import { Portal, portalTemplate } from "./portal";
import { createBlock, html, list, multi, text, toggler, comment } from "../blockdom";
import { compile, Template } from "../compiler";
import { markRaw } from "../reactivity";
import { Portal } from "../portal";
import { component, getCurrent } from "../component/component_node";
import { helpers } from "./template_helpers";
import { OwlError } from "./error_handling";
import { globalTemplates } from "../utils";
const bdom = { text, createBlock, list, multi, html, toggler, comment };
const bdom = { text, createBlock, list, multi, html, toggler, component, comment };
function parseXML(xml: string): Document {
const parser = new DOMParser();
@@ -32,11 +33,27 @@ function parseXML(xml: string): Document {
}
}
}
throw new OwlError(msg);
throw new Error(msg);
}
return doc;
}
/**
* Returns the helpers object that will be injected in each template closure
* function
*/
function makeHelpers(getTemplate: (name: string) => Template): any {
return Object.assign({}, helpers, {
Portal,
markRaw,
getTemplate,
call: (owner: any, subTemplate: string, ctx: any, parent: any, key: any) => {
const template = getTemplate(subTemplate);
return toggler(subTemplate, template.call(owner, ctx, parent, key));
},
});
}
export interface TemplateSetConfig {
dev?: boolean;
translatableAttributes?: string[];
@@ -45,15 +62,12 @@ export interface TemplateSetConfig {
}
export class TemplateSet {
static registerTemplate(name: string, fn: TemplateFunction) {
globalTemplates[name] = fn;
}
dev: boolean;
rawTemplates: typeof globalTemplates = Object.create(globalTemplates);
templates: { [name: string]: Template } = {};
translateFn?: (s: string) => string;
translatableAttributes?: string[];
Portal = Portal;
helpers: any;
constructor(config: TemplateSetConfig = {}) {
this.dev = config.dev || false;
@@ -62,27 +76,21 @@ export class TemplateSet {
if (config.templates) {
this.addTemplates(config.templates);
}
this.helpers = makeHelpers(this.getTemplate.bind(this));
}
addTemplate(name: string, template: string | Element) {
if (name in this.rawTemplates) {
const rawTemplate = this.rawTemplates[name];
const currentAsString =
typeof rawTemplate === "string"
? rawTemplate
: rawTemplate instanceof Element
? rawTemplate.outerHTML
: rawTemplate.toString();
const newAsString = typeof template === "string" ? template : template.outerHTML;
if (currentAsString === newAsString) {
return;
}
throw new OwlError(`Template ${name} already defined with different content`);
addTemplate(
name: string,
template: string | Element,
options: { allowDuplicate?: boolean } = {}
) {
if (name in this.rawTemplates && !options.allowDuplicate) {
throw new Error(`Template ${name} already defined`);
}
this.rawTemplates[name] = template;
}
addTemplates(xml: string | Document) {
addTemplates(xml: string | Document, options: { allowDuplicate?: boolean } = {}) {
if (!xml) {
// empty string
return;
@@ -90,7 +98,7 @@ export class TemplateSet {
xml = xml instanceof Document ? xml : parseXML(xml);
for (const template of xml.querySelectorAll("[t-name]")) {
const name = template.getAttribute("t-name")!;
this.addTemplate(name, template);
this.addTemplate(name, template, options);
}
}
@@ -103,44 +111,27 @@ export class TemplateSet {
const componentName = getCurrent().component.constructor.name;
extraInfo = ` (for component "${componentName}")`;
} catch {}
throw new OwlError(`Missing template: "${name}"${extraInfo}`);
throw new Error(`Missing template: "${name}"${extraInfo}`);
}
const isFn = typeof rawTemplate === "function" && !(rawTemplate instanceof Element);
const templateFn = isFn ? rawTemplate : this._compileTemplate(name, rawTemplate);
const templateFn = this._compileTemplate(name, rawTemplate);
// first add a function to lazily get the template, in case there is a
// recursive call to the template name
const templates = this.templates;
this.templates[name] = function (context, parent) {
return templates[name].call(this, context, parent);
};
const template = templateFn(this, bdom, helpers);
const template = templateFn(bdom, this.helpers);
this.templates[name] = template;
}
return this.templates[name];
}
_compileTemplate(name: string, template: string | Element): ReturnType<typeof compile> {
throw new OwlError(`Unable to compile a template. Please use owl full build instead`);
}
callTemplate(owner: any, subTemplate: string, ctx: any, parent: any, key: any): any {
const template = this.getTemplate(subTemplate);
return toggler(subTemplate, template.call(owner, ctx, parent, key));
_compileTemplate(name: string, template: string | Element) {
return compile(template, {
name,
dev: this.dev,
translateFn: this.translateFn,
translatableAttributes: this.translatableAttributes,
});
}
}
// -----------------------------------------------------------------------------
// xml tag helper
// -----------------------------------------------------------------------------
export const globalTemplates: { [key: string]: string | Element | TemplateFunction } = {};
export function xml(...args: Parameters<typeof String.raw>) {
const name = `__template__${xml.nextId++}`;
const value = String.raw(...args);
globalTemplates[name] = value;
return name;
}
xml.nextId = 1;
TemplateSet.registerTemplate("__portal__", portalTemplate);
@@ -93,10 +93,6 @@ function toClassObj(expr: string | number | { [c: string]: any }) {
for (let key in expr as any) {
const value = (expr as any)[key];
if (value) {
key = trim.call(key);
if (!key) {
continue;
}
const words = split.call(key, wordRegexp);
for (let word of words) {
result[word] = value;
@@ -144,7 +140,7 @@ export function updateClass(this: HTMLElement, val: any, oldVal: any) {
export function makePropSetter(name: string): Setter<HTMLElement> {
return function setProp(this: HTMLElement, value: any) {
// support 0, fallback to empty string for other falsy values
(this as any)[name] = value === 0 ? 0 : value ? value.valueOf() : "";
(this as any)[name] = value === 0 ? 0 : value || "";
};
}
@@ -1,4 +1,3 @@
import { OwlError } from "../error_handling";
import {
attrsSetter,
attrsUpdater,
@@ -157,15 +156,6 @@ function buildTree(
: document.createElement(tagName);
}
if (el instanceof Element) {
if (!domParentTree) {
// some html elements may have side effects when setting their attributes.
// For example, setting the src attribute of an <img/> will trigger a
// request to get the corresponding image. This is something that we
// don't want at compile time. We avoid that by putting the content of
// the block in a <template/> element
const fragment = document.createElement("template").content;
fragment.appendChild(el);
}
for (let i = 0; i < attrs.length; i++) {
const attrName = attrs[i].name;
const attrValue = attrs[i].value;
@@ -255,7 +245,7 @@ function buildTree(
};
}
}
throw new OwlError("boom");
throw new Error("boom");
}
function addRef(tree: IntermediateTree) {
@@ -517,13 +507,9 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
return this.el!;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
nodeInsertBefore.call(parent, this.el!, node);
}
moveBeforeVNode(other: Block | null, afterNode: Node | null) {
nodeInsertBefore.call(this.parentEl, this.el!, other ? other.el! : afterNode);
moveBefore(other: Block | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
}
toString() {
+89
View File
@@ -0,0 +1,89 @@
import { createEventHandler } from "./events";
import type { VNode } from "./index";
type EventsSpec = { [name: string]: number };
type Catcher = (child: VNode, handlers: any[]) => VNode;
export function createCatcher(eventsSpec: EventsSpec): Catcher {
let setupFns: any[] = [];
let removeFns: any[] = [];
for (let name in eventsSpec) {
let index = eventsSpec[name];
let { setup, remove } = createEventHandler(name);
setupFns[index] = setup;
removeFns[index] = remove;
}
let n = setupFns.length;
class VCatcher {
child: VNode;
handlers: any[];
parentEl?: HTMLElement | undefined;
afterNode: Node | null = null;
constructor(child: VNode, handlers: any[]) {
this.child = child;
this.handlers = handlers;
}
mount(parent: HTMLElement, afterNode: Node | null) {
this.parentEl = parent;
this.afterNode = afterNode;
this.child.mount(parent, afterNode);
for (let i = 0; i < n; i++) {
let origFn = this.handlers[i][0];
const self = this;
this.handlers[i][0] = function (ev: any) {
const target = ev.target;
let currentNode: any = self.child.firstNode();
const afterNode = self.afterNode;
while (currentNode !== afterNode) {
if (currentNode.contains(target)) {
return origFn.call(this, ev);
}
currentNode = currentNode.nextSibling;
}
};
setupFns[i].call(parent, this.handlers[i]);
}
}
moveBefore(other: VCatcher | null, afterNode: Node | null) {
this.afterNode = null;
this.child.moveBefore(other ? other.child : null, afterNode);
}
patch(other: VCatcher, withBeforeRemove: boolean) {
if (this === other) {
return;
}
this.handlers = other.handlers;
this.child.patch(other.child, withBeforeRemove);
}
beforeRemove() {
this.child.beforeRemove();
}
remove() {
for (let i = 0; i < n; i++) {
removeFns[i].call(this.parentEl!);
}
this.child.remove();
}
firstNode(): Node | undefined {
return this.child.firstNode();
}
toString(): string {
return this.child.toString();
}
}
return function (child: VNode, handlers: any[]): VNode<VCatcher> {
return new VCatcher(child, handlers);
};
}
@@ -27,8 +27,8 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa
}
function listener(ev: Event) {
const currentTarget = ev.currentTarget as HTMLElement;
if (!currentTarget || !currentTarget.ownerDocument.contains(currentTarget)) return;
const currentTarget = ev.currentTarget;
if (!currentTarget || !document.contains(currentTarget as HTMLElement)) return;
const data = (currentTarget as any)[eventKey];
if (!data) return;
config.mainEventHandler(data, ev, currentTarget);
@@ -29,16 +29,12 @@ class VHtml {
}
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
for (let elem of this.content) {
nodeInsertBefore.call(parent, elem, node);
}
}
moveBeforeVNode(other: VHtml | null, afterNode: Node | null) {
moveBefore(other: VHtml | null, afterNode: Node | null) {
const target = other ? other.content[0] : afterNode;
this.moveBeforeDOMNode(target);
const parent = this.parentEl;
for (let elem of this.content) {
nodeInsertBefore.call(parent, elem, target);
}
}
patch(other: VHtml) {
@@ -10,8 +10,7 @@ export { createCatcher } from "./event_catcher";
export interface VNode<T = any> {
mount(parent: HTMLElement, afterNode: Node | null): void;
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement): void;
moveBeforeVNode(other: T | null, afterNode: Node | null): void;
moveBefore(other: T | null, afterNode: Node | null): void;
patch(other: T, withBeforeRemove: boolean): void;
beforeRemove(): void;
remove(): void;
@@ -38,23 +38,14 @@ class VList {
this.parentEl = parent;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
const children = this.children;
for (let i = 0, l = children.length; i < l; i++) {
children[i].moveBeforeDOMNode(node, parent);
}
parent!.insertBefore(this.anchor!, node);
}
moveBeforeVNode(other: VList | null, afterNode: Node | null) {
moveBefore(other: VList | null, afterNode: Node | null) {
if (other) {
const next = other!.children[0];
afterNode = (next ? next.firstNode() : other!.anchor) || null;
}
const children = this.children;
for (let i = 0, l = children.length; i < l; i++) {
children[i].moveBeforeVNode(null, afterNode);
children[i].moveBefore(null, afterNode);
}
this.parentEl!.insertBefore(this.anchor!, afterNode);
}
@@ -75,7 +66,7 @@ class VList {
patch: cPatch,
remove: cRemove,
beforeRemove,
moveBeforeVNode: cMoveBefore,
moveBefore: cMoveBefore,
firstNode: cFirstNode,
} = proto;
@@ -38,22 +38,7 @@ export class VMulti {
this.parentEl = parent;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
const children = this.children;
const anchors = this.anchors;
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
child.moveBeforeDOMNode(node, parent);
} else {
const anchor = anchors![i];
nodeInsertBefore.call(parent, anchor, node);
}
}
}
moveBeforeVNode(other: VMulti | null, afterNode: Node | null) {
moveBefore(other: VMulti | null, afterNode: Node | null) {
if (other) {
const next = other!.children[0];
afterNode = (next ? next.firstNode() : other!.anchors![0]) || null;
@@ -64,7 +49,7 @@ export class VMulti {
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
child.moveBeforeVNode(null, afterNode);
child.moveBefore(null, afterNode);
} else {
const anchor = anchors![i];
nodeInsertBefore.call(parent, anchor, afterNode);
@@ -23,13 +23,9 @@ abstract class VSimpleNode {
this.el = node;
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
nodeInsertBefore.call(parent, this.el!, node);
}
moveBeforeVNode(other: VText | null, afterNode: Node | null) {
nodeInsertBefore.call(this.parentEl, this.el!, other ? other.el! : afterNode);
moveBefore(other: VText | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
}
beforeRemove() {}
@@ -20,12 +20,8 @@ class VToggler {
this.child.mount(parent, afterNode);
}
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement) {
this.child.moveBeforeDOMNode(node, parent);
}
moveBeforeVNode(other: VToggler | null, afterNode: Node | null) {
this.moveBeforeDOMNode((other && other.firstNode()) || afterNode);
moveBefore(other: VToggler | null, afterNode: Node | null) {
this.child.moveBefore(other ? other.child : null, afterNode);
}
patch(other: VToggler, withBeforeRemove: boolean) {
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -1,11 +1,10 @@
import type { TemplateSet } from "../runtime/template_set";
import type { BDom } from "../runtime/blockdom";
import type { BDom } from "../blockdom";
import { CodeGenerator, Config } from "./code_generator";
import { parse } from "./parser";
export type Template = (context: any, vnode: any, key?: string) => BDom;
export type TemplateFunction = (app: TemplateSet, bdom: any, helpers: any) => Template;
export type TemplateFunction = (blocks: any, utils: any) => Template;
interface CompileOptions extends Config {
name?: string;
@@ -27,5 +26,5 @@ export function compile(
const codeGenerator = new CodeGenerator(ast, { ...options, hasSafeContext });
const code = codeGenerator.generateCode();
// template function
return new Function("app, bdom, helpers", code) as TemplateFunction;
return new Function("bdom, helpers", code) as TemplateFunction;
}
+12 -23
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
/**
* Owl QWeb Expression Parser
*
@@ -28,7 +26,7 @@ import { OwlError } from "../runtime/error_handling";
//------------------------------------------------------------------------------
const RESERVED_WORDS =
"true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,eval,void,Math,RegExp,Array,Object,Date".split(
"true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,eval,void,Math,RegExp,Array,Object,Date".split(
","
);
@@ -87,9 +85,8 @@ const STATIC_TOKEN_MAP: { [key: string]: TKind } = Object.assign(Object.create(n
});
// note that the space after typeof is relevant. It makes sure that the formatted
// expression has a space after typeof. Currently we don't support delete and void
const OPERATORS =
"...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ,new ,|,&,^,~".split(",");
// expression has a space after typeof
const OPERATORS = "...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ".split(",");
type Tokenizer = (expr: string) => Token | false;
@@ -108,14 +105,14 @@ let tokenizeString: Tokenizer = function (expr) {
i++;
cur = expr[i];
if (!cur) {
throw new OwlError("Invalid expression");
throw new Error("Invalid expression");
}
s += cur;
}
i++;
}
if (expr[i] !== start) {
throw new OwlError("Invalid expression");
throw new Error("Invalid expression");
}
s += start;
if (start === "`") {
@@ -225,7 +222,7 @@ export function tokenize(expr: string): Token[] {
error = e; // Silence all errors and throw a generic error below
}
if (current.length || error) {
throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);
throw new Error(`Tokenizer error: could not tokenize \`${expr}\``);
}
return result;
}
@@ -347,29 +344,21 @@ export function compileExprToArray(expr: string): Token[] {
return tokens;
}
// Leading spaces are trimmed during tokenization, so they need to be added back for some values
const paddedValues = new Map([["in ", " in "]]);
export function compileExpr(expr: string): string {
return compileExprToArray(expr)
.map((t) => paddedValues.get(t.value) || t.value)
.map((t) => t.value)
.join("");
}
export const INTERP_REGEXP = /\{\{.*?\}\}|\#\{.*?\}/g;
export const INTERP_REGEXP = /\{\{.*?\}\}/g;
const INTERP_GROUP_REGEXP = /\{\{.*?\}\}/g;
export function replaceDynamicParts(s: string, replacer: (s: string) => string) {
export function interpolate(s: string): string {
let matches = s.match(INTERP_REGEXP);
if (matches && matches[0].length === s.length) {
return `(${replacer(s.slice(2, matches[0][0] === "{" ? -2 : -1))})`;
return `(${compileExpr(s.slice(2, -2))})`;
}
let r = s.replace(
INTERP_REGEXP,
(s) => "${" + replacer(s.slice(2, s[0] === "{" ? -2 : -1)) + "}"
);
let r = s.replace(INTERP_GROUP_REGEXP, (s) => "${" + compileExpr(s.slice(2, -2)) + "}");
return "`" + r + "`";
}
export function interpolate(s: string): string {
return replaceDynamicParts(s, compileExpr);
}
+84 -116
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
// -----------------------------------------------------------------------------
// AST Type definition
// -----------------------------------------------------------------------------
@@ -23,7 +21,6 @@ export const enum ASTType {
TDebug,
TLog,
TSlot,
TSetSlot,
TCallBlock,
TTranslation,
TPortal,
@@ -118,12 +115,9 @@ export interface ASTTCall {
type: ASTType.TCall;
name: string;
body: AST[] | null;
context: string | null;
}
export interface ASTSlotDefinition {
type: ASTType.TSetSlot;
name: string;
interface SlotDefinition {
content: AST | null;
scope: string | null;
on: EventHandlers | null;
@@ -137,8 +131,7 @@ export interface ASTComponent {
dynamicProps: string | null;
on: EventHandlers | null;
props: { [name: string]: string } | null;
body: AST | null;
// slots: { [name: string]: ASTSlotDefinition } | null;
slots: { [name: string]: SlotDefinition } | null;
}
export interface ASTSlot {
@@ -190,7 +183,6 @@ export type AST =
| ASTTKey
| ASTComponent
| ASTSlot
| ASTSlotDefinition
| ASTTCallBlock
| ASTLog
| ASTDebug
@@ -243,7 +235,6 @@ function parseNode(node: Node, ctx: ParsingContext): AST | null {
parseTKey(node, ctx) ||
parseTTranslation(node, ctx) ||
parseTSlot(node, ctx) ||
parseTSetSlot(node, ctx) ||
parseTOutNode(node, ctx) ||
parseComponent(node, ctx) ||
parseDOMNode(node, ctx) ||
@@ -327,7 +318,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
return null;
}
if (tagName.startsWith("block-")) {
throw new OwlError(`Invalid tag name: '${tagName}'`);
throw new Error(`Invalid tag name: '${tagName}'`);
}
ctx = Object.assign({}, ctx);
if (tagName === "pre") {
@@ -348,15 +339,13 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
const value = node.getAttribute(attr)!;
if (attr.startsWith("t-on")) {
if (attr === "t-on") {
throw new OwlError("Missing event name with t-on directive");
throw new Error("Missing event name with t-on directive");
}
on = on || {};
on[attr.slice(5)] = value;
} else if (attr.startsWith("t-model")) {
if (!["input", "select", "textarea"].includes(tagName)) {
throw new OwlError(
"The t-model directive only works with <input>, <textarea> and <select>"
);
throw new Error("The t-model directive only works with <input>, <textarea> and <select>");
}
let baseExpr, expr;
@@ -369,7 +358,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
baseExpr = value.slice(0, index);
expr = value.slice(index + 1, -1);
} else {
throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);
throw new Error(`Invalid t-model expression: "${value}" (it should be assignable)`);
}
const typeAttr = node.getAttribute("type");
@@ -400,10 +389,10 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
ctx.tModelInfo = model;
}
} else if (attr.startsWith("block-")) {
throw new OwlError(`Invalid attribute: '${attr}'`);
throw new Error(`Invalid attribute: '${attr}'`);
} else if (attr !== "t-name") {
if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
throw new OwlError(`Unknown QWeb directive: '${attr}'`);
throw new Error(`Unknown QWeb directive: '${attr}'`);
}
const tModel = ctx.tModelInfo;
if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) {
@@ -457,7 +446,7 @@ function parseTEscNode(node: Element, ctx: ParsingContext): AST | null {
};
}
if (ast.type === ASTType.TComponent) {
throw new OwlError("t-esc is not supported on Component nodes");
throw new Error("t-esc is not supported on Component nodes");
}
return tesc;
}
@@ -513,7 +502,7 @@ function parseTForEach(node: Element, ctx: ParsingContext): AST | null {
node.removeAttribute("t-as");
const key = node.getAttribute("t-key");
if (!key) {
throw new OwlError(
throw new Error(
`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`
);
}
@@ -568,23 +557,21 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
return null;
}
const subTemplate = node.getAttribute("t-call")!;
const context = node.getAttribute("t-call-context");
node.removeAttribute("t-call");
node.removeAttribute("t-call-context");
node.removeAttribute("t-call");
if (node.tagName !== "t") {
const ast = parseNode(node, ctx);
const tcall: AST = { type: ASTType.TCall, name: subTemplate, body: null, context };
const tcall: AST = { type: ASTType.TCall, name: subTemplate, body: null };
if (ast && ast.type === ASTType.DomNode) {
ast.content = [tcall];
return ast;
}
// if (ast && ast.type === ASTType.TComponent) {
// return {
// ...ast,
// slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
// };
// }
if (ast && ast.type === ASTType.TComponent) {
return {
...ast,
slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
};
}
}
const body = parseChildren(node, ctx);
@@ -592,7 +579,6 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
type: ASTType.TCall,
name: subTemplate,
body: body.length ? body : null,
context,
};
}
@@ -696,9 +682,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
let isDynamic = node.hasAttribute("t-component");
if (isDynamic && name !== "t") {
throw new OwlError(
`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`
);
throw new Error(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);
}
if (!(firstLetter === firstLetter.toUpperCase() || isDynamic)) {
@@ -712,8 +696,8 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
const dynamicProps = node.getAttribute("t-props");
node.removeAttribute("t-props");
// const defaultSlotScope = node.getAttribute("t-slot-scope");
// node.removeAttribute("t-slot-scope");
const defaultSlotScope = node.getAttribute("t-slot-scope");
node.removeAttribute("t-slot-scope");
let on: ASTComponent["on"] = null;
let props: ASTComponent["props"] = null;
@@ -725,7 +709,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
on[name.slice(5)] = value;
} else {
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-"));
throw new OwlError(message || `unsupported directive on Component: ${name}`);
throw new Error(message || `unsupported directive on Component: ${name}`);
}
} else {
props = props || {};
@@ -733,17 +717,66 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
}
}
let body: ASTComponent["body"] = null;
// let slots: ASTComponent["slots"] | null = null;
let slots: ASTComponent["slots"] | null = null;
if (node.hasChildNodes()) {
body = parseChildNodes(node, ctx);
if (!node.querySelector('[t-set-slot]')) {
body = {type: ASTType.TSetSlot, name: "default", content: body, on: null, attrs: null, scope: null}
const clone = <Element>node.cloneNode(true);
// named slots
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
for (let slotNode of slotNodes) {
if (slotNode.tagName !== "t") {
throw new Error(
`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`
);
}
const name = slotNode.getAttribute("t-set-slot")!;
// check if this is defined in a sub component (in which case it should
// be ignored)
let el = slotNode.parentElement!;
let isInSubComponent = false;
while (el !== clone) {
if (el!.hasAttribute("t-component") || el!.tagName[0] === el!.tagName[0].toUpperCase()) {
isInSubComponent = true;
break;
}
el = el.parentElement!;
}
if (isInSubComponent) {
continue;
}
slotNode.removeAttribute("t-set-slot");
slotNode.remove();
const slotAst = parseNode(slotNode, ctx);
let on: SlotDefinition["on"] = null;
let attrs: Attrs | null = null;
let scope: string | null = null;
for (let attributeName of slotNode.getAttributeNames()) {
const value = slotNode.getAttribute(attributeName)!;
if (attributeName === "t-slot-scope") {
scope = value;
continue;
} else if (attributeName.startsWith("t-on-")) {
on = on || {};
on[attributeName.slice(5)] = value;
} else {
attrs = attrs || {};
attrs[attributeName] = value;
}
}
slots = slots || {};
slots[name] = { content: slotAst, on, attrs, scope };
}
// default slot
const defaultContent = parseChildNodes(clone, ctx);
if (defaultContent) {
slots = slots || {};
slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
}
}
return { type: ASTType.TComponent, name, isDynamic, dynamicProps, props, body, on };
return { type: ASTType.TComponent, name, isDynamic, dynamicProps, props, slots, on };
}
// -----------------------------------------------------------------------------
@@ -777,71 +810,6 @@ function parseTSlot(node: Element, ctx: ParsingContext): AST | null {
};
}
function parseTSetSlot(node: Element, ctx: ParsingContext): AST | null {
if (!node.hasAttribute("t-set-slot")) {
return null;
}
// const t = el.ownerDocument.createElement("t");
// const clone = <Element>node.cloneNode(true);
// // named slots
// const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
// for (let slotNode of slotNodes) {
if (node.tagName !== "t") {
throw new OwlError(
`Directive 't-set-slot' can only be used on <t> nodes (used on a <${node.tagName}>)`
);
}
const name = node.getAttribute("t-set-slot")!;
// // check if this is defined in a sub component (in which case it should
// // be ignored)
// let el = slotNode.parentElement!;
// let isInSubComponent = false;
// while (el !== clone) {
// if (el!.hasAttribute("t-component") || el!.tagName[0] === el!.tagName[0].toUpperCase()) {
// isInSubComponent = true;
// break;
// }
// el = el.parentElement!;
// }
// if (isInSubComponent) {
// continue;
// }
node.removeAttribute("t-set-slot");
node.remove();
const slotAst = parseNode(node, ctx);
let on: ASTSlotDefinition["on"] = null;
let attrs: Attrs | null = null;
let scope: string | null = null;
for (let attributeName of node.getAttributeNames()) {
const value = node.getAttribute(attributeName)!;
if (attributeName === "t-slot-scope") {
scope = value;
continue;
} else if (attributeName.startsWith("t-on-")) {
on = on || {};
on[attributeName.slice(5)] = value;
} else {
attrs = attrs || {};
attrs[attributeName] = value;
}
}
// slots = slots || {};
return { type: ASTType.TSetSlot, name, content: slotAst, on, attrs, scope };
// }
// // default slot
// const defaultContent = parseChildNodes(clone, ctx);
// slots = slots || {};
// // t-set-slot="default" has priority over content
// if (defaultContent && !slots.default) {
// slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
// }
}
function parseTTranslation(node: Element, ctx: ParsingContext): AST | null {
if (node.getAttribute("t-translation") !== "off") {
return null;
@@ -932,7 +900,7 @@ function normalizeTIf(el: Element) {
let nattr = (name: string) => +!!node.getAttribute(name);
if (prevElem && (pattr("t-if") || pattr("t-elif"))) {
if (pattr("t-foreach")) {
throw new OwlError(
throw new Error(
"t-if cannot stay at the same level as t-foreach when using t-elif or t-else"
);
}
@@ -941,19 +909,19 @@ function normalizeTIf(el: Element) {
return a + b;
}) > 1
) {
throw new OwlError("Only one conditional branching directive is allowed per node");
throw new Error("Only one conditional branching directive is allowed per node");
}
// All text (with only spaces) and comment nodes (nodeType 8) between
// branch nodes are removed
let textNode;
while ((textNode = node.previousSibling) !== prevElem) {
if (textNode!.nodeValue!.trim().length && textNode!.nodeType !== 8) {
throw new OwlError("text is not allowed between branching directives");
throw new Error("text is not allowed between branching directives");
}
textNode!.remove();
}
} else {
throw new OwlError(
throw new Error(
"t-elif and t-else directives must be preceded by a t-if or t-elif directive"
);
}
@@ -974,7 +942,7 @@ function normalizeTEsc(el: Element) {
);
for (const el of elements) {
if (el.childNodes.length) {
throw new OwlError("Cannot have t-esc on a component that already has content");
throw new Error("Cannot have t-esc on a component that already has content");
}
const value = el.getAttribute("t-esc");
el.removeAttribute("t-esc");
@@ -1028,7 +996,7 @@ function parseXML(xml: string): XMLDocument {
}
}
}
throw new OwlError(msg);
throw new Error(msg);
}
return doc;
@@ -1,17 +1,15 @@
import { Schema } from "./validation";
import type { ComponentNode } from "./component_node";
// -----------------------------------------------------------------------------
// Component Class
// -----------------------------------------------------------------------------
export type Props = { [key: string]: any };
type Props = { [key: string]: any };
interface StaticComponentProperties {
template: string;
defaultProps?: any;
props?: Schema;
components?: { [componentName: string]: ComponentConstructor };
props?: any;
}
export type ComponentConstructor<P extends Props = any, E = any> = (new (
@@ -39,6 +37,6 @@ export class Component<Props = any, Env = any> {
setup() {}
render(deep: boolean = false) {
this.__owl__.render(deep === true);
this.__owl__.render(deep);
}
}
@@ -1,17 +1,25 @@
import type { App, Env } from "./app";
import { BDom, VNode } from "./blockdom";
import { Component, ComponentConstructor, Props } from "./component";
import { fibersInError, OwlError } from "./error_handling";
import type { App, Env } from "../app/app";
import { BDom, VNode } from "../blockdom";
import {
clearReactivesForCallback,
getSubscriptions,
NonReactive,
Reactive,
reactive,
TARGET,
} from "../reactivity";
import { batched, Callback } from "../utils";
import { Component, ComponentConstructor } from "./component";
import { fibersInError, handleError } from "./error_handling";
import { Fiber, makeChildFiber, makeRootFiber, MountFiber, MountOptions } from "./fibers";
import { clearReactivesForCallback, getSubscriptions, reactive, targets } from "./reactivity";
import { applyDefaultProps } from "./props_validation";
import { STATUS } from "./status";
import { batched, Callback } from "./utils";
let currentNode: ComponentNode | null = null;
export function getCurrent(): ComponentNode {
if (!currentNode) {
throw new OwlError("No active component (a hook function should only be called in 'setup')");
throw new Error("No active component (a hook function should only be called in 'setup')");
}
return currentNode;
}
@@ -20,16 +28,6 @@ export function useComponent(): Component {
return currentNode!.component;
}
/**
* Apply default props (only top level).
*/
function applyDefaultProps<P extends object>(props: P, defaultProps: Partial<P>) {
for (let propName in defaultProps) {
if (props[propName] === undefined) {
(props as any)[propName] = defaultProps[propName];
}
}
}
// -----------------------------------------------------------------------------
// Integration with reactivity system (useState)
// -----------------------------------------------------------------------------
@@ -45,11 +43,11 @@ const batchedRenderFunctions = new WeakMap<ComponentNode, Callback>();
* relevant changes
* @see reactive
*/
export function useState<T extends object>(state: T): T {
export function useState<T extends object>(state: T): Reactive<T> | NonReactive<T> {
const node = getCurrent();
let render = batchedRenderFunctions.get(node)!;
if (!render) {
render = batched(node.render.bind(node, false));
render = batched(node.render.bind(node));
batchedRenderFunctions.set(node, render);
// manual implementation of onWillDestroy to break cyclic dependency
node.willDestroy.push(clearReactivesForCallback.bind(null, render));
@@ -57,13 +55,82 @@ export function useState<T extends object>(state: T): T {
return reactive(state, render);
}
// -----------------------------------------------------------------------------
// component function (used in compiled template code)
// -----------------------------------------------------------------------------
type Props = { [key: string]: any };
function arePropsDifferent(props1: Props, props2: Props): boolean {
for (let k in props1) {
if (props1[k] !== props2[k]) {
return true;
}
}
return Object.keys(props1).length !== Object.keys(props2).length;
}
export function component<P extends object>(
name: string | ComponentConstructor<P>,
props: P,
key: string,
ctx: ComponentNode,
parent: any
): ComponentNode<P> {
let node: any = ctx.children[key];
let isDynamic = typeof name !== "string";
if (node) {
if (node.status < STATUS.MOUNTED) {
node.destroy();
node = undefined;
} else if (node.status === STATUS.DESTROYED) {
node = undefined;
}
}
if (isDynamic && node && node.component.constructor !== name) {
node = undefined;
}
const parentFiber = ctx.fiber!;
if (node) {
let shouldRender = node.forceNextRender;
if (shouldRender) {
node.forceNextRender = false;
} else {
const currentProps = node.component.props[TARGET];
shouldRender = parentFiber.deep || arePropsDifferent(currentProps, props);
}
if (shouldRender) {
node.updateAndRender(props, parentFiber);
}
} else {
// new component
let C;
if (isDynamic) {
C = name;
} else {
C = parent.constructor.components[name as any];
if (!C) {
throw new Error(`Cannot find the definition of component "${name}"`);
}
}
node = new ComponentNode(C, props, ctx.app, ctx);
ctx.children[key] = node;
node.initiateRender(new Fiber(node, parentFiber));
}
parentFiber.childrenMap[key] = node;
parentFiber.root!.reachedChildren.add(node);
return node;
}
// -----------------------------------------------------------------------------
// Component VNode class
// -----------------------------------------------------------------------------
type LifecycleHook = Function;
export class ComponentNode<P extends Props = any, E = any> implements VNode<ComponentNode<P, E>> {
export class ComponentNode<P extends object = any, E = any> implements VNode<ComponentNode<P, E>> {
el?: HTMLElement | Text | undefined;
app: App;
fiber: Fiber | null = null;
@@ -71,11 +138,10 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
bdom: BDom | null = null;
status: STATUS = STATUS.NEW;
forceNextRender: boolean = false;
parentKey: string | null;
props: P;
renderFn: Function;
parent: ComponentNode | null;
level: number;
childEnv: Env;
children: { [key: string]: ComponentNode } = Object.create(null);
refs: any = {};
@@ -88,34 +154,17 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
patched: LifecycleHook[] = [];
willDestroy: LifecycleHook[] = [];
constructor(
C: ComponentConstructor<P, E>,
props: P,
app: App,
parent: ComponentNode | null,
parentKey: string | null
) {
constructor(C: ComponentConstructor<P, E>, props: P, app: App, parent?: ComponentNode) {
currentNode = this;
this.app = app;
this.parent = parent;
this.props = props;
this.parentKey = parentKey;
const defaultProps = C.defaultProps;
props = Object.assign({}, props);
if (defaultProps) {
applyDefaultProps(props, defaultProps);
}
this.parent = parent || null;
this.level = parent ? parent.level + 1 : 0;
applyDefaultProps(props, C);
const env = (parent && parent.childEnv) || app.env;
this.childEnv = env;
for (const key in props) {
const prop = props[key];
if (prop && typeof prop === "object" && targets.has(prop)) {
props[key] = useState(prop);
}
}
this.component = new C(props, env, this);
const ctx = Object.assign(Object.create(this.component), { this: this.component });
this.renderFn = app.getTemplate(C.template).bind(this.component, ctx, this);
props = useState(props);
this.component = new C(props, env, this) as any;
this.renderFn = app.getTemplate(C.template).bind(this.component, this.component, this);
this.component.setup();
currentNode = null;
}
@@ -135,7 +184,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
try {
await Promise.all(this.willStart.map((f) => f.call(component)));
} catch (e) {
this.app.handleError({ node: this, error: e });
handleError({ node: this, error: e });
return;
}
if (this.status === STATUS.NEW && this.fiber === fiber) {
@@ -143,9 +192,9 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
}
}
async render(deep: boolean) {
async render(deep: boolean = false) {
let current = this.fiber;
if (current && (current.root!.locked || (current as any).bdom === true)) {
if (current && current.root!.locked) {
await Promise.resolve();
// situation may have changed after the microtask tick
current = this.fiber;
@@ -167,7 +216,6 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
const fiber = makeRootFiber(this);
fiber.deep = deep;
this.fiber = fiber;
this.app.scheduler.addFiber(fiber);
await Promise.resolve();
if (this.status === STATUS.DESTROYED) {
@@ -207,37 +255,21 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
for (let child of Object.values(this.children)) {
child._destroy();
}
if (this.willDestroy.length) {
try {
for (let cb of this.willDestroy) {
cb.call(component);
}
} catch (e) {
this.app.handleError({ error: e, node: this });
}
for (let cb of this.willDestroy) {
cb.call(component);
}
this.status = STATUS.DESTROYED;
}
async updateAndRender(props: P, parentFiber: Fiber) {
const rawProps = props;
props = Object.assign({}, props);
async updateAndRender(props: any, parentFiber: Fiber) {
// update
const fiber = makeChildFiber(this, parentFiber);
this.fiber = fiber;
const component = this.component;
const defaultProps = (component.constructor as any).defaultProps;
if (defaultProps) {
applyDefaultProps(props, defaultProps);
}
applyDefaultProps(props, component.constructor as any);
currentNode = this;
for (const key in props) {
const prop = props[key];
if (prop && typeof prop === "object" && targets.has(prop)) {
props[key] = useState(prop);
}
}
props = useState(props);
currentNode = null;
const prom = Promise.all(this.willUpdateProps.map((f) => f.call(component, props)));
await prom;
@@ -245,7 +277,6 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
return;
}
component.props = props;
this.props = rawProps;
fiber.render();
const parentRoot = parentFiber.root!;
if (this.willPatch.length) {
@@ -300,12 +331,8 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
this.fiber = null;
}
moveBeforeDOMNode(node: Node | null, parent?: HTMLElement): void {
this.bdom!.moveBeforeDOMNode(node, parent);
}
moveBeforeVNode(other: ComponentNode<P, E> | null, afterNode: Node | null) {
this.bdom!.moveBeforeVNode(other ? other.bdom : null, afterNode);
moveBefore(other: ComponentNode | null, afterNode: Node | null) {
this.bdom!.moveBefore(other ? other.bdom : null, afterNode);
}
patch() {
@@ -317,16 +344,10 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
}
}
_patch() {
let hasChildren = false;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (let _k in this.children) {
hasChildren = true;
break;
}
const fiber = this.fiber!;
this.children = fiber.childrenMap;
this.bdom!.patch(fiber.bdom!, hasChildren);
fiber.appliedToDom = true;
const hasChildren = Object.keys(this.children).length > 0;
this.children = this.fiber!.childrenMap;
this.bdom!.patch(this!.fiber!.bdom!, hasChildren);
this.fiber!.appliedToDom = true;
this.fiber = null;
}
@@ -1,16 +1,11 @@
import type { ComponentNode } from "./component_node";
import type { Fiber } from "./fibers";
// Custom error class that wraps error that happen in the owl lifecycle
export class OwlError extends Error {
cause?: any;
}
// Maps fibers to thrown errors
export const fibersInError: WeakMap<Fiber, any> = new WeakMap();
export const nodeErrorHandlers: WeakMap<ComponentNode, ((error: any) => void)[]> = new WeakMap();
function _handleError(node: ComponentNode | null, error: any): boolean {
function _handleError(node: ComponentNode | null, error: any, isFirstRound = false): boolean {
if (!node) {
return false;
}
@@ -21,19 +16,23 @@ function _handleError(node: ComponentNode | null, error: any): boolean {
const errorHandlers = nodeErrorHandlers.get(node);
if (errorHandlers) {
let handled = false;
let stopped = false;
// execute in the opposite order
for (let i = errorHandlers.length - 1; i >= 0; i--) {
try {
errorHandlers[i](error);
handled = true;
stopped = true;
break;
} catch (e) {
error = e;
}
}
if (handled) {
if (stopped) {
if (isFirstRound && fiber && fiber.node.fiber) {
const root = fiber.root!;
root.setCounter(root.counter - 1);
}
return true;
}
}
@@ -42,14 +41,7 @@ function _handleError(node: ComponentNode | null, error: any): boolean {
type ErrorParams = { error: any } & ({ node: ComponentNode } | { fiber: Fiber });
export function handleError(params: ErrorParams) {
let { error } = params;
// Wrap error if it wasn't wrapped by wrapError (ie when not in dev mode)
if (!(error instanceof OwlError)) {
error = Object.assign(
new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`),
{ cause: error }
);
}
const error = params.error;
const node = "node" in params ? params.node : params.fiber.node;
const fiber = "fiber" in params ? params.fiber : node.fiber!;
@@ -63,7 +55,7 @@ export function handleError(params: ErrorParams) {
fibersInError.set(fiber.root!, error);
const handled = _handleError(node, error);
const handled = _handleError(node, error, true);
if (!handled) {
console.warn(`[Owl] Unhandled error. Destroying the root component`);
try {
@@ -71,6 +63,5 @@ export function handleError(params: ErrorParams) {
} catch (e) {
console.error(e);
}
throw error;
}
}
@@ -1,6 +1,6 @@
import { BDom, mount } from "./blockdom";
import { BDom, mount } from "../blockdom";
import type { ComponentNode } from "./component_node";
import { fibersInError, OwlError } from "./error_handling";
import { fibersInError, handleError } from "./error_handling";
import { STATUS } from "./status";
export function makeChildFiber(node: ComponentNode, parent: Fiber): Fiber {
@@ -16,15 +16,13 @@ export function makeRootFiber(node: ComponentNode): Fiber {
let current = node.fiber;
if (current) {
let root = current.root!;
// lock root fiber because canceling children fibers may destroy components,
// which means any arbitrary code can be run in onWillDestroy, which may
// trigger new renderings
root.locked = true;
root.setCounter(root.counter + 1 - cancelFibers(current.children));
root.locked = false;
current.children = [];
current.childrenMap = {};
current.bdom = null;
if (current === root) {
root.reachedChildren = new WeakSet();
}
if (fibersInError.has(current)) {
fibersInError.delete(current);
fibersInError.delete(root);
@@ -42,10 +40,6 @@ export function makeRootFiber(node: ComponentNode): Fiber {
return fiber;
}
function throwOnRender() {
throw new OwlError("Attempted to render cancelled fiber");
}
/**
* @returns number of not-yet rendered fibers cancelled
*/
@@ -53,10 +47,8 @@ function cancelFibers(fibers: Fiber[]): number {
let result = 0;
for (let fiber of fibers) {
let node = fiber.node;
fiber.render = throwOnRender;
if (node.status === STATUS.NEW) {
node.destroy();
delete node.parent!.children[node.parentKey!];
}
node.fiber = null;
if (fiber.bdom) {
@@ -107,11 +99,16 @@ export class Fiber {
while (current) {
if (current.fiber) {
let root = current.fiber.root!;
if (root.counter === 0 && prev.parentKey! in current.fiber.childrenMap) {
current = root.node;
} else {
if (root.counter) {
scheduler.delayedRenders.push(this);
return;
} else {
if (!root.reachedChildren.has(prev)) {
// is dead. but we keep the render around just in case
scheduler.delayedRenders.push(this);
return;
}
current = root.node;
}
}
prev = current;
@@ -124,15 +121,17 @@ export class Fiber {
_render() {
const node = this.node;
if (node.status > STATUS.MOUNTED) {
return;
}
const root = this.root;
if (root) {
try {
(this.bdom as any) = true;
this.bdom = node.renderFn();
root.setCounter(root.counter - 1);
} catch (e) {
node.app.handleError({ node, error: e });
handleError({ node, error: e });
}
root.setCounter(root.counter - 1);
}
}
}
@@ -148,6 +147,8 @@ export class RootFiber extends Fiber {
// i.e.: render triggered in onWillUnmount or in willPatch will be delayed
locked: boolean = false;
reachedChildren: WeakSet<ComponentNode> = new WeakSet();
complete() {
const node = this.node;
this.locked = true;
@@ -195,7 +196,7 @@ export class RootFiber extends Fiber {
}
} catch (e) {
this.locked = false;
node.app.handleError({ fiber: current || this, error: e });
handleError({ fiber: current || this, error: e });
}
}
@@ -259,7 +260,7 @@ export class MountFiber extends RootFiber {
}
}
} catch (e) {
this.node.app.handleError({ fiber: current as Fiber, error: e });
handleError({ fiber: current as Fiber, error: e });
}
}
}
@@ -1,6 +1,5 @@
import { filterOutModifiersFromData } from "./blockdom/config";
import { filterOutModifiersFromData } from "../blockdom/config";
import { STATUS } from "./status";
import { OwlError } from "./error_handling";
export const mainEventHandler = (data: any, ev: Event, currentTarget?: EventTarget | null) => {
const { data: _data, modifiers } = filterOutModifiersFromData(data);
@@ -34,7 +33,7 @@ export const mainEventHandler = (data: any, ev: Event, currentTarget?: EventTarg
if (Object.hasOwnProperty.call(data, 0)) {
const handler = data[0];
if (typeof handler !== "function") {
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
throw new Error(`Invalid handler (expected a function, received: '${handler}')`);
}
let node = data[1] ? data[1].__owl__ : null;
if (node ? node.status === STATUS.MOUNTED : true) {
@@ -1,30 +1,21 @@
import { getCurrent } from "./component_node";
import { nodeErrorHandlers, OwlError } from "./error_handling";
import { nodeErrorHandlers } from "./error_handling";
const TIMEOUT = Symbol("timeout");
function wrapError(fn: (...args: any[]) => any, hookName: string) {
const error = new OwlError(`The following error occurred in ${hookName}: `) as Error & {
const error = new Error(`The following error occurred in ${hookName}: `) as Error & {
cause: any;
};
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
const timeoutError = new Error(`${hookName}'s promise hasn't resolved after 3 seconds`);
const node = getCurrent();
return (...args: any[]) => {
const onError = (cause: any) => {
error.cause = cause;
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
} else {
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
}
throw error;
};
try {
const result = fn(...args);
if (result instanceof Promise) {
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
const fiber = node.fiber;
Promise.race([
result.catch(() => {}),
result,
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber) {
@@ -32,11 +23,20 @@ function wrapError(fn: (...args: any[]) => any, hookName: string) {
}
});
}
return result.catch(onError);
return result.catch((cause) => {
error.cause = cause;
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
}
throw error;
});
}
return result;
} catch (cause) {
onError(cause);
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
}
throw error;
}
};
}
+150
View File
@@ -0,0 +1,150 @@
import { ComponentConstructor } from "./component";
/**
* Apply default props (only top level).
*
* Note that this method does modify in place the props
*/
export function applyDefaultProps<P>(props: P, ComponentClass: ComponentConstructor<P>) {
const defaultProps = ComponentClass.defaultProps;
if (defaultProps) {
for (let propName in defaultProps) {
if ((props as any)[propName] === undefined) {
(props as any)[propName] = defaultProps[propName];
}
}
}
}
//------------------------------------------------------------------------------
// Prop validation helper
//------------------------------------------------------------------------------
function getPropDescription(staticProps: any) {
if (staticProps instanceof Array) {
return Object.fromEntries(
staticProps.map((p) => (p.endsWith("?") ? [p.slice(0, -1), false] : [p, true]))
);
}
return staticProps || { "*": true };
}
/**
* Validate the component props (or next props) against the (static) props
* description. This is potentially an expensive operation: it may needs to
* visit recursively the props and all the children to check if they are valid.
* This is why it is only done in 'dev' mode.
*/
export function validateProps<P>(name: string | ComponentConstructor<P>, props: P, parent?: any) {
const ComponentClass =
typeof name !== "string"
? name
: (parent.constructor.components[name] as ComponentConstructor<P> | undefined);
if (!ComponentClass) {
// this is an error, wrong component. We silently return here instead so the
// error is triggered by the usual path ('component' function)
return;
}
applyDefaultProps(props, ComponentClass);
const defaultProps = ComponentClass.defaultProps || {};
let propsDef = getPropDescription(ComponentClass.props);
const allowAdditionalProps = "*" in propsDef;
for (let propName in propsDef) {
if (propName === "*") {
continue;
}
const propDef = propsDef[propName];
let isMandatory = !!propDef;
if (typeof propDef === "object" && "optional" in propDef) {
isMandatory = !propDef.optional;
}
if (isMandatory && propName in defaultProps) {
throw new Error(
`A default value cannot be defined for a mandatory prop (name: '${propName}', component: ${ComponentClass.name})`
);
}
if ((props as any)[propName] === undefined) {
if (isMandatory) {
throw new Error(`Missing props '${propName}' (component '${ComponentClass.name}')`);
} else {
continue;
}
}
let isValid;
try {
isValid = isValidProp((props as any)[propName], propDef);
} catch (e) {
(e as Error).message = `Invalid prop '${propName}' in component ${ComponentClass.name} (${
(e as Error).message
})`;
throw e;
}
if (!isValid) {
throw new Error(`Invalid Prop '${propName}' in component '${ComponentClass.name}'`);
}
}
if (!allowAdditionalProps) {
for (let propName in props) {
if (!(propName in propsDef)) {
throw new Error(`Unknown prop '${propName}' given to component '${ComponentClass.name}'`);
}
}
}
}
/**
* Check if an invidual prop value matches its (static) prop definition
*/
function isValidProp(prop: any, propDef: any): boolean {
if (propDef === true) {
return true;
}
if (typeof propDef === "function") {
// Check if a value is constructed by some Constructor. Note that there is a
// slight abuse of language: we want to consider primitive values as well.
//
// So, even though 1 is not an instance of Number, we want to consider that
// it is valid.
if (typeof prop === "object") {
return prop instanceof propDef;
}
return typeof prop === propDef.name.toLowerCase();
} else if (propDef instanceof Array) {
// If this code is executed, this means that we want to check if a prop
// matches at least one of its descriptor.
let result = false;
for (let i = 0, iLen = propDef.length; i < iLen; i++) {
result = result || isValidProp(prop, propDef[i]);
}
return result;
}
// propsDef is an object
if (propDef.optional && prop === undefined) {
return true;
}
let result = propDef.type ? isValidProp(prop, propDef.type) : true;
if (propDef.validate) {
result = result && propDef.validate(prop);
}
if (propDef.type === Array && propDef.element) {
for (let i = 0, iLen = prop.length; i < iLen; i++) {
result = result && isValidProp(prop[i], propDef.element);
}
}
if (propDef.type === Object && propDef.shape) {
const shape = propDef.shape;
for (let key in shape) {
result = result && isValidProp(prop[key], shape[key]);
}
if (result) {
for (let propName in prop) {
if (!(propName in shape)) {
throw new Error(`unknown prop '${propName}'`);
}
}
}
}
return result;
}
@@ -32,7 +32,7 @@ export class Scheduler {
let renders = this.delayedRenders;
this.delayedRenders = [];
for (let f of renders) {
if (f.root && f.node.status !== STATUS.DESTROYED && f.node.fiber === f) {
if (f.root) {
f.render();
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
import type { Env } from "./app";
import { getCurrent } from "./component_node";
import { onMounted, onPatched, onWillUnmount } from "./lifecycle_hooks";
import type { Env } from "./app/app";
import { getCurrent } from "./component/component_node";
import { onMounted, onPatched, onWillUnmount } from "./component/lifecycle_hooks";
// -----------------------------------------------------------------------------
// useRef
@@ -117,7 +117,7 @@ export function useEffect(effect: Effect, computeDependencies: () => any[] = ()
* `useExternalListener(window, 'click', this._doSomething);`
* */
export function useExternalListener(
target: EventTarget,
target: HTMLElement | typeof window,
eventName: string,
handler: EventListener,
eventParams?: AddEventListenerOptions
+53 -13
View File
@@ -1,16 +1,56 @@
import { TemplateSet } from "./runtime/template_set";
import { compile } from "./compiler";
import {
config,
createBlock,
html,
list,
mount as blockMount,
multi,
patch,
remove,
text,
toggler,
comment,
} from "./blockdom";
import { mainEventHandler } from "./component/handler";
export type { Reactive } from "./reactivity";
export * from "./runtime";
config.shouldNormalizeDom = false;
config.mainEventHandler = mainEventHandler;
TemplateSet.prototype._compileTemplate = function _compileTemplate(
name: string,
template: string | Element
) {
return compile(template, {
name,
dev: this.dev,
translateFn: this.translateFn,
translatableAttributes: this.translatableAttributes,
});
export const blockDom = {
config,
// bdom entry points
mount: blockMount,
patch,
remove,
// bdom block types
list,
multi,
text,
toggler,
createBlock,
html,
comment,
};
export { App, mount } from "./app/app";
export { Component } from "./component/component";
export { useComponent, useState } from "./component/component_node";
export { status } from "./component/status";
export { reactive, markRaw, toRaw } from "./reactivity";
export { useEffect, useEnv, useExternalListener, useRef, useChildSubEnv, useSubEnv } from "./hooks";
export { EventBus, whenReady, loadFile, markup, xml } from "./utils";
export {
onWillStart,
onMounted,
onWillUnmount,
onWillUpdateProps,
onWillPatch,
onPatched,
onWillRender,
onRendered,
onWillDestroy,
onError,
} from "./component/lifecycle_hooks";
export const __info__ = {};
+75
View File
@@ -0,0 +1,75 @@
import { onWillUnmount } from "./component/lifecycle_hooks";
import { xml } from "./utils";
import { BDom, text, VNode } from "./blockdom";
import { Component } from "./component/component";
const VText: any = text("").constructor;
class VPortal extends VText implements Partial<VNode<VPortal>> {
// selector: string;
realBDom: BDom | null;
target: HTMLElement | null = null;
constructor(selector: string, realBDom: BDom) {
super("");
this.selector = selector;
this.realBDom = realBDom;
}
mount(parent: HTMLElement, anchor: ChildNode) {
super.mount(parent, anchor);
this.target = document.querySelector(this.selector) as any;
if (!this.target) {
let el: any = this.el;
while (el && el.parentElement instanceof HTMLElement) {
el = el.parentElement;
}
this.target = el && el.querySelector(this.selector);
if (!this.target) {
throw new Error("invalid portal target");
}
}
this.realBDom!.mount(this.target!, null);
}
beforeRemove() {
this.realBDom!.beforeRemove();
}
remove() {
if (this.realBDom) {
super.remove();
this.realBDom!.remove();
this.realBDom = null;
}
}
patch(other: VPortal) {
super.patch(other);
if (this.realBDom) {
this.realBDom.patch(other.realBDom!, true);
} else {
this.realBDom = other.realBDom;
this.realBDom!.mount(this.target!, null);
}
}
}
export class Portal extends Component {
static template = xml`<t t-slot="default"/>`;
static props = {
target: {
type: String,
},
slots: true,
};
setup() {
const node = this.__owl__;
const renderFn = node.renderFn;
node.renderFn = () => new VPortal(this.props.target, renderFn());
onWillUnmount(() => {
if (node.bdom) {
node.bdom.remove();
}
});
}
}
+53 -60
View File
@@ -1,22 +1,24 @@
import type { Callback } from "./utils";
import { OwlError } from "./error_handling";
import { Callback } from "./utils";
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
export const TARGET = Symbol("Target");
// Escape hatch to prevent reactivity system to turn something into a reactive
const SKIP = Symbol("Skip");
// Special key to subscribe to, to be notified of key creation/deletion
const KEYCHANGES = Symbol("Key changes");
// Used to specify the absence of a callback, can be used as WeakMap key but
// should only be used as a sentinel value and never called.
const NO_CALLBACK = () => {
throw new Error("Called NO_CALLBACK. Owl is broken, please report this to the maintainers.");
};
// The following types only exist to signify places where objects are expected
// to be reactive or not, they provide no type checking benefit over "object"
type Target = object;
type Reactive<T extends Target> = T;
type Collection = Set<any> | Map<any, any> | WeakMap<any, any>;
type CollectionRawType = "Set" | "Map" | "WeakMap";
export type Reactive<T extends Target = Target> = T & {
[TARGET]: any;
};
export type NonReactive<T extends Target = Target> = T & {
[SKIP]: any;
};
const objectToString = Object.prototype.toString;
const objectHasOwnProperty = Object.prototype.hasOwnProperty;
@@ -33,7 +35,7 @@ const COLLECTION_RAWTYPES = new Set(["Set", "Map", "WeakMap"]);
* @returns the raw type of the object
*/
function rawType(obj: any) {
return objectToString.call(toRaw(obj)).slice(8, -1);
return objectToString.call(obj).slice(8, -1);
}
/**
* Checks whether a given value can be made into a reactive object.
@@ -58,16 +60,15 @@ function possiblyReactive(val: any, cb: Callback) {
return canBeMadeReactive(val) ? reactive(val, cb) : val;
}
const skipped = new WeakSet<Target>();
/**
* Mark an object or array so that it is ignored by the reactivity system
*
* @param value the value to mark
* @returns the object itself
*/
export function markRaw<T extends Target>(value: T): T {
skipped.add(value);
return value;
export function markRaw<T extends Target>(value: T): NonReactive<T> {
(value as any)[SKIP] = true;
return value as NonReactive<T>;
}
/**
@@ -76,8 +77,8 @@ export function markRaw<T extends Target>(value: T): T {
* @param value a reactive value
* @returns the underlying value
*/
export function toRaw<T extends Target, U extends Reactive<T>>(value: U | T): T {
return targets.has(value) ? (targets.get(value) as T) : value;
export function toRaw<T extends object>(value: Reactive<T>): T {
return value[TARGET] || value;
}
const targetToKeysToCallbacks = new WeakMap<Target, Map<PropertyKey, Set<Callback>>>();
@@ -91,9 +92,6 @@ const targetToKeysToCallbacks = new WeakMap<Target, Map<PropertyKey, Set<Callbac
* @param callback the function to call when the key changes
*/
function observeTargetKey(target: Target, key: PropertyKey, callback: Callback): void {
if (callback === NO_CALLBACK) {
return;
}
if (!targetToKeysToCallbacks.get(target)) {
targetToKeysToCallbacks.set(target, new Map());
}
@@ -148,11 +146,8 @@ export function clearReactivesForCallback(callback: Callback): void {
if (!observedKeys) {
continue;
}
for (const [key, callbacks] of observedKeys.entries()) {
for (const callbacks of observedKeys.values()) {
callbacks.delete(callback);
if (!callbacks.size) {
observedKeys.delete(key);
}
}
}
targetsToClear.clear();
@@ -162,20 +157,14 @@ export function getSubscriptions(callback: Callback) {
const targets = callbacksToTargets.get(callback) || [];
return [...targets].map((target) => {
const keysToCallbacks = targetToKeysToCallbacks.get(target);
let keys = [];
if (keysToCallbacks) {
for (const [key, cbs] of keysToCallbacks) {
if (cbs.has(callback)) {
keys.push(key);
}
}
}
return { target, keys };
return {
target,
keys: keysToCallbacks ? [...keysToCallbacks.keys()] : [],
};
});
}
// Maps reactive objects to the underlying target
export const targets = new WeakMap<Reactive<Target>, Target>();
const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>();
const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive>>();
/**
* Creates a reactive proxy for an object. Reading data on the reactive object
* subscribes to changes to the data. Writing data on the object will cause the
@@ -190,7 +179,7 @@ const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>()
* Subscriptions:
* + Reading a property on an object will subscribe you to changes in the value
* of that property.
* + Accessing an object's keys (eg with Object.keys or with `for..in`) will
* + Accessing an object keys (eg with Object.keys or with `for..in`) will
* subscribe you to the creation/deletion of keys. Checking the presence of a
* key on the object with 'in' has the same effect.
* - getOwnPropertyDescriptor does not currently subscribe you to the property.
@@ -203,19 +192,22 @@ const reactiveCache = new WeakMap<Target, WeakMap<Callback, Reactive<Target>>>()
* reactive has changed
* @returns a proxy that tracks changes to it
*/
export function reactive<T extends Target>(target: T, callback: Callback = NO_CALLBACK): T {
export function reactive<T extends Target>(
target: T,
callback: Callback = () => {}
): Reactive<T> | NonReactive<T> {
if (!canBeMadeReactive(target)) {
throw new OwlError(`Cannot make the given value reactive`);
throw new Error(`Cannot make the given value reactive`);
}
if (skipped.has(target)) {
return target;
if (SKIP in target) {
return target as NonReactive<T>;
}
if (targets.has(target)) {
// target is reactive, create a reactive on the underlying object instead
return reactive(targets.get(target) as T, callback);
const originalTarget = (target as Reactive)[TARGET];
if (originalTarget) {
return reactive(originalTarget, callback);
}
if (!reactiveCache.has(target)) {
reactiveCache.set(target, new WeakMap());
reactiveCache.set(target, new Map());
}
const reactivesForTarget = reactiveCache.get(target)!;
if (!reactivesForTarget.has(callback)) {
@@ -225,7 +217,6 @@ export function reactive<T extends Target>(target: T, callback: Callback = NO_CA
: basicProxyHandler<T>(callback);
const proxy = new Proxy(target, handler as ProxyHandler<T>) as Reactive<T>;
reactivesForTarget.set(callback, proxy);
targets.set(proxy, target);
}
return reactivesForTarget.get(callback) as Reactive<T>;
}
@@ -237,29 +228,29 @@ export function reactive<T extends Target>(target: T, callback: Callback = NO_CA
*/
function basicProxyHandler<T extends Target>(callback: Callback): ProxyHandler<T> {
return {
get(target, key, receiver) {
get(target: any, key: PropertyKey, proxy: Reactive<T>) {
if (key === TARGET) {
return target;
}
// non-writable non-configurable properties cannot be made reactive
const desc = Object.getOwnPropertyDescriptor(target, key);
if (desc && !desc.writable && !desc.configurable) {
return Reflect.get(target, key, receiver);
return Reflect.get(target, key, proxy);
}
observeTargetKey(target, key, callback);
return possiblyReactive(Reflect.get(target, key, receiver), callback);
return possiblyReactive(Reflect.get(target, key, proxy), callback);
},
set(target, key, value, receiver) {
const hadKey = objectHasOwnProperty.call(target, key);
const originalValue = Reflect.get(target, key, receiver);
const ret = Reflect.set(target, key, value, receiver);
if (!hadKey && objectHasOwnProperty.call(target, key)) {
set(target, key, value, proxy) {
const isNewKey = !objectHasOwnProperty.call(target, key);
const originalValue = Reflect.get(target, key, proxy);
const ret = Reflect.set(target, key, value, proxy);
if (isNewKey) {
notifyReactives(target, KEYCHANGES);
}
// While Array length may trigger the set trap, it's not actually set by this
// method but is updated behind the scenes, and the trap is not called with the
// new value. We disable the "same-value-optimization" for it because of that.
if (
originalValue !== Reflect.get(target, key, receiver) ||
(key === "length" && Array.isArray(target))
) {
if (originalValue !== value || (Array.isArray(target) && key === "length")) {
notifyReactives(target, key);
}
return ret;
@@ -452,8 +443,10 @@ function collectionsProxyHandler<T extends Collection>(
// property is read.
const specialHandlers = rawTypeToFuncHandlers[targetRawType](target, callback);
return Object.assign(basicProxyHandler(callback), {
// FIXME: probably broken when part of prototype chain since we ignore the receiver
get(target: any, key: PropertyKey) {
if (key === TARGET) {
return target;
}
if (objectHasOwnProperty.call(specialHandlers, key)) {
return (specialHandlers as any)[key];
}
-210
View File
@@ -1,210 +0,0 @@
import { Component, ComponentConstructor, Props } from "./component";
import { ComponentNode } from "./component_node";
import { nodeErrorHandlers, OwlError, handleError } from "./error_handling";
import { Fiber, RootFiber, MountOptions } from "./fibers";
import { Scheduler } from "./scheduler";
import { validateProps } from "./template_helpers";
import { TemplateSet, TemplateSetConfig } from "./template_set";
import { validateTarget } from "./utils";
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
export interface Env {
[key: string]: any;
}
export interface AppConfig<P, E> extends TemplateSetConfig {
props?: P;
env?: E;
test?: boolean;
warnIfNoStaticProps?: boolean;
}
let hasBeenLogged = false;
export const DEV_MSG = () => {
const hash = (window as any).owl ? (window as any).owl.__info__.hash : "master";
return `Owl is running in 'dev' mode.
This is not suitable for production use.
See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;
};
declare global {
interface Window {
__OWL_DEVTOOLS__: {
apps: Set<App>;
Fiber: typeof Fiber;
RootFiber: typeof RootFiber;
};
}
}
window.__OWL_DEVTOOLS__ ||= {
apps: new Set<App>(),
Fiber: Fiber,
RootFiber: RootFiber,
};
export class App<
T extends abstract new (...args: any) => any = any,
P extends object = any,
E = any
> extends TemplateSet {
static validateTarget = validateTarget;
Root: ComponentConstructor<P, E>;
props: P;
env: E;
scheduler = new Scheduler();
root: ComponentNode<P, E> | null = null;
warnIfNoStaticProps: boolean;
constructor(Root: ComponentConstructor<P, E>, config: AppConfig<P, E> = {}) {
super(config);
this.Root = Root;
window.__OWL_DEVTOOLS__.apps.add(this);
if (config.test) {
this.dev = true;
}
this.warnIfNoStaticProps = config.warnIfNoStaticProps || false;
if (this.dev && !config.test && !hasBeenLogged) {
console.info(DEV_MSG());
hasBeenLogged = true;
}
const env = config.env || {};
const descrs = Object.getOwnPropertyDescriptors(env);
this.env = Object.freeze(Object.create(Object.getPrototypeOf(env), descrs));
this.props = config.props || ({} as P);
}
mount(target: HTMLElement, options?: MountOptions): Promise<Component<P, E> & InstanceType<T>> {
App.validateTarget(target);
if (this.dev) {
validateProps(this.Root, this.props, { __owl__: { app: this } });
}
const node = this.makeNode(this.Root, this.props);
const prom = this.mountNode(node, target, options);
this.root = node;
return prom;
}
makeNode(Component: ComponentConstructor, props: any): ComponentNode {
return new ComponentNode(Component, props, this, null, null);
}
mountNode(node: ComponentNode, target: HTMLElement, options?: MountOptions) {
const promise: any = new Promise((resolve, reject) => {
let isResolved = false;
// manually set a onMounted callback.
// that way, we are independant from the current node.
node.mounted.push(() => {
resolve(node.component);
isResolved = true;
});
// Manually add the last resort error handler on the node
let handlers = nodeErrorHandlers.get(node);
if (!handlers) {
handlers = [];
nodeErrorHandlers.set(node, handlers);
}
handlers.unshift((e) => {
if (!isResolved) {
reject(e);
}
throw e;
});
});
node.mountComponent(target, options);
return promise;
}
destroy() {
if (this.root) {
this.scheduler.flush();
this.root.destroy();
}
window.__OWL_DEVTOOLS__.apps.delete(this);
}
createComponent<P extends Props>(
name: string | null,
isStatic: boolean,
hasSlotsProp: boolean,
hasDynamicPropList: boolean,
hasNoProp: boolean
) {
const isDynamic = !isStatic;
function _arePropsDifferent(props1: Props, props2: Props): boolean {
for (let k in props1) {
if (props1[k] !== props2[k]) {
return true;
}
}
return hasDynamicPropList && Object.keys(props1).length !== Object.keys(props2).length;
}
const arePropsDifferent = hasSlotsProp
? (_1: any, _2: any) => true
: hasNoProp
? (_1: any, _2: any) => false
: _arePropsDifferent;
const updateAndRender = ComponentNode.prototype.updateAndRender;
const initiateRender = ComponentNode.prototype.initiateRender;
return (props: P, key: string, ctx: ComponentNode, parent: any, C: any) => {
let children = ctx.children;
let node: any = children[key];
if (isDynamic && node && node.component.constructor !== C) {
node = undefined;
}
const parentFiber = ctx.fiber!;
if (node) {
if (arePropsDifferent(node.props, props) || parentFiber.deep || node.forceNextRender) {
node.forceNextRender = false;
updateAndRender.call(node, props, parentFiber);
}
} else {
// new component
if (isStatic) {
const components = parent.constructor.components;
if (!components) {
throw new OwlError(
`Cannot find the definition of component "${name}", missing static components key in parent`
);
}
C = components[name as any];
if (!C) {
throw new OwlError(`Cannot find the definition of component "${name}"`);
} else if (!(C.prototype instanceof Component)) {
throw new OwlError(
`"${name}" is not a Component. It must inherit from the Component class`
);
}
}
node = new ComponentNode(C, props, this, ctx, key);
children[key] = node;
initiateRender.call(node, new Fiber(node, parentFiber));
}
parentFiber.childrenMap[key] = node;
return node;
};
}
handleError(...args: Parameters<typeof handleError>) {
return handleError(...args);
}
}
export async function mount<
T extends abstract new (...args: any) => any = any,
P extends object = any,
E = any
>(
C: T & ComponentConstructor<P, E>,
target: HTMLElement,
config: AppConfig<P, E> & MountOptions = {}
): Promise<Component<P, E> & InstanceType<T>> {
return new App(C, config).mount(target, config);
}
-111
View File
@@ -1,111 +0,0 @@
import { createEventHandler } from "./events";
import type { VNode } from "./index";
type EventsSpec = { [name: string]: number };
type Catcher = (child: VNode, handlers: any[]) => VNode;
export function createCatcher(eventsSpec: EventsSpec): Catcher {
const n = Object.keys(eventsSpec).length;
class VCatcher {
child: VNode;
handlerData: any[];
handlerFns: any[] = [];
parentEl?: HTMLElement | undefined;
afterNode: Text | null = null;
constructor(child: VNode, handlers: any[]) {
this.child = child;
this.handlerData = handlers;
}
mount(parent: HTMLElement, afterNode: Node | null) {
this.parentEl = parent;
this.child.mount(parent, afterNode);
this.afterNode = document.createTextNode("");
parent.insertBefore(this.afterNode, afterNode);
this.wrapHandlerData();
for (let name in eventsSpec) {
const index = eventsSpec[name];
const handler = createEventHandler(name);
this.handlerFns[index] = handler;
handler.setup.call(parent, this.handlerData[index]);
}
}
wrapHandlerData() {
for (let i = 0; i < n; i++) {
let handler = this.handlerData[i];
// handler = [...mods, fn, comp], so we need to replace second to last elem
let idx = handler.length - 2;
let origFn = handler[idx];
const self = this;
handler[idx] = function (ev: any) {
const target = ev.target;
let currentNode: any = self.child.firstNode();
const afterNode = self.afterNode;
while (currentNode && currentNode !== afterNode) {
if (currentNode.contains(target)) {
return origFn.call(this, ev);
}
currentNode = currentNode.nextSibling;
}
};
}
}
moveBeforeDOMNode(node: Node | null, parent = this.parentEl) {
this.parentEl = parent;
this.child.moveBeforeDOMNode(node, parent);
parent!.insertBefore(this.afterNode!, node);
}
moveBeforeVNode(other: VCatcher | null, afterNode: Node | null) {
if (other) {
// check this with @ged-odoo for use in foreach
afterNode = other.firstNode() || afterNode;
}
this.child.moveBeforeVNode(other ? other.child : null, afterNode);
this.parentEl!.insertBefore(this.afterNode!, afterNode);
}
patch(other: VCatcher, withBeforeRemove: boolean) {
if (this === other) {
return;
}
this.handlerData = other.handlerData;
this.wrapHandlerData();
for (let i = 0; i < n; i++) {
this.handlerFns[i].update.call(this.parentEl!, this.handlerData[i]);
}
this.child.patch(other.child, withBeforeRemove);
}
beforeRemove() {
this.child.beforeRemove();
}
remove() {
for (let i = 0; i < n; i++) {
this.handlerFns[i].remove.call(this.parentEl!);
}
this.child.remove();
this.afterNode!.remove();
}
firstNode(): Node | undefined {
return this.child.firstNode();
}
toString(): string {
return this.child.toString();
}
}
return function (child: VNode, handlers: any[]): VNode<VCatcher> {
return new VCatcher(child, handlers);
};
}
-59
View File
@@ -1,59 +0,0 @@
import {
config,
createBlock,
html,
list,
mount as blockMount,
multi,
patch,
remove,
text,
toggler,
comment,
} from "./blockdom";
import { mainEventHandler } from "./event_handling";
config.shouldNormalizeDom = false;
config.mainEventHandler = mainEventHandler;
export const blockDom = {
config,
// bdom entry points
mount: blockMount,
patch,
remove,
// bdom block types
list,
multi,
text,
toggler,
createBlock,
html,
comment,
};
export { App, mount } from "./app";
export { xml } from "./template_set";
export { Component } from "./component";
export type { ComponentConstructor } from "./component";
export { useComponent, useState } from "./component_node";
export { status } from "./status";
export { reactive, markRaw, toRaw } from "./reactivity";
export { useEffect, useEnv, useExternalListener, useRef, useChildSubEnv, useSubEnv } from "./hooks";
export { EventBus, whenReady, loadFile, markup } from "./utils";
export {
onWillStart,
onMounted,
onWillUnmount,
onWillUpdateProps,
onWillPatch,
onPatched,
onWillRender,
onRendered,
onWillDestroy,
onError,
} from "./lifecycle_hooks";
export { validate } from "./validation";
export { OwlError } from "./error_handling";
export const __info__ = {};
-90
View File
@@ -1,90 +0,0 @@
import { onMounted, onWillUnmount } from "./lifecycle_hooks";
import { BDom, text, VNode } from "./blockdom";
import { Component } from "./component";
import { OwlError } from "./error_handling";
const VText: any = text("").constructor;
class VPortal extends VText implements Partial<VNode<VPortal>> {
content: BDom | null;
selector: string;
target: HTMLElement | null = null;
constructor(selector: string, content: BDom) {
super("");
this.selector = selector;
this.content = content;
}
mount(parent: HTMLElement, anchor: ChildNode) {
super.mount(parent, anchor);
this.target = document.querySelector(this.selector) as any;
if (this.target) {
this.content!.mount(this.target!, null);
} else {
this.content!.mount(parent, anchor);
}
}
beforeRemove() {
this.content!.beforeRemove();
}
remove() {
if (this.content) {
super.remove();
this.content!.remove();
this.content = null;
}
}
patch(other: VPortal) {
super.patch(other);
if (this.content) {
this.content.patch(other.content!, true);
} else {
this.content = other.content;
this.content!.mount(this.target!, null);
}
}
}
/**
* kind of similar to <t t-slot="default"/>, but it wraps it around a VPortal
*/
export function portalTemplate(app: any, bdom: any, helpers: any) {
let { callSlot } = helpers;
return function template(ctx: any, node: any, key = ""): any {
return new VPortal(ctx.props.target, callSlot(ctx, node, key, "default", false, null));
};
}
export class Portal extends Component {
static template = "__portal__";
static props = {
target: {
type: String,
},
slots: true,
};
setup() {
const node: any = this.__owl__;
onMounted(() => {
const portal: VPortal = node.bdom;
if (!portal.target) {
const target: HTMLElement = document.querySelector(this.props.target);
if (target) {
portal.content!.moveBeforeDOMNode(target.firstChild, target);
} else {
throw new OwlError("invalid portal target");
}
}
});
onWillUnmount(() => {
const portal: VPortal = node.bdom;
portal.remove();
});
}
}
-283
View File
@@ -1,283 +0,0 @@
import { BDom, multi, text, toggler, createCatcher } from "./blockdom";
import { Markup } from "./utils";
import { html } from "./blockdom/index";
import { isOptional, validateSchema } from "./validation";
import type { ComponentConstructor } from "./component";
import { markRaw } from "./reactivity";
import { OwlError } from "./error_handling";
const ObjectCreate = Object.create;
/**
* This file contains utility functions that will be injected in each template,
* to perform various useful tasks in the compiled code.
*/
function withDefault(value: any, defaultValue: any): any {
return value === undefined || value === null || value === false ? defaultValue : value;
}
function callSlot(
ctx: any,
parent: any,
key: string,
name: string,
dynamic: boolean,
extra: any,
defaultContent?: (ctx: any, node: any, key: string) => BDom
): BDom {
key = key + "__slot_" + name;
const slots = ctx.props.slots || {};
const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = ObjectCreate(__ctx || {});
if (__scope) {
slotScope[__scope] = extra;
}
const slotBDom = __render ? __render(slotScope, parent, key) : null;
if (defaultContent) {
let child1: BDom | undefined = undefined;
let child2: BDom | undefined = undefined;
if (slotBDom) {
child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
} else {
child2 = defaultContent(ctx, parent, key);
}
return multi([child1, child2]);
}
return slotBDom || text("");
}
function capture(ctx: any): any {
const result = ObjectCreate(ctx);
for (let k in ctx) {
result[k] = ctx[k];
}
return result;
}
function withKey(elem: any, k: string) {
elem.key = k;
return elem;
}
function prepareList(collection: any): [any[], any[], number, any[]] {
let keys: any[];
let values: any[];
if (Array.isArray(collection)) {
keys = collection;
values = collection;
} else if (collection) {
values = Object.keys(collection);
keys = Object.values(collection);
} else {
throw new OwlError("Invalid loop expression");
}
const n = values.length;
return [keys, values, n, new Array(n)];
}
const isBoundary = Symbol("isBoundary");
function setContextValue(ctx: { [key: string]: any }, key: string, value: any): void {
const ctx0 = ctx;
while (!ctx.hasOwnProperty(key) && !ctx.hasOwnProperty(isBoundary)) {
const newCtx = ctx.__proto__;
if (!newCtx) {
ctx = ctx0;
break;
}
ctx = newCtx;
}
ctx[key] = value;
}
function toNumber(val: string): number | string {
const n = parseFloat(val);
return isNaN(n) ? val : n;
}
function shallowEqual(l1: any[], l2: any[]): boolean {
for (let i = 0, l = l1.length; i < l; i++) {
if (l1[i] !== l2[i]) {
return false;
}
}
return true;
}
class LazyValue {
fn: any;
ctx: any;
component: any;
node: any;
key: any;
constructor(fn: any, ctx: any, component: any, node: any, key: any) {
this.fn = fn;
this.ctx = capture(ctx);
this.component = component;
this.node = node;
this.key = key;
}
evaluate(): any {
return this.fn.call(this.component, this.ctx, this.node, this.key);
}
toString() {
return this.evaluate().toString();
}
}
/*
* Safely outputs `value` as a block depending on the nature of `value`
*/
export function safeOutput(value: any, defaultValue?: any): ReturnType<typeof toggler> {
if (value === undefined) {
return defaultValue ? toggler("default", defaultValue) : toggler("undefined", text(""));
}
let safeKey;
let block;
switch (typeof value) {
case "object":
if (value instanceof Markup) {
safeKey = `string_safe`;
block = html(value as string);
} else if (value instanceof LazyValue) {
safeKey = `lazy_value`;
block = value.evaluate();
} else if (value instanceof String) {
safeKey = "string_unsafe";
block = text(value);
} else {
// Assuming it is a block
safeKey = "block_safe";
block = value;
}
break;
case "string":
safeKey = "string_unsafe";
block = text(value);
break;
default:
safeKey = "string_unsafe";
block = text(String(value));
}
return toggler(safeKey, block);
}
let boundFunctions = new WeakMap();
const WeakMapGet = WeakMap.prototype.get;
const WeakMapSet = WeakMap.prototype.set;
function bind(component: any, fn: Function): Function {
let boundFnMap = WeakMapGet.call(boundFunctions, component);
if (!boundFnMap) {
boundFnMap = new WeakMap();
WeakMapSet.call(boundFunctions, component, boundFnMap);
}
let boundFn = WeakMapGet.call(boundFnMap, fn);
if (!boundFn) {
boundFn = fn.bind(component);
WeakMapSet.call(boundFnMap, fn, boundFn);
}
return boundFn;
}
type RefMap = { [key: string]: HTMLElement | null };
type RefSetter = (el: HTMLElement | null) => void;
function multiRefSetter(refs: RefMap, name: string): RefSetter {
let count = 0;
return (el) => {
if (el) {
count++;
if (count > 1) {
throw new OwlError("Cannot have 2 elements with same ref name at the same time");
}
}
if (count === 0 || el) {
refs[name] = el;
}
};
}
function singleRefSetter(refs: RefMap, name: string): RefSetter {
let _el: HTMLElement | null = null;
return (el) => {
if (el || refs[name] === _el) {
refs[name] = el;
_el = el;
}
};
}
/**
* Validate the component props (or next props) against the (static) props
* description. This is potentially an expensive operation: it may needs to
* visit recursively the props and all the children to check if they are valid.
* This is why it is only done in 'dev' mode.
*/
export function validateProps<P>(name: string | ComponentConstructor<P>, props: P, comp?: any) {
const ComponentClass =
typeof name !== "string"
? name
: (comp.constructor.components[name] as ComponentConstructor<P> | undefined);
if (!ComponentClass) {
// this is an error, wrong component. We silently return here instead so the
// error is triggered by the usual path ('component' function)
return;
}
const schema = ComponentClass.props;
if (!schema) {
if (comp.__owl__.app.warnIfNoStaticProps) {
console.warn(`Component '${ComponentClass.name}' does not have a static props description`);
}
return;
}
const defaultProps = ComponentClass.defaultProps;
if (defaultProps) {
let isMandatory = (name: string) =>
Array.isArray(schema)
? schema.includes(name)
: name in schema && !("*" in schema) && !isOptional(schema[name]);
for (let p in defaultProps) {
if (isMandatory(p)) {
throw new OwlError(
`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`
);
}
}
}
const errors = validateSchema(props, schema);
if (errors.length) {
throw new OwlError(
`Invalid props for component '${ComponentClass.name}': ` + errors.join(", ")
);
}
}
export const helpers = {
withDefault,
zero: Symbol("zero"),
isBoundary,
callSlot,
capture,
withKey,
prepareList,
setContextValue,
multiRefSetter,
singleRefSetter,
shallowEqual,
toNumber,
validateProps,
LazyValue,
safeOutput,
bind,
createCatcher,
markRaw,
OwlError,
};
-171
View File
@@ -1,171 +0,0 @@
import { OwlError } from "./error_handling";
import { toRaw } from "./reactivity";
type BaseType =
| typeof String
| typeof Boolean
| typeof Number
| typeof Date
| typeof Object
| typeof Array
| true
| "*";
interface TypeInfo {
type?: TypeDescription;
optional?: boolean;
validate?: Function;
shape?: Schema;
element?: TypeDescription;
}
type ValueType = { value: any };
type TypeDescription = BaseType | TypeInfo | ValueType | TypeDescription[];
type SimplifiedSchema = string[];
type NormalizedSchema = { [key: string]: TypeDescription };
export type Schema = SimplifiedSchema | NormalizedSchema;
// -----------------------------------------------------------------------------
// helpers
// -----------------------------------------------------------------------------
const isUnionType = (t: TypeDescription): t is TypeDescription[] => Array.isArray(t);
const isBaseType = (t: TypeDescription): t is BaseType => typeof t !== "object";
const isValueType = (t: TypeDescription): t is ValueType =>
typeof t === "object" && t && "value" in t;
export function isOptional(t: TypeDescription): Boolean {
return typeof t === "object" && "optional" in t ? t.optional || false : false;
}
function describeType(type: BaseType): string {
return type === "*" || type === true ? "value" : type.name.toLowerCase();
}
function describe(info: TypeDescription): string {
if (isBaseType(info)) {
return describeType(info);
} else if (isUnionType(info)) {
return info.map(describe).join(" or ");
} else if (isValueType(info)) {
return String(info.value);
}
if ("element" in info) {
return `list of ${describe({ type: info.element, optional: false })}s`;
}
if ("shape" in (info as TypeInfo)) {
return `object`;
}
return describe(info.type || "*");
}
function toSchema(spec: SimplifiedSchema): NormalizedSchema {
return Object.fromEntries(
spec.map((e) =>
e.endsWith("?") ? [e.slice(0, -1), { optional: true }] : [e, { type: "*", optional: false }]
)
);
}
/**
* Main validate function
*/
export function validate(obj: { [key: string]: any }, spec: Schema) {
let errors = validateSchema(obj, spec);
if (errors.length) {
throw new OwlError("Invalid object: " + errors.join(", "));
}
}
/**
* Helper validate function, to get the list of errors. useful if one want to
* manipulate the errors without parsing an error object
*/
export function validateSchema(obj: { [key: string]: any }, schema: Schema): string[] {
if (Array.isArray(schema)) {
schema = toSchema(schema);
}
obj = toRaw(obj);
let errors = [];
// check if each value in obj has correct shape
for (let key in obj) {
if (key in schema) {
let result = validateType(key, obj[key], schema[key]);
if (result) {
errors.push(result);
}
} else if (!("*" in schema)) {
errors.push(`unknown key '${key}'`);
}
}
// check that all specified keys are defined in obj
for (let key in schema) {
const spec = schema[key];
if (key !== "*" && !isOptional(spec) && !(key in obj)) {
const isObj = typeof spec === "object" && !Array.isArray(spec);
const isAny = spec === "*" || (isObj && "type" in spec ? spec.type === "*" : isObj);
let detail = isAny ? "" : ` (should be a ${describe(spec)})`;
errors.push(`'${key}' is missing${detail}`);
}
}
return errors;
}
function validateBaseType(key: string, value: any, type: BaseType): string | null {
if (typeof type === "function") {
if (typeof value === "object") {
if (!(value instanceof type)) {
return `'${key}' is not a ${describeType(type)}`;
}
} else if (typeof value !== type.name.toLowerCase()) {
return `'${key}' is not a ${describeType(type)}`;
}
}
return null;
}
function validateArrayType(key: string, value: any, descr: TypeDescription): string | null {
if (!Array.isArray(value)) {
return `'${key}' is not a list of ${describe(descr)}s`;
}
for (let i = 0; i < value.length; i++) {
const error = validateType(`${key}[${i}]`, value[i], descr);
if (error) {
return error;
}
}
return null;
}
function validateType(key: string, value: any, descr: TypeDescription): string | null {
if (value === undefined) {
return isOptional(descr) ? null : `'${key}' is undefined (should be a ${describe(descr)})`;
} else if (isBaseType(descr)) {
return validateBaseType(key, value, descr);
} else if (isValueType(descr)) {
return value === descr.value ? null : `'${key}' is not equal to '${descr.value}'`;
} else if (isUnionType(descr)) {
let validDescr = descr.find((p) => !validateType(key, value, p));
return validDescr ? null : `'${key}' is not a ${describe(descr)}`;
}
let result: string | null = null;
if ("element" in descr) {
result = validateArrayType(key, value, descr.element!);
} else if ("shape" in descr && !result) {
if (typeof value !== "object" || Array.isArray(value)) {
result = `'${key}' is not an object`;
} else {
const errors = validateSchema(value, descr.shape!);
if (errors.length) {
result = `'${key}' has not the correct shape (${errors.join(", ")})`;
}
}
}
if ("type" in descr && !result) {
result = validateType(key, value, descr.type!);
}
if ("validate" in descr && !result) {
result = !descr.validate!(value) ? `'${key}' is not valid` : null;
}
return result;
}
+20 -13
View File
@@ -1,4 +1,3 @@
import { OwlError } from "./error_handling";
export type Callback = () => void;
/**
@@ -28,18 +27,12 @@ export function batched(callback: Callback): Callback {
}
export function validateTarget(target: HTMLElement) {
// Get the document and HTMLElement corresponding to the target to allow mounting in iframes
const document = target && target.ownerDocument;
if (document) {
const HTMLElement = document.defaultView!.HTMLElement;
if (target instanceof HTMLElement) {
if (!document.body.contains(target)) {
throw new OwlError("Cannot mount a component on a detached dom node");
}
return;
}
if (!(target instanceof HTMLElement)) {
throw new Error("Cannot mount component: the target is not a valid DOM element");
}
if (!document.body.contains(target)) {
throw new Error("Cannot mount a component on a detached dom node");
}
throw new OwlError("Cannot mount component: the target is not a valid DOM element");
}
export class EventBus extends EventTarget {
@@ -61,7 +54,7 @@ export function whenReady(fn?: any): Promise<void> {
export async function loadFile(url: string): Promise<string> {
const result = await fetch(url);
if (!result.ok) {
throw new OwlError("Error while fetching xml templates");
throw new Error("Error while fetching xml templates");
}
return await result.text();
}
@@ -80,3 +73,17 @@ export class Markup extends String {}
export function markup(value: any) {
return new Markup(value);
}
// -----------------------------------------------------------------------------
// xml tag helper
// -----------------------------------------------------------------------------
export const globalTemplates: { [key: string]: string | Element } = {};
export function xml(...args: Parameters<typeof String.raw>) {
const name = `__template__${xml.nextId++}`;
const value = String.raw(...args);
globalTemplates[name] = value;
return name;
}
xml.nextId = 1;
+47 -58
View File
@@ -47,17 +47,16 @@ exports[`Reactivity: useState concurrent renderings 3`] = `
`;
exports[`Reactivity: useState destroyed component before being mounted is inactive 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
if (ctx['state'].flag) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
}
return block1([], [b2]);
}
@@ -65,9 +64,9 @@ exports[`Reactivity: useState destroyed component before being mounted is inacti
`;
exports[`Reactivity: useState destroyed component before being mounted is inactive 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -79,17 +78,16 @@ exports[`Reactivity: useState destroyed component before being mounted is inacti
`;
exports[`Reactivity: useState destroyed component is inactive 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
if (ctx['state'].flag) {
b2 = comp1({}, key + \`__1\`, node, this, null);
b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
}
return block1([], [b2]);
}
@@ -97,9 +95,9 @@ exports[`Reactivity: useState destroyed component is inactive 1`] = `
`;
exports[`Reactivity: useState destroyed component is inactive 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -111,9 +109,9 @@ exports[`Reactivity: useState destroyed component is inactive 2`] = `
`;
exports[`Reactivity: useState one components can subscribe twice to same context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
@@ -126,15 +124,14 @@ exports[`Reactivity: useState one components can subscribe twice to same context
`;
exports[`Reactivity: useState parent and children subscribed to same context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
let txt1 = ctx['contextObj'].b;
return block1([txt1], [b2]);
}
@@ -142,9 +139,9 @@ exports[`Reactivity: useState parent and children subscribed to same context 1`]
`;
exports[`Reactivity: useState parent and children subscribed to same context 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -219,26 +216,24 @@ exports[`Reactivity: useState several nodes on different level use same context
`;
exports[`Reactivity: useState two components are updated in parallel 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b3 = comp2({}, key + \`__2\`, node, this, null);
const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
const b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]);
}
}"
`;
exports[`Reactivity: useState two components are updated in parallel 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -250,26 +245,24 @@ exports[`Reactivity: useState two components are updated in parallel 2`] = `
`;
exports[`Reactivity: useState two components can subscribe to same context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b3 = comp2({}, key + \`__2\`, node, this, null);
const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
const b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]);
}
}"
`;
exports[`Reactivity: useState two components can subscribe to same context 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -281,26 +274,24 @@ exports[`Reactivity: useState two components can subscribe to same context 2`] =
`;
exports[`Reactivity: useState two independent components on different levels are updated in parallel 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
const comp2 = app.createComponent(\`Parent\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b3 = comp2({}, key + \`__2\`, node, this, null);
const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
const b3 = component(\`Parent\`, {}, key + \`__2\`, node, ctx);
return block1([], [b2, b3]);
}
}"
`;
exports[`Reactivity: useState two independent components on different levels are updated in parallel 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -312,24 +303,23 @@ exports[`Reactivity: useState two independent components on different levels are
`;
exports[`Reactivity: useState two independent components on different levels are updated in parallel 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, true);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = comp1({}, key + \`__1\`, node, this, null);
const b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
return block1([], [b2]);
}
}"
`;
exports[`Reactivity: useState useContext=useState hook is reactive, for one component 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -341,11 +331,10 @@ exports[`Reactivity: useState useContext=useState hook is reactive, for one comp
`;
exports[`Reactivity: useState useless atoms should be deleted 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`Quantity\`, true, false, false, false);
let block1 = createBlock(\`<div><block-child-0/> Total: <block-text-0/> Count: <block-text-1/></div>\`);
@@ -355,7 +344,7 @@ exports[`Reactivity: useState useless atoms should be deleted 1`] = `
for (let i1 = 0; i1 < l_block2; i1++) {
ctx[\`id\`] = v_block2[i1];
const key1 = ctx['id'];
c_block2[i1] = withKey(comp1({id: ctx['id']}, key + \`__1__\${key1}\`, node, this, null), key1);
c_block2[i1] = withKey(component(\`Quantity\`, {id: ctx['id']}, key + \`__1__\${key1}\`, node, ctx), key1);
}
ctx = ctx.__proto__;
const b2 = list(c_block2);
@@ -367,9 +356,9 @@ exports[`Reactivity: useState useless atoms should be deleted 1`] = `
`;
exports[`Reactivity: useState useless atoms should be deleted 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -381,9 +370,9 @@ exports[`Reactivity: useState useless atoms should be deleted 2`] = `
`;
exports[`Reactivity: useState very simple use, with initial value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
+6 -33
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`app App supports env with getters/setters 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/> <block-text-1/></div>\`);
@@ -16,9 +16,9 @@ exports[`app App supports env with getters/setters 1`] = `
`;
exports[`app can configure an app with props 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -29,23 +29,10 @@ exports[`app can configure an app with props 1`] = `
}"
`;
exports[`app can mount app in an iframe 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div class=\\"my-div\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`app destroy remove the widget from the DOM 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div/>\`);
@@ -54,17 +41,3 @@ exports[`app destroy remove the widget from the DOM 1`] = `
}
}"
`;
exports[`app warnIfNoStaticProps works as expected 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['message'];
return block1([txt1]);
}
}"
`;
+2 -37
View File
@@ -1,5 +1,5 @@
import { App, Component, mount, xml } from "../../src";
import { status } from "../../src/runtime/status";
import { App, Component, xml } from "../../src";
import { status } from "../../src/component/status";
import { makeTestFixture, snapshotEverything, nextTick, elem } from "../helpers";
let fixture: HTMLElement;
@@ -59,39 +59,4 @@ describe("app", () => {
await app.mount(fixture);
expect(fixture.innerHTML).toBe("<div>333</div>");
});
test("warnIfNoStaticProps works as expected", async () => {
let originalconsoleWarn = console.warn;
let mockConsoleWarn = jest.fn(() => {});
console.warn = mockConsoleWarn;
class Root extends Component {
static template = xml`<div t-esc="message"/>`;
}
await mount(Root, fixture, { dev: true, props: { messge: "hey" }, warnIfNoStaticProps: true });
console.warn = originalconsoleWarn;
expect(mockConsoleWarn).toBeCalledWith(
"Component 'Root' does not have a static props description"
);
});
test("can mount app in an iframe", async () => {
class SomeComponent extends Component {
static template = xml`<div class="my-div"/>`;
}
const iframe = document.createElement("iframe");
fixture.appendChild(iframe);
const app = new App(SomeComponent);
const iframeDoc = iframe.contentDocument!;
const comp = await app.mount(iframeDoc.body);
const div = iframeDoc.querySelector(".my-div");
expect(div).not.toBe(null);
expect(iframeDoc.contains(div)).toBe(true);
app.destroy();
expect(iframeDoc.contains(div)).toBe(false);
expect(status(comp)).toBe("destroyed");
});
});
+1 -1
View File
@@ -1,4 +1,4 @@
import { createBlock, mount, patch, remove, text } from "../../src/runtime/blockdom";
import { createBlock, mount, patch, remove, text } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { mount, patch, createBlock } from "../../src/runtime/blockdom";
import { mount, patch, createBlock } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { mount, createBlock, multi, config, patch } from "../../src/runtime/blockdom";
import { mount, createBlock, multi, config, patch } from "../../src/blockdom";
// import { defaultHandler, setupMainHandler } from "../../src/bdom/block";
import { makeTestFixture } from "./helpers";
+1 -1
View File
@@ -1,4 +1,4 @@
import { createBlock, mount, patch, remove } from "../../src/runtime/blockdom";
import { createBlock, mount, patch, remove } from "../../src/blockdom";
import { logStep } from "../helpers";
import { makeTestFixture } from "./helpers";
+1 -1
View File
@@ -1,4 +1,4 @@
import { comment, mount } from "../../src/runtime/blockdom";
import { comment, mount } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+2 -2
View File
@@ -1,6 +1,6 @@
import { config, createBlock, createCatcher, mount } from "../../src/runtime/blockdom";
import { config, createBlock, createCatcher, mount } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
import { mainEventHandler } from "../../src/runtime/event_handling";
import { mainEventHandler } from "../../src/component/handler";
//------------------------------------------------------------------------------
// Setup and helpers
+1 -1
View File
@@ -1,4 +1,4 @@
import { html, mount, patch, text } from "../../src/runtime/blockdom";
import { html, mount, patch, text } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -10
View File
@@ -1,13 +1,4 @@
import {
list,
mount,
multi,
patch,
text,
createBlock,
VNode,
withKey,
} from "../../src/runtime/blockdom";
import { list, mount, multi, patch, text, createBlock, VNode, withKey } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { mount, multi, patch, text, createBlock } from "../../src/runtime/blockdom";
import { mount, multi, patch, text, createBlock } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { createBlock, mount } from "../../src/runtime/blockdom";
import { createBlock, mount } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { createBlock, mount, multi, patch } from "../../src/runtime/blockdom";
import { createBlock, mount, multi, patch } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { mount, patch, remove, text } from "../../src/runtime/blockdom";
import { mount, patch, remove, text } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
+1 -1
View File
@@ -1,4 +1,4 @@
import { createBlock, mount, patch, text, toggler } from "../../src/runtime/blockdom";
import { createBlock, mount, patch, text, toggler } from "../../src/blockdom";
import { makeTestFixture } from "./helpers";
//------------------------------------------------------------------------------
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`attributes changing a class with t-att-class (preexisting class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"hoy\\" block-attribute-0=\\"class\\"/>\`);
@@ -15,9 +15,9 @@ exports[`attributes changing a class with t-att-class (preexisting class 1`] = `
`;
exports[`attributes changing a class with t-att-class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -29,9 +29,9 @@ exports[`attributes changing a class with t-att-class 1`] = `
`;
exports[`attributes changing an attribute with t-att- 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"value\\"/>\`);
@@ -43,9 +43,9 @@ exports[`attributes changing an attribute with t-att- 1`] = `
`;
exports[`attributes class and t-att-class should combine together 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\" class=\\"hello\\"/>\`);
@@ -57,9 +57,9 @@ exports[`attributes class and t-att-class should combine together 1`] = `
`;
exports[`attributes class and t-attf-class with ternary operation 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"hello\\" block-attribute-0=\\"class\\"/>\`);
@@ -71,9 +71,9 @@ exports[`attributes class and t-attf-class with ternary operation 1`] = `
`;
exports[`attributes dynamic attribute evaluating to 0 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -85,9 +85,9 @@ exports[`attributes dynamic attribute evaluating to 0 1`] = `
`;
exports[`attributes dynamic attribute falsy variable 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -99,9 +99,9 @@ exports[`attributes dynamic attribute falsy variable 1`] = `
`;
exports[`attributes dynamic attribute with a dash 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"data-action-id\\"/>\`);
@@ -113,9 +113,9 @@ exports[`attributes dynamic attribute with a dash 1`] = `
`;
exports[`attributes dynamic attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -126,24 +126,10 @@ exports[`attributes dynamic attributes 1`] = `
}"
`;
exports[`attributes dynamic attributes with backticks 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = \`bar\`;
return block1([attr1]);
}
}"
`;
exports[`attributes dynamic class attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -155,9 +141,9 @@ exports[`attributes dynamic class attribute 1`] = `
`;
exports[`attributes dynamic class attribute evaluating to 0 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -168,52 +154,10 @@ exports[`attributes dynamic class attribute evaluating to 0 1`] = `
}"
`;
exports[`attributes dynamic class attribute that starts and ends with a space 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = ctx['c'];
return block1([attr1]);
}
}"
`;
exports[`attributes dynamic class attribute which is only a space 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = ctx['c'];
return block1([attr1]);
}
}"
`;
exports[`attributes dynamic class attribute with multiple consecutive spaces 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = ctx['c'];
return block1([attr1]);
}
}"
`;
exports[`attributes dynamic empty class attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -225,9 +169,9 @@ exports[`attributes dynamic empty class attribute 1`] = `
`;
exports[`attributes dynamic formatted attributes with a dash 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"aria-label\\"/>\`);
@@ -239,9 +183,9 @@ exports[`attributes dynamic formatted attributes with a dash 1`] = `
`;
exports[`attributes dynamic undefined class attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -253,9 +197,9 @@ exports[`attributes dynamic undefined class attribute 1`] = `
`;
exports[`attributes dynamic undefined generic attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"thing\\"/>\`);
@@ -267,9 +211,9 @@ exports[`attributes dynamic undefined generic attribute 1`] = `
`;
exports[`attributes fixed variable 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -281,9 +225,9 @@ exports[`attributes fixed variable 1`] = `
`;
exports[`attributes format expression 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -295,9 +239,9 @@ exports[`attributes format expression 1`] = `
`;
exports[`attributes format literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -309,9 +253,9 @@ exports[`attributes format literal 1`] = `
`;
exports[`attributes format multiple 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -323,9 +267,9 @@ exports[`attributes format multiple 1`] = `
`;
exports[`attributes format value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
@@ -337,9 +281,9 @@ exports[`attributes format value 1`] = `
`;
exports[`attributes from object variables set previously 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><span block-attribute-0=\\"class\\"/></div>\`);
@@ -355,9 +299,9 @@ exports[`attributes from object variables set previously 1`] = `
`;
exports[`attributes from variables set previously (no external node) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<span block-attribute-0=\\"class\\"/>\`);
@@ -373,9 +317,9 @@ exports[`attributes from variables set previously (no external node) 1`] = `
`;
exports[`attributes from variables set previously 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><span block-attribute-0=\\"class\\"/></div>\`);
@@ -391,9 +335,9 @@ exports[`attributes from variables set previously 1`] = `
`;
exports[`attributes object 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attributes=\\"0\\"/>\`);
@@ -405,9 +349,9 @@ exports[`attributes object 1`] = `
`;
exports[`attributes static attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"a\\" bar=\\"b\\" baz=\\"c\\"/>\`);
@@ -418,9 +362,9 @@ exports[`attributes static attributes 1`] = `
`;
exports[`attributes static attributes on void elements 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<img src=\\"/test.skip.jpg\\" alt=\\"Test\\"/>\`);
@@ -430,36 +374,10 @@ exports[`attributes static attributes on void elements 1`] = `
}"
`;
exports[`attributes static attributes with backslash or backtick 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"\\\\\\\\a\\" bar=\\"\\\\\\\\n\\" baz=\\"\\\\\`\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`attributes static attributes with backticks 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"\\\\\`bar\\\\\`\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`attributes static attributes with dashes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div aria-label=\\"Close\\"/>\`);
@@ -469,24 +387,10 @@ exports[`attributes static attributes with dashes 1`] = `
}"
`;
exports[`attributes string interpolation, alternate syntax 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = \`b\${ctx['value']}r\`;
return block1([attr1]);
}
}"
`;
exports[`attributes t-att-class and class should combine together 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"hello\\" block-attribute-0=\\"class\\"/>\`);
@@ -498,9 +402,9 @@ exports[`attributes t-att-class and class should combine together 1`] = `
`;
exports[`attributes t-att-class with multiple classes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -512,9 +416,9 @@ exports[`attributes t-att-class with multiple classes 1`] = `
`;
exports[`attributes t-att-class with multiple classes 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -525,24 +429,10 @@ exports[`attributes t-att-class with multiple classes 2`] = `
}"
`;
exports[`attributes t-att-class with multiple classes 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = {'a b c':ctx['value']};
return block1([attr1]);
}
}"
`;
exports[`attributes t-att-class with multiple classes, some of which are duplicate 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -554,9 +444,9 @@ exports[`attributes t-att-class with multiple classes, some of which are duplica
`;
exports[`attributes t-att-class with object 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"static\\" block-attribute-0=\\"class\\"/>\`);
@@ -567,38 +457,10 @@ exports[`attributes t-att-class with object 1`] = `
}"
`;
exports[`attributes t-att-class with object 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = {' a ':ctx['value']};
return block1([attr1]);
}
}"
`;
exports[`attributes t-att-class with object 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = {' ':ctx['value']};
return block1([attr1]);
}
}"
`;
exports[`attributes t-attf-class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -610,9 +472,9 @@ exports[`attributes t-attf-class 1`] = `
`;
exports[`attributes t-attf-class should combine with class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"hello\\" block-attribute-0=\\"class\\"/>\`);
@@ -624,9 +486,9 @@ exports[`attributes t-attf-class should combine with class 1`] = `
`;
exports[`attributes t-attf-class with multiple classes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -638,9 +500,9 @@ exports[`attributes t-attf-class with multiple classes 1`] = `
`;
exports[`attributes t-attf-class with multiple classes separated by multiple spaces 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"/>\`);
@@ -652,9 +514,9 @@ exports[`attributes t-attf-class with multiple classes separated by multiple spa
`;
exports[`attributes tuple literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attributes=\\"0\\"/>\`);
@@ -666,9 +528,9 @@ exports[`attributes tuple literal 1`] = `
`;
exports[`attributes tuple variable 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attributes=\\"0\\"/>\`);
@@ -680,9 +542,9 @@ exports[`attributes tuple variable 1`] = `
`;
exports[`attributes two classes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"a b\\"/>\`);
@@ -693,9 +555,9 @@ exports[`attributes two classes 1`] = `
`;
exports[`attributes two dynamic attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0=\\"foo\\" block-attribute-1=\\"bar\\"/>\`);
@@ -708,9 +570,9 @@ exports[`attributes two dynamic attributes 1`] = `
`;
exports[`attributes updating classes (with obj notation) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"hoy\\" block-attribute-0=\\"class\\"/>\`);
@@ -721,24 +583,10 @@ exports[`attributes updating classes (with obj notation) 1`] = `
}"
`;
exports[`attributes updating property with falsy value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
return block1([attr1]);
}
}"
`;
exports[`attributes various escapes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div foo=\\"&lt;foo\\" block-attribute-0=\\"bar\\" block-attribute-1=\\"baz\\" block-attributes=\\"2\\"/>\`);
@@ -752,9 +600,9 @@ exports[`attributes various escapes 1`] = `
`;
exports[`attributes various escapes 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div> &lt; </div>\`);
@@ -765,107 +613,79 @@ exports[`attributes various escapes 2 1`] = `
`;
exports[`special cases for some specific html attributes/properties input of type checkbox with t-att-indeterminate 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"indeterminate\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['v']);
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input type= checkbox, with t-att-checked 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['flag']);
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input with t-att-value (patching with same value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
let attr1 = ctx['flag'];
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input with t-att-value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<input block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties input, type checkbox, with t-att-checked (patching with same value 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<input type=\\"checkbox\\" block-attribute-0=\\"checked\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new Boolean(ctx['v']);
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties select with t-att-value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<select block-attribute-0=\\"value\\"><option value=\\"potato\\">Potato</option><option value=\\"tomato\\">Tomato</option><option value=\\"onion\\">Onion</option></select>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['value']) || \\"\\");
let attr1 = ctx['value'];
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties textarea with t-att-value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<textarea block-attribute-0=\\"value\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let attr1 = new String((ctx['v']) || \\"\\");
let attr1 = ctx['v'];
return block1([attr1]);
}
}"
`;
exports[`special cases for some specific html attributes/properties various boolean html attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><input type=\\"checkbox\\" checked=\\"checked\\"/><input checked=\\"checked\\"/><div checked=\\"checked\\"/><div selected=\\"selected\\"/><option selected=\\"selected\\" other=\\"1\\"/><input readonly=\\"readonly\\"/><button disabled=\\"disabled\\"/></div>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`comments only a comment 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return comment(\` comment\`);
@@ -12,9 +12,9 @@ exports[`comments only a comment 1`] = `
`;
exports[`comments properly handle comments 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>hello <!-- comment-->owl</div>\`);
@@ -25,9 +25,9 @@ exports[`comments properly handle comments 1`] = `
`;
exports[`comments properly handle comments between t-if/t-else 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span>true</span>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-on can bind event handler 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -15,9 +15,9 @@ exports[`t-on can bind event handler 1`] = `
`;
exports[`t-on can bind handlers with arguments 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -30,9 +30,9 @@ exports[`t-on can bind handlers with arguments 1`] = `
`;
exports[`t-on can bind handlers with empty object 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -45,9 +45,9 @@ exports[`t-on can bind handlers with empty object 1`] = `
`;
exports[`t-on can bind handlers with empty object (with non empty inner string) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -60,9 +60,9 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
`;
exports[`t-on can bind handlers with empty object (with non empty inner string) 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
@@ -87,9 +87,9 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
`;
exports[`t-on can bind handlers with object arguments 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -102,9 +102,9 @@ exports[`t-on can bind handlers with object arguments 1`] = `
`;
exports[`t-on can bind two event handlers 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\" block-handler-1=\\"dblclick\\">Click</button>\`);
@@ -117,9 +117,9 @@ exports[`t-on can bind two event handlers 1`] = `
`;
exports[`t-on handler is bound to proper owner 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -131,9 +131,9 @@ exports[`t-on handler is bound to proper owner 1`] = `
`;
exports[`t-on handler is bound to proper owner, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block2 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -153,10 +153,11 @@ exports[`t-on handler is bound to proper owner, part 2 1`] = `
`;
exports[`t-on handler is bound to proper owner, part 3 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
return callTemplate_1.call(this, ctx, node, key + \`__1\`);
@@ -165,9 +166,9 @@ exports[`t-on handler is bound to proper owner, part 3 1`] = `
`;
exports[`t-on handler is bound to proper owner, part 3 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -179,11 +180,11 @@ exports[`t-on handler is bound to proper owner, part 3 2`] = `
`;
exports[`t-on handler is bound to proper owner, part 4 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -203,9 +204,9 @@ exports[`t-on handler is bound to proper owner, part 4 1`] = `
`;
exports[`t-on handler is bound to proper owner, part 4 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -217,9 +218,9 @@ exports[`t-on handler is bound to proper owner, part 4 2`] = `
`;
exports[`t-on receive event in first argument 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -231,9 +232,9 @@ exports[`t-on receive event in first argument 1`] = `
`;
exports[`t-on t-on modifiers (native listener) basic support for native listener 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"myClass\\" block-handler-0=\\"click\\"><button block-handler-1=\\"click\\">Button</button></div>\`);
@@ -246,9 +247,9 @@ exports[`t-on t-on modifiers (native listener) basic support for native listener
`;
exports[`t-on t-on modifiers (native listener) t-on combined with t-esc 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\"><block-text-1/></button></div>\`);
@@ -261,9 +262,9 @@ exports[`t-on t-on modifiers (native listener) t-on combined with t-esc 1`] = `
`;
exports[`t-on t-on modifiers (native listener) t-on combined with t-out 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\"><block-child-0/></button></div>\`);
@@ -277,9 +278,9 @@ exports[`t-on t-on modifiers (native listener) t-on combined with t-out 1`] = `
`;
exports[`t-on t-on modifiers (native listener) t-on with .capture modifier 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-handler-0=\\"click.capture\\"><button block-handler-1=\\"click\\">Button</button></div>\`);
@@ -292,9 +293,9 @@ exports[`t-on t-on modifiers (native listener) t-on with .capture modifier 1`] =
`;
exports[`t-on t-on modifiers (native listener) t-on with empty handler (only modifiers) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent\\">Button</button></div>\`);
@@ -306,9 +307,9 @@ exports[`t-on t-on modifiers (native listener) t-on with empty handler (only mod
`;
exports[`t-on t-on modifiers (native listener) t-on with prevent and self modifiers (order matters) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent.self\\"><span>Button</span></button></div>\`);
@@ -320,9 +321,9 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent and self modifi
`;
exports[`t-on t-on modifiers (native listener) t-on with prevent and/or stop modifiers 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.prevent\\">Button 1</button><button block-handler-1=\\"click.stop\\">Button 2</button><button block-handler-2=\\"click.prevent.stop\\">Button 3</button></div>\`);
@@ -336,9 +337,9 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent and/or stop mod
`;
exports[`t-on t-on modifiers (native listener) t-on with prevent modifier in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -363,9 +364,9 @@ exports[`t-on t-on modifiers (native listener) t-on with prevent modifier in t-f
`;
exports[`t-on t-on modifiers (native listener) t-on with self and prevent modifiers (order matters) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click.self.prevent\\"><span>Button</span></button></div>\`);
@@ -377,9 +378,9 @@ exports[`t-on t-on modifiers (native listener) t-on with self and prevent modifi
`;
exports[`t-on t-on modifiers (native listener) t-on with self modifier 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><button block-handler-0=\\"click\\"><span>Button</span></button><button block-handler-1=\\"click.self\\"><span>Button</span></button></div>\`);
@@ -392,9 +393,9 @@ exports[`t-on t-on modifiers (native listener) t-on with self modifier 1`] = `
`;
exports[`t-on t-on modifiers (synthetic listener) basic support for synthetic 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div block-handler-0=\\"click.synthetic\\"><button block-handler-1=\\"click.synthetic\\">Button</button></div>\`);
@@ -407,9 +408,9 @@ exports[`t-on t-on modifiers (synthetic listener) basic support for synthetic 1`
`;
exports[`t-on t-on with inline statement (function call) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -422,9 +423,9 @@ exports[`t-on t-on with inline statement (function call) 1`] = `
`;
exports[`t-on t-on with inline statement 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Click</button>\`);
@@ -437,9 +438,9 @@ exports[`t-on t-on with inline statement 1`] = `
`;
exports[`t-on t-on with inline statement, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Toggle</button>\`);
@@ -452,9 +453,9 @@ exports[`t-on t-on with inline statement, part 2 1`] = `
`;
exports[`t-on t-on with inline statement, part 3 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<button block-handler-0=\\"click\\">Toggle</button>\`);
@@ -468,10 +469,11 @@ exports[`t-on t-on with inline statement, part 3 1`] = `
`;
exports[`t-on t-on with t-call 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -483,9 +485,9 @@ exports[`t-on t-on with t-call 1`] = `
`;
exports[`t-on t-on with t-call 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<p block-handler-0=\\"click\\">lucas</p>\`);
@@ -497,10 +499,11 @@ exports[`t-on t-on with t-call 2`] = `
`;
exports[`t-on t-on, with arguments and t-call 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -512,16 +515,15 @@ exports[`t-on t-on, with arguments and t-call 1`] = `
`;
exports[`t-on t-on, with arguments and t-call 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<p block-handler-0=\\"click\\">lucas</p>\`);
return function template(ctx, node, key = \\"\\") {
const v1 = ctx['this'];
const v2 = ctx['value'];
let hdlr1 = [()=>v1.update(v2), ctx];
const v1 = ctx['value'];
let hdlr1 = [()=>this.update(v1), ctx];
return block1([hdlr1]);
}
}"
+31 -34
View File
@@ -1,11 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`misc complex template 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
const comp1 = app.createComponent(\`SlotButton\`, true, false, false, false);
let block1 = createBlock(\`<div block-attribute-0=\\"class\\"><div block-attribute-1=\\"class\\"><div class=\\"batch_header\\"><a block-attribute-2=\\"href\\" block-attribute-3=\\"class\\" title=\\"View Batch\\"><block-text-4/><block-child-0/><i class=\\"arrow fa fa-window-maximize\\"/></a></div><block-child-1/><div class=\\"batch_slots\\"><block-child-2/><block-child-3/></div><div class=\\"batch_commits\\"><block-child-4/></div></div></div>\`);
let block2 = createBlock(\`<i class=\\"fa fa-exclamation-triangle\\"/>\`);
@@ -35,7 +34,7 @@ exports[`misc complex template 1`] = `
for (let i1 = 0; i1 < l_block4; i1++) {
ctx[\`slot\`] = v_block4[i1];
const key1 = ctx['slot'].id;
c_block4[i1] = withKey(comp1({class: ctx['slot_container'],slot: ctx['slot']}, key + \`__1__\${key1}\`, node, this, null), key1);
c_block4[i1] = withKey(component(\`SlotButton\`, {class: ctx['slot_container'], slot: ctx['slot']}, key + \`__1__\${key1}\`, node, ctx), key1);
}
ctx = ctx.__proto__;
b4 = list(c_block4);
@@ -80,15 +79,15 @@ exports[`misc complex template 1`] = `
`;
exports[`misc global 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, zero, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`_callee-uses-foo\`);
const callTemplate_2 = app.getTemplate(\`_callee-uses-foo\`);
const callTemplate_3 = app.getTemplate(\`_callee-uses-foo\`);
const callTemplate_4 = app.getTemplate(\`_callee-asc\`);
const callTemplate_5 = app.getTemplate(\`_callee-asc-toto\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, zero, withKey } = helpers;
const callTemplate_1 = getTemplate(\`_callee-uses-foo\`);
const callTemplate_2 = getTemplate(\`_callee-uses-foo\`);
const callTemplate_3 = getTemplate(\`_callee-uses-foo\`);
const callTemplate_4 = getTemplate(\`_callee-asc\`);
const callTemplate_5 = getTemplate(\`_callee-asc-toto\`);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block4 = createBlock(\`<span><block-text-0/></span>\`);
@@ -132,9 +131,9 @@ exports[`misc global 1`] = `
`;
exports[`misc global 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { withDefault } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -147,9 +146,9 @@ exports[`misc global 2`] = `
`;
exports[`misc global 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<año block-attribute-0=\\"falló\\"><block-child-0/></año>\`);
@@ -163,29 +162,27 @@ exports[`misc global 3`] = `
`;
exports[`misc global 4`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = text(\`toto default\`);
const b2 = safeOutput(ctx['toto'], b3);
const b2 = withDefault(safeOutput(ctx['toto']), b3);
return block1([], [b2]);
}
}"
`;
exports[`misc other complex template 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey, singleRefSetter } = helpers;
const callTemplate_1 = app.getTemplate(\`LOAD_INFOS_TEMPLATE\`);
const comp1 = app.createComponent(\`BundlesList\`, true, false, false, false);
const comp2 = app.createComponent(\`BundlesList\`, true, false, false, false);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`LOAD_INFOS_TEMPLATE\`);
let block1 = createBlock(\`<div><header><nav class=\\"navbar navbar-expand-md navbar-light bg-light\\"><a block-attribute-0=\\"href\\"><b style=\\"color:#777;\\"><block-text-1/></b></a><button type=\\"button\\" class=\\"navbar-toggler\\" data-toggle=\\"collapse\\" data-target=\\"#top_menu_collapse\\"><span class=\\"navbar-toggler-icon\\"/></button><div class=\\"collapse navbar-collapse\\" id=\\"top_menu_collapse\\" aria-expanded=\\"false\\"><ul class=\\"nav navbar-nav ml-auto text-right\\" id=\\"top_menu\\"><block-child-0/><li class=\\"nav-item divider\\"/><block-child-1/></ul><div><div class=\\"input-group input-group-sm\\"><div class=\\"input-group-prepend input-group-sm\\"><button class=\\"btn btn-default fa fa-cog\\" title=\\"Settings\\" block-handler-2=\\"click\\"/><button class=\\"btn btn-default\\" block-handler-3=\\"click\\"> More </button><block-child-2/></div><input class=\\"form-control\\" type=\\"text\\" placeholder=\\"Search\\" aria-label=\\"Search\\" name=\\"search\\" block-attribute-4=\\"value\\" block-handler-5=\\"keyup\\" block-handler-6=\\"change\\" block-ref=\\"7\\"/><div class=\\"input-group-append\\"><button class=\\"btn btn-default fa fa-eraser\\" block-handler-8=\\"click\\"/></div></div></div></div></nav></header><div class=\\"container-fluid\\" block-ref=\\"9\\"><div class=\\"row\\"><!--div class=\\"form-group col-md-6\\">
<h5>Search options</h5>
@@ -217,9 +214,9 @@ exports[`misc other complex template 1`] = `
let block25 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = singleRefSetter(refs, \`search_input\`);
const ref2 = singleRefSetter(refs, \`settings_menu\`);
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`search_input\`] = el;
const ref2 = (el) => refs[\`settings_menu\`] = el;
let b2,b4,b14,b17,b22,b23,b24,b25;
let attr1 = \`/runbot/\${ctx['project'].slug}\`;
let txt1 = ctx['project'].name;
@@ -269,7 +266,7 @@ exports[`misc other complex template 1`] = `
ctx[\`category\`] = v_block15[i1];
const key1 = ctx['category'].id;
let attr6 = ctx['category'].id;
let attr7 = new Boolean(ctx['category'].id==ctx['options'].active_category_id);
let attr7 = ctx['category'].id==ctx['options'].active_category_id;
let txt5 = ctx['category'].name;
c_block15[i1] = withKey(block16([attr6, attr7, txt5]), key1);
}
@@ -277,7 +274,7 @@ exports[`misc other complex template 1`] = `
const b15 = list(c_block15);
b14 = block14([], [b15]);
}
let attr8 = new String((ctx['search'].value) || \\"\\");
let attr8 = ctx['search'].value;
let hdlr4 = [ctx['updateFilter'], ctx];
let hdlr5 = [ctx['updateFilter'], ctx];
let hdlr6 = [ctx['clearSearch'], ctx];
@@ -291,7 +288,7 @@ exports[`misc other complex template 1`] = `
if (!ctx['trigger'].manual&&ctx['trigger'].project_id===ctx['project'].id&&ctx['trigger'].category_id===ctx['options'].active_category_id) {
let attr9 = \`trigger_\${ctx['trigger'].id}\`;
let attr10 = \`trigger_\${ctx['trigger'].id}\`;
let attr11 = new Boolean(ctx['options'].trigger_display[ctx['trigger'].id]);
let attr11 = ctx['options'].trigger_display[ctx['trigger'].id];
let attr12 = ctx['trigger'].id;
let hdlr7 = [ctx['updateTriggerDisplay'], ctx];
let attr13 = \`trigger_\${ctx['trigger'].id}\`;
@@ -319,8 +316,8 @@ exports[`misc other complex template 1`] = `
if (!ctx['project']) {
b24 = block24();
} else {
const b26 = comp1({bundles: ctx['bundles'].sticky,category_custom_views: ctx['category_custom_views'],search: ctx['search']}, key + \`__2\`, node, this, null);
const b27 = comp2({bundles: ctx['bundles'].dev,search: ctx['search']}, key + \`__3\`, node, this, null);
const b26 = component(\`BundlesList\`, {bundles: ctx['bundles'].sticky, category_custom_views: ctx['category_custom_views'], search: ctx['search']}, key + \`__2\`, node, ctx);
const b27 = component(\`BundlesList\`, {bundles: ctx['bundles'].dev, search: ctx['search']}, key + \`__3\`, node, ctx);
b25 = block25([], [b26, b27]);
}
return block1([attr1, txt1, hdlr2, hdlr3, attr8, hdlr4, hdlr5, ref1, hdlr6, ref2], [b2, b4, b14, b17, b22, b23, b24, b25]);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`memory t-foreach does not leak stuff in global scope 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<p><block-child-0/></p>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`simple templates, mostly static can render a table row 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<tr><td>cell</td></tr>\`);
@@ -14,9 +14,9 @@ exports[`simple templates, mostly static can render a table row 1`] = `
`;
exports[`simple templates, mostly static div with a class attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"abc\\">foo</div>\`);
@@ -27,9 +27,9 @@ exports[`simple templates, mostly static div with a class attribute 1`] = `
`;
exports[`simple templates, mostly static div with a class attribute with a quote 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div class=\\"a'bc\\">word</div>\`);
@@ -40,9 +40,9 @@ exports[`simple templates, mostly static div with a class attribute with a quote
`;
exports[`simple templates, mostly static div with a span child node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span>word</span></div>\`);
@@ -53,9 +53,9 @@ exports[`simple templates, mostly static div with a span child node 1`] = `
`;
exports[`simple templates, mostly static div with an arbitrary attribute with a quote 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div abc=\\"a'bc\\">word</div>\`);
@@ -66,9 +66,9 @@ exports[`simple templates, mostly static div with an arbitrary attribute with a
`;
exports[`simple templates, mostly static div with an empty class attribute 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>word</div>\`);
@@ -79,9 +79,9 @@ exports[`simple templates, mostly static div with an empty class attribute 1`] =
`;
exports[`simple templates, mostly static div with content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>foo</div>\`);
@@ -92,9 +92,9 @@ exports[`simple templates, mostly static div with content 1`] = `
`;
exports[`simple templates, mostly static dom node with t-esc 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -106,9 +106,9 @@ exports[`simple templates, mostly static dom node with t-esc 1`] = `
`;
exports[`simple templates, mostly static dom node with t-esc 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -120,9 +120,9 @@ exports[`simple templates, mostly static dom node with t-esc 2`] = `
`;
exports[`simple templates, mostly static dynamic text value 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['text']);
@@ -131,9 +131,9 @@ exports[`simple templates, mostly static dynamic text value 1`] = `
`;
exports[`simple templates, mostly static empty div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div/>\`);
@@ -144,9 +144,9 @@ exports[`simple templates, mostly static empty div 1`] = `
`;
exports[`simple templates, mostly static empty string 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`\`);
@@ -155,9 +155,9 @@ exports[`simple templates, mostly static empty string 1`] = `
`;
exports[`simple templates, mostly static empty string in a template set 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`\`);
@@ -166,9 +166,9 @@ exports[`simple templates, mostly static empty string in a template set 1`] = `
`;
exports[`simple templates, mostly static inline template string in t-esc 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`text\`);
@@ -177,9 +177,9 @@ exports[`simple templates, mostly static inline template string in t-esc 1`] = `
`;
exports[`simple templates, mostly static inline template string with content in t-esc 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -192,9 +192,9 @@ exports[`simple templates, mostly static inline template string with content in
`;
exports[`simple templates, mostly static inline template string with variable in context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`text \${ctx['v']}\`);
@@ -203,9 +203,9 @@ exports[`simple templates, mostly static inline template string with variable in
`;
exports[`simple templates, mostly static multiple root nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<div>foo</div>\`);
let block3 = createBlock(\`<span>hey</span>\`);
@@ -219,9 +219,9 @@ exports[`simple templates, mostly static multiple root nodes 1`] = `
`;
exports[`simple templates, mostly static simple string 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`hello vdom\`);
@@ -230,9 +230,9 @@ exports[`simple templates, mostly static simple string 1`] = `
`;
exports[`simple templates, mostly static simple string in t tag 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`hello vdom\`);
@@ -241,9 +241,9 @@ exports[`simple templates, mostly static simple string in t tag 1`] = `
`;
exports[`simple templates, mostly static static text and dynamic text (no t tag) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`hello \`);
@@ -254,9 +254,9 @@ exports[`simple templates, mostly static static text and dynamic text (no t tag)
`;
exports[`simple templates, mostly static static text and dynamic text 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`hello \`);
@@ -267,9 +267,9 @@ exports[`simple templates, mostly static static text and dynamic text 1`] = `
`;
exports[`simple templates, mostly static t-esc in dom node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -281,9 +281,9 @@ exports[`simple templates, mostly static t-esc in dom node 1`] = `
`;
exports[`simple templates, mostly static t-esc in dom node, variations 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>hello <block-text-0/></div>\`);
@@ -295,9 +295,9 @@ exports[`simple templates, mostly static t-esc in dom node, variations 1`] = `
`;
exports[`simple templates, mostly static t-esc in dom node, variations 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>hello <block-text-0/> world</div>\`);
@@ -309,9 +309,9 @@ exports[`simple templates, mostly static t-esc in dom node, variations 2`] = `
`;
exports[`simple templates, mostly static template with multiple t tag with multiple content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/>Loading<block-text-2/></div>\`);
@@ -325,9 +325,9 @@ exports[`simple templates, mostly static template with multiple t tag with multi
`;
exports[`simple templates, mostly static template with t tag with multiple content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>Loading<block-child-0/></div>\`);
@@ -342,9 +342,9 @@ exports[`simple templates, mostly static template with t tag with multiple conte
`;
exports[`simple templates, mostly static two t-escs next to each other 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['text1']);
@@ -355,9 +355,9 @@ exports[`simple templates, mostly static two t-escs next to each other 1`] = `
`;
exports[`simple templates, mostly static two t-escs next to each other 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['text1']);
@@ -368,9 +368,9 @@ exports[`simple templates, mostly static two t-escs next to each other 2`] = `
`;
exports[`simple templates, mostly static two t-escs next to each other, in a div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
+20 -19
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`properly support svg add proper namespace to g tags 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<g block-ns=\\"http://www.w3.org/2000/svg\\"><circle cx=\\"50\\" cy=\\"50\\" r=\\"4\\" stroke=\\"green\\" stroke-width=\\"1\\" fill=\\"yellow\\"/> </g>\`);
@@ -14,9 +14,9 @@ exports[`properly support svg add proper namespace to g tags 1`] = `
`;
exports[`properly support svg add proper namespace to svg 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\" width=\\"100px\\" height=\\"90px\\"><circle cx=\\"50\\" cy=\\"50\\" r=\\"4\\" stroke=\\"green\\" stroke-width=\\"1\\" fill=\\"yellow\\"/> </svg>\`);
@@ -27,9 +27,9 @@ exports[`properly support svg add proper namespace to svg 1`] = `
`;
exports[`properly support svg namespace to g tags not added if already in svg namespace 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><g/></svg>\`);
@@ -40,9 +40,9 @@ exports[`properly support svg namespace to g tags not added if already in svg na
`;
exports[`properly support svg namespace to svg tags added even if already in svg namespace 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><svg/></svg>\`);
@@ -53,9 +53,9 @@ exports[`properly support svg namespace to svg tags added even if already in svg
`;
exports[`properly support svg svg creates new block if it is within html -- 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><polygon fill=\\"#000000\\" points=\\"0 0 4 4 8 0\\" transform=\\"translate(5 7)\\"/><block-child-0/></svg>\`);
@@ -73,9 +73,9 @@ exports[`properly support svg svg creates new block if it is within html -- 2 1`
`;
exports[`properly support svg svg creates new block if it is within html 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><polygon fill=\\"#000000\\" points=\\"0 0 4 4 8 0\\" transform=\\"translate(5 7)\\"/></svg>\`);
@@ -88,10 +88,11 @@ exports[`properly support svg svg creates new block if it is within html 1`] = `
`;
exports[`properly support svg svg namespace added to sub templates if root tag is path 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`path\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`path\`);
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
@@ -103,9 +104,9 @@ exports[`properly support svg svg namespace added to sub templates if root tag i
`;
exports[`properly support svg svg namespace added to sub templates if root tag is path 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<path block-ns=\\"http://www.w3.org/2000/svg\\"/>\`);
@@ -116,9 +117,9 @@ exports[`properly support svg svg namespace added to sub templates if root tag i
`;
exports[`properly support svg svg namespace added to sub-blocks 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
let block2 = createBlock(\`<path block-ns=\\"http://www.w3.org/2000/svg\\"/>\`);
+178 -315
View File
@@ -1,10 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-call (template calling) basic caller 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`_basic-callee\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`_basic-callee\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -16,9 +17,9 @@ exports[`t-call (template calling) basic caller 1`] = `
`;
exports[`t-call (template calling) basic caller 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span>ok</span>\`);
@@ -29,10 +30,11 @@ exports[`t-call (template calling) basic caller 2`] = `
`;
exports[`t-call (template calling) basic caller, no parent node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`_basic-callee\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`_basic-callee\`);
return function template(ctx, node, key = \\"\\") {
return callTemplate_1.call(this, ctx, node, key + \`__1\`);
@@ -41,9 +43,9 @@ exports[`t-call (template calling) basic caller, no parent node 1`] = `
`;
exports[`t-call (template calling) basic caller, no parent node 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span>ok</span>\`);
@@ -54,11 +56,11 @@ exports[`t-call (template calling) basic caller, no parent node 2`] = `
`;
exports[`t-call (template calling) call with several sub nodes on same line 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span>hey</span>\`);
@@ -79,9 +81,9 @@ exports[`t-call (template calling) call with several sub nodes on same line 1`]
`;
exports[`t-call (template calling) call with several sub nodes on same line 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -94,11 +96,11 @@ exports[`t-call (template calling) call with several sub nodes on same line 2`]
`;
exports[`t-call (template calling) cascading t-call t-out='0' 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`subTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`subTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span>hey</span>\`);
@@ -119,11 +121,11 @@ exports[`t-call (template calling) cascading t-call t-out='0' 1`] = `
`;
exports[`t-call (template calling) cascading t-call t-out='0' 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`subSubTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`subSubTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span>cascade 0</span>\`);
@@ -142,11 +144,11 @@ exports[`t-call (template calling) cascading t-call t-out='0' 2`] = `
`;
exports[`t-call (template calling) cascading t-call t-out='0' 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`finalTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`finalTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span>cascade 1</span>\`);
@@ -165,9 +167,9 @@ exports[`t-call (template calling) cascading t-call t-out='0' 3`] = `
`;
exports[`t-call (template calling) cascading t-call t-out='0' 4`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<div><span>cascade 2</span><block-child-0/></div>\`);
@@ -180,11 +182,11 @@ exports[`t-call (template calling) cascading t-call t-out='0' 4`] = `
`;
exports[`t-call (template calling) cascading t-call t-out='0', without external divs 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`subTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`subTemplate\`);
let block2 = createBlock(\`<span>hey</span>\`);
let block4 = createBlock(\`<span>yay</span>\`);
@@ -203,11 +205,11 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
`;
exports[`t-call (template calling) cascading t-call t-out='0', without external divs 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`subSubTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`subSubTemplate\`);
let block2 = createBlock(\`<span>cascade 0</span>\`);
@@ -224,11 +226,11 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
`;
exports[`t-call (template calling) cascading t-call t-out='0', without external divs 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`finalTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`finalTemplate\`);
let block2 = createBlock(\`<span>cascade 1</span>\`);
@@ -245,9 +247,9 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
`;
exports[`t-call (template calling) cascading t-call t-out='0', without external divs 4`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block2 = createBlock(\`<span>cascade 2</span>\`);
@@ -261,10 +263,10 @@ exports[`t-call (template calling) cascading t-call t-out='0', without external
`;
exports[`t-call (template calling) dynamic t-call 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const call = app.callTemplate.bind(app);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { call } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -277,9 +279,9 @@ exports[`t-call (template calling) dynamic t-call 1`] = `
`;
exports[`t-call (template calling) dynamic t-call 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<foo><block-text-0/></foo>\`);
@@ -291,9 +293,9 @@ exports[`t-call (template calling) dynamic t-call 2`] = `
`;
exports[`t-call (template calling) dynamic t-call 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<bar><block-text-0/></bar>\`);
@@ -305,11 +307,11 @@ exports[`t-call (template calling) dynamic t-call 3`] = `
`;
exports[`t-call (template calling) inherit context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -324,9 +326,9 @@ exports[`t-call (template calling) inherit context 1`] = `
`;
exports[`t-call (template calling) inherit context 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['foo']);
@@ -334,62 +336,12 @@ exports[`t-call (template calling) inherit context 2`] = `
}"
`;
exports[`t-call (template calling) nested t-calls with magic variable 0 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`grandchild\`);
const callTemplate_2 = app.getTemplate(\`child\`);
let block1 = createBlock(\`<p>Some content...</p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
ctx = Object.create(ctx);
ctx[isBoundary] = 1;
const b1 = block1();
ctx[zero] = b1;
const b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
ctx = ctx.__proto__;
ctx[zero] = b2;
return callTemplate_2.call(this, ctx, node, key + \`__2\`);
}
}"
`;
exports[`t-call (template calling) nested t-calls with magic variable 0 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { zero } = helpers;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\`grandchild\`);
const b3 = ctx[zero];
return multi([b2, b3]);
}
}"
`;
exports[`t-call (template calling) nested t-calls with magic variable 0 3`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { zero } = helpers;
return function template(ctx, node, key = \\"\\") {
return ctx[zero];
}
}"
`;
exports[`t-call (template calling) recursive template, part 1 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`recursive\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`recursive\`);
let block1 = createBlock(\`<div><span>hey</span><block-child-0/></div>\`);
@@ -404,11 +356,11 @@ exports[`t-call (template calling) recursive template, part 1 1`] = `
`;
exports[`t-call (template calling) recursive template, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -425,11 +377,11 @@ exports[`t-call (template calling) recursive template, part 2 1`] = `
`;
exports[`t-call (template calling) recursive template, part 2 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/></div>\`);
@@ -459,11 +411,11 @@ exports[`t-call (template calling) recursive template, part 2 2`] = `
`;
exports[`t-call (template calling) recursive template, part 3 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -480,11 +432,11 @@ exports[`t-call (template calling) recursive template, part 3 1`] = `
`;
exports[`t-call (template calling) recursive template, part 3 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/></div>\`);
@@ -514,11 +466,11 @@ exports[`t-call (template calling) recursive template, part 3 2`] = `
`;
exports[`t-call (template calling) recursive template, part 4: with t-set recursive index 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -536,11 +488,11 @@ exports[`t-call (template calling) recursive template, part 4: with t-set recurs
`;
exports[`t-call (template calling) recursive template, part 4: with t-set recursive index 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`nodeTemplate\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`nodeTemplate\`);
let block1 = createBlock(\`<div><p><block-text-0/> <block-text-1/></p><block-child-0/></div>\`);
@@ -572,11 +524,11 @@ exports[`t-call (template calling) recursive template, part 4: with t-set recurs
`;
exports[`t-call (template calling) scoped parameters 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
@@ -595,9 +547,9 @@ exports[`t-call (template calling) scoped parameters 1`] = `
`;
exports[`t-call (template calling) scoped parameters 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(\`ok\`);
@@ -606,11 +558,11 @@ exports[`t-call (template calling) scoped parameters 2`] = `
`;
exports[`t-call (template calling) scoped parameters, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
@@ -630,9 +582,9 @@ exports[`t-call (template calling) scoped parameters, part 2 1`] = `
`;
exports[`t-call (template calling) scoped parameters, part 2 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['foo']);
@@ -641,10 +593,11 @@ exports[`t-call (template calling) scoped parameters, part 2 2`] = `
`;
exports[`t-call (template calling) t-call allowed on a non t node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -656,9 +609,9 @@ exports[`t-call (template calling) t-call allowed on a non t node 1`] = `
`;
exports[`t-call (template calling) t-call allowed on a non t node 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span>ok</span>\`);
@@ -668,42 +621,12 @@ exports[`t-call (template calling) t-call allowed on a non t node 2`] = `
}"
`;
exports[`t-call (template calling) t-call on a div with t-call-context 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let ctx1 = ctx['obj'];
const b2 = callTemplate_1.call(this, ctx1, node, key + \`__1\`);
return block1([], [b2]);
}
}"
`;
exports[`t-call (template calling) t-call on a div with t-call-context 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['value'];
return block1([txt1]);
}
}"
`;
exports[`t-call (template calling) t-call with body content as root of a template 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`antony\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`antony\`);
let block1 = createBlock(\`<p>antony</p>\`);
@@ -718,9 +641,9 @@ exports[`t-call (template calling) t-call with body content as root of a templat
`;
exports[`t-call (template calling) t-call with body content as root of a template 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<foo><block-child-0/></foo>\`);
@@ -733,10 +656,11 @@ exports[`t-call (template calling) t-call with body content as root of a templat
`;
exports[`t-call (template calling) t-call with t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -751,9 +675,9 @@ exports[`t-call (template calling) t-call with t-if 1`] = `
`;
exports[`t-call (template calling) t-call with t-if 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span>ok</span>\`);
@@ -764,11 +688,11 @@ exports[`t-call (template calling) t-call with t-if 2`] = `
`;
exports[`t-call (template calling) t-call with t-set inside and body text content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -785,9 +709,9 @@ exports[`t-call (template calling) t-call with t-set inside and body text conten
`;
exports[`t-call (template calling) t-call with t-set inside and body text content 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<p><block-text-0/></p>\`);
@@ -799,11 +723,11 @@ exports[`t-call (template calling) t-call with t-set inside and body text conten
`;
exports[`t-call (template calling) t-call with t-set inside and outside 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -833,9 +757,9 @@ exports[`t-call (template calling) t-call with t-set inside and outside 1`] = `
`;
exports[`t-call (template calling) t-call with t-set inside and outside 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -847,11 +771,11 @@ exports[`t-call (template calling) t-call with t-set inside and outside 2`] = `
`;
exports[`t-call (template calling) t-call with t-set inside and outside. 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`main\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`main\`);
let block1 = createBlock(\`<p><block-child-0/></p>\`);
@@ -866,11 +790,11 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 1`] =
`;
exports[`t-call (template calling) t-call with t-set inside and outside. 2 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -900,9 +824,9 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 2`] =
`;
exports[`t-call (template calling) t-call with t-set inside and outside. 2 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<span><block-text-0/></span>\`);
@@ -916,12 +840,12 @@ exports[`t-call (template calling) t-call with t-set inside and outside. 2 3`] =
`;
exports[`t-call (template calling) t-call, conditional and t-set in t-call body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`callee1\`);
const callTemplate_2 = app.getTemplate(\`callee2\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`callee1\`);
const callTemplate_2 = getTemplate(\`callee2\`);
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -945,9 +869,9 @@ exports[`t-call (template calling) t-call, conditional and t-set in t-call body
`;
exports[`t-call (template calling) t-call, conditional and t-set in t-call body 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>callee1</div>\`);
@@ -958,9 +882,9 @@ exports[`t-call (template calling) t-call, conditional and t-set in t-call body
`;
exports[`t-call (template calling) t-call, conditional and t-set in t-call body 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>callee2 <block-text-0/></div>\`);
@@ -971,73 +895,12 @@ exports[`t-call (template calling) t-call, conditional and t-set in t-call body
}"
`;
exports[`t-call (template calling) t-call-context 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
let ctx1 = ctx['obj'];
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
}
}"
`;
exports[`t-call (template calling) t-call-context 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['value'];
return block1([txt1]);
}
}"
`;
exports[`t-call (template calling) t-call-context and value in body 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let ctx1 = ctx['obj'];
ctx1 = Object.create(ctx1);
ctx1[isBoundary] = 1;
setContextValue(ctx1, \\"value2\\", ctx['aaron']);
return callTemplate_1.call(this, ctx1, node, key + \`__1\`);
}
}"
`;
exports[`t-call (template calling) t-call-context and value in body 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/><block-text-1/></span>\`);
return function template(ctx, node, key = \\"\\") {
let txt1 = ctx['value1'];
let txt2 = ctx['value2'];
return block1([txt1, txt2]);
}
}"
`;
exports[`t-call (template calling) t-esc inside t-call, with t-set outside 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -1052,9 +915,9 @@ exports[`t-call (template calling) t-esc inside t-call, with t-set outside 1`] =
`;
exports[`t-call (template calling) t-esc inside t-call, with t-set outside 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -1066,11 +929,11 @@ exports[`t-call (template calling) t-esc inside t-call, with t-set outside 2`] =
`;
exports[`t-call (template calling) with unused body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -1083,9 +946,9 @@ exports[`t-call (template calling) with unused body 1`] = `
`;
exports[`t-call (template calling) with unused body 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>ok</div>\`);
@@ -1096,11 +959,11 @@ exports[`t-call (template calling) with unused body 2`] = `
`;
exports[`t-call (template calling) with unused setbody 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -1114,9 +977,9 @@ exports[`t-call (template calling) with unused setbody 1`] = `
`;
exports[`t-call (template calling) with unused setbody 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>ok</div>\`);
@@ -1127,11 +990,11 @@ exports[`t-call (template calling) with unused setbody 2`] = `
`;
exports[`t-call (template calling) with used body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -1144,9 +1007,9 @@ exports[`t-call (template calling) with used body 1`] = `
`;
exports[`t-call (template calling) with used body 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<h1><block-text-0/></h1>\`);
@@ -1159,11 +1022,11 @@ exports[`t-call (template calling) with used body 2`] = `
`;
exports[`t-call (template calling) with used setbody 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -1180,9 +1043,9 @@ exports[`t-call (template calling) with used setbody 1`] = `
`;
exports[`t-call (template calling) with used setbody 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['foo']);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`debugging t-debug 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span>hey</span>\`);
@@ -21,9 +21,9 @@ exports[`debugging t-debug 1`] = `
`;
exports[`debugging t-debug on sub template 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<p>coucou</p>\`);
@@ -35,10 +35,11 @@ exports[`debugging t-debug on sub template 1`] = `
`;
exports[`debugging t-debug on sub template 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -50,9 +51,9 @@ exports[`debugging t-debug on sub template 2`] = `
`;
exports[`debugging t-log 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div/>\`);
+27 -63
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-esc div with falsy values 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><p><block-text-0/></p><p><block-text-1/></p><p><block-text-2/></p><p><block-text-3/></p><p><block-text-4/></p></div>\`);
@@ -19,9 +19,9 @@ exports[`t-esc div with falsy values 1`] = `
`;
exports[`t-esc escaping 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -33,9 +33,9 @@ exports[`t-esc escaping 1`] = `
`;
exports[`t-esc escaping on a node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -47,9 +47,9 @@ exports[`t-esc escaping on a node 1`] = `
`;
exports[`t-esc escaping on a node with a body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { withDefault } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -62,9 +62,9 @@ exports[`t-esc escaping on a node with a body 1`] = `
`;
exports[`t-esc escaping on a node with a body, as a default 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { withDefault } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -77,9 +77,9 @@ exports[`t-esc escaping on a node with a body, as a default 1`] = `
`;
exports[`t-esc falsy values in text nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['v1']);
@@ -97,9 +97,9 @@ exports[`t-esc falsy values in text nodes 1`] = `
`;
exports[`t-esc literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -111,9 +111,9 @@ exports[`t-esc literal 1`] = `
`;
exports[`t-esc t-esc is escaped 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -126,32 +126,7 @@ exports[`t-esc t-esc is escaped 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`var\`] = new LazyValue(value1, ctx, this, node, key);
let txt1 = ctx['var'];
return block1([txt1]);
}
}"
`;
exports[`t-esc t-esc with the 0 number 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['var']);
}
}"
`;
exports[`t-esc t-esc with the 0 number, in a p 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<p><block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
ctx[\`var\`] = new LazyValue(value1, ctx, node);
let txt1 = ctx['var'];
return block1([txt1]);
}
@@ -159,9 +134,9 @@ exports[`t-esc t-esc with the 0 number, in a p 1`] = `
`;
exports[`t-esc t-esc work with spread operator 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -173,11 +148,11 @@ exports[`t-esc t-esc work with spread operator 1`] = `
`;
exports[`t-esc t-esc=0 is escaped 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<p>escaped</p>\`);
@@ -194,9 +169,9 @@ exports[`t-esc t-esc=0 is escaped 1`] = `
`;
exports[`t-esc t-esc=0 is escaped 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -208,21 +183,10 @@ exports[`t-esc t-esc=0 is escaped 2`] = `
}"
`;
exports[`t-esc top level t-esc with undefined 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['var']);
}
}"
`;
exports[`t-esc variable 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-foreach does not pollute the rendering context 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -23,9 +23,9 @@ exports[`t-foreach does not pollute the rendering context 1`] = `
`;
exports[`t-foreach iterate on items (on a element node) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -47,9 +47,9 @@ exports[`t-foreach iterate on items (on a element node) 1`] = `
`;
exports[`t-foreach iterate on items 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -78,9 +78,9 @@ exports[`t-foreach iterate on items 1`] = `
`;
exports[`t-foreach iterate, dict param 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -109,9 +109,9 @@ exports[`t-foreach iterate, dict param 1`] = `
`;
exports[`t-foreach iterate, position 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -145,9 +145,9 @@ exports[`t-foreach iterate, position 1`] = `
`;
exports[`t-foreach simple iteration (in a node) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -167,9 +167,9 @@ exports[`t-foreach simple iteration (in a node) 1`] = `
`;
exports[`t-foreach simple iteration 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -186,9 +186,9 @@ exports[`t-foreach simple iteration 1`] = `
`;
exports[`t-foreach simple iteration with two nodes inside 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block3 = createBlock(\`<span>a<block-text-0/></span>\`);
@@ -212,11 +212,11 @@ exports[`t-foreach simple iteration with two nodes inside 1`] = `
`;
exports[`t-foreach t-call with body in t-foreach in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, isBoundary, withDefault, setContextValue, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span></div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
@@ -265,9 +265,9 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 1`] = `
`;
exports[`t-foreach t-call with body in t-foreach in t-foreach 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
const b2 = text(\` [\`);
@@ -283,11 +283,11 @@ exports[`t-foreach t-call with body in t-foreach in t-foreach 2`] = `
`;
exports[`t-foreach t-call without body in t-foreach in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, getTemplate, withKey } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/><span>[<block-text-0/>][<block-text-1/>][<block-text-2/>]</span></div>\`);
let block6 = createBlock(\`<span><block-text-0/></span>\`);
@@ -330,9 +330,9 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 1`] = `
`;
exports[`t-foreach t-call without body in t-foreach in t-foreach 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -352,9 +352,9 @@ exports[`t-foreach t-call without body in t-foreach in t-foreach 2`] = `
`;
exports[`t-foreach t-foreach in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -386,9 +386,9 @@ exports[`t-foreach t-foreach in t-foreach 1`] = `
`;
exports[`t-foreach t-foreach with t-if inside (no external node) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block3 = createBlock(\`<span><block-text-0/></span>\`);
@@ -412,9 +412,9 @@ exports[`t-foreach t-foreach with t-if inside (no external node) 1`] = `
`;
exports[`t-foreach t-foreach with t-if inside 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -440,9 +440,9 @@ exports[`t-foreach t-foreach with t-if inside 1`] = `
`;
exports[`t-foreach t-key on t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -463,9 +463,9 @@ exports[`t-foreach t-key on t-foreach 1`] = `
`;
exports[`t-foreach throws error if invalid loop expression 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -488,9 +488,9 @@ exports[`t-foreach throws error if invalid loop expression 1`] = `
`;
exports[`t-foreach with t-memo 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
+52 -52
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-if a t-if next to a div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<div>foo</div>\`);
@@ -19,9 +19,9 @@ exports[`t-if a t-if next to a div 1`] = `
`;
exports[`t-if a t-if with two inner nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block3 = createBlock(\`<span>yip</span>\`);
let block4 = createBlock(\`<div>yip</div>\`);
@@ -39,9 +39,9 @@ exports[`t-if a t-if with two inner nodes 1`] = `
`;
exports[`t-if boolean value condition elif (no outside node) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3,b4,b5;
@@ -60,9 +60,9 @@ exports[`t-if boolean value condition elif (no outside node) 1`] = `
`;
exports[`t-if boolean value condition elif 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-2/><block-child-3/></div>\`);
@@ -83,9 +83,9 @@ exports[`t-if boolean value condition elif 1`] = `
`;
exports[`t-if boolean value condition else 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span>begin</span><block-child-0/><block-child-1/><span>end</span></div>\`);
@@ -102,9 +102,9 @@ exports[`t-if boolean value condition else 1`] = `
`;
exports[`t-if boolean value condition false else 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span>begin</span><block-child-0/><block-child-1/><span>end</span></div>\`);
@@ -121,9 +121,9 @@ exports[`t-if boolean value condition false else 1`] = `
`;
exports[`t-if boolean value condition missing 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -138,9 +138,9 @@ exports[`t-if boolean value condition missing 1`] = `
`;
exports[`t-if can use some boolean operators in expressions 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/><block-child-2/><block-child-3/><block-child-4/><block-child-5/><block-child-6/><block-child-7/></div>\`);
@@ -176,9 +176,9 @@ exports[`t-if can use some boolean operators in expressions 1`] = `
`;
exports[`t-if div containing a t-if with two inner nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span>yip</span>\`);
@@ -197,9 +197,9 @@ exports[`t-if div containing a t-if with two inner nodes 1`] = `
`;
exports[`t-if dynamic content after t-if with two children nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-text-0/></div>\`);
let block3 = createBlock(\`<p>1</p>\`);
@@ -219,9 +219,9 @@ exports[`t-if dynamic content after t-if with two children nodes 1`] = `
`;
exports[`t-if just a t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2;
@@ -234,9 +234,9 @@ exports[`t-if just a t-if 1`] = `
`;
exports[`t-if simple t-if/t-else 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -251,9 +251,9 @@ exports[`t-if simple t-if/t-else 1`] = `
`;
exports[`t-if simple t-if/t-else in a div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -270,9 +270,9 @@ exports[`t-if simple t-if/t-else in a div 1`] = `
`;
exports[`t-if t-esc with t-elif 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -289,9 +289,9 @@ exports[`t-if t-esc with t-elif 1`] = `
`;
exports[`t-if t-esc with t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -306,9 +306,9 @@ exports[`t-if t-esc with t-if 1`] = `
`;
exports[`t-if t-if and t-else with two nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block4 = createBlock(\`<span>a</span>\`);
let block5 = createBlock(\`<span>b</span>\`);
@@ -328,9 +328,9 @@ exports[`t-if t-if and t-else with two nodes 1`] = `
`;
exports[`t-if t-if in a div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -345,9 +345,9 @@ exports[`t-if t-if in a div 1`] = `
`;
exports[`t-if t-if in a t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span>1<block-child-0/></span>\`);
@@ -367,9 +367,9 @@ exports[`t-if t-if in a t-if 1`] = `
`;
exports[`t-if t-if with empty content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -383,9 +383,9 @@ exports[`t-if t-if with empty content 1`] = `
`;
exports[`t-if t-if/t-else with more content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -402,9 +402,9 @@ exports[`t-if t-if/t-else with more content 1`] = `
`;
exports[`t-if t-set, then t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -423,9 +423,9 @@ exports[`t-if t-set, then t-if 1`] = `
`;
exports[`t-if t-set, then t-if, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -446,9 +446,9 @@ exports[`t-if t-set, then t-if, part 2 1`] = `
`;
exports[`t-if t-set, then t-if, part 3 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -472,9 +472,9 @@ exports[`t-if t-set, then t-if, part 3 1`] = `
`;
exports[`t-if two consecutive t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
let b2,b3;
@@ -490,9 +490,9 @@ exports[`t-if two consecutive t-if 1`] = `
`;
exports[`t-if two consecutive t-if in a div 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -510,9 +510,9 @@ exports[`t-if two consecutive t-if in a div 1`] = `
`;
exports[`t-if two t-ifs next to each other 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span><block-text-0/></span>\`);
+12 -12
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-key can use t-key directive on a node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -16,9 +16,9 @@ exports[`t-key can use t-key directive on a node 1`] = `
`;
exports[`t-key can use t-key directive on a node 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -31,9 +31,9 @@ exports[`t-key can use t-key directive on a node 2 1`] = `
`;
exports[`t-key can use t-key directive on a node as a function 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -46,9 +46,9 @@ exports[`t-key can use t-key directive on a node as a function 1`] = `
`;
exports[`t-key t-key directive in a list 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
@@ -70,9 +70,9 @@ exports[`t-key t-key directive in a list 1`] = `
`;
exports[`t-key t-key on sub dom node pushes a child block in its parent 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
let block2 = createBlock(\`<span/>\`);
@@ -91,9 +91,9 @@ exports[`t-key t-key on sub dom node pushes a child block in its parent 1`] = `
`;
exports[`t-key t-key on sub dom node pushes a child block in its parent 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><h1/></div>\`);
+68 -122
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-out literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -16,9 +16,9 @@ exports[`t-out literal 1`] = `
`;
exports[`t-out literal, no outside html element 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -28,11 +28,11 @@ exports[`t-out literal, no outside html element 1`] = `
`;
exports[`t-out multiple calls to t-out 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span>coucou</span>\`);
@@ -49,9 +49,9 @@ exports[`t-out multiple calls to t-out 1`] = `
`;
exports[`t-out multiple calls to t-out 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<div><block-child-0/><div>Greeter</div><block-child-1/></div>\`);
@@ -65,9 +65,9 @@ exports[`t-out multiple calls to t-out 2`] = `
`;
exports[`t-out not escaping 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -79,27 +79,12 @@ exports[`t-out not escaping 1`] = `
}"
`;
exports[`t-out number literal 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = safeOutput(1);
return block1([], [b2]);
}
}"
`;
exports[`t-out t-out 0 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, zero } = helpers;
const callTemplate_1 = app.getTemplate(\`_basic-callee\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, zero, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`_basic-callee\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<div>zero</div>\`);
@@ -116,9 +101,9 @@ exports[`t-out t-out 0 1`] = `
`;
exports[`t-out t-out 0 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { zero } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -131,9 +116,9 @@ exports[`t-out t-out 0 2`] = `
`;
exports[`t-out t-out and another sibling node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><span>hello</span><block-child-0/></span>\`);
@@ -146,9 +131,9 @@ exports[`t-out t-out and another sibling node 1`] = `
`;
exports[`t-out t-out bdom 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><span><block-child-0/></span></div>\`);
@@ -161,7 +146,7 @@ exports[`t-out t-out bdom 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`var\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`var\`] = new LazyValue(value1, ctx, node);
const b3 = safeOutput(ctx['var']);
return block1([], [b3]);
}
@@ -169,9 +154,9 @@ exports[`t-out t-out bdom 1`] = `
`;
exports[`t-out t-out block 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -184,9 +169,9 @@ exports[`t-out t-out block 1`] = `
`;
exports[`t-out t-out escaped 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -199,9 +184,9 @@ exports[`t-out t-out escaped 1`] = `
`;
exports[`t-out t-out markedup 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -214,42 +199,42 @@ exports[`t-out t-out markedup 1`] = `
`;
exports[`t-out t-out on a node with a body, as a default 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = text(\`nope\`);
const b2 = safeOutput(ctx['var'], b3);
const b2 = withDefault(safeOutput(ctx['var']), b3);
return block1([], [b2]);
}
}"
`;
exports[`t-out t-out on a node with a dom node in body, as a default 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput, withDefault } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
let block3 = createBlock(\`<div>nope</div>\`);
return function template(ctx, node, key = \\"\\") {
const b3 = block3();
const b2 = safeOutput(ctx['var'], b3);
const b2 = withDefault(safeOutput(ctx['var']), b3);
return block1([], [b2]);
}
}"
`;
exports[`t-out t-out switch escaped 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -262,9 +247,9 @@ exports[`t-out t-out switch escaped 1`] = `
`;
exports[`t-out t-out switch escaped on markup 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -277,9 +262,9 @@ exports[`t-out t-out switch escaped on markup 1`] = `
`;
exports[`t-out t-out switch markup 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -292,9 +277,9 @@ exports[`t-out t-out switch markup 1`] = `
`;
exports[`t-out t-out switch markup on bdom 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/><block-child-1/></div>\`);
@@ -310,7 +295,7 @@ exports[`t-out t-out switch markup on bdom 1`] = `
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b3,b5;
ctx[\`bdom\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`bdom\`] = new LazyValue(value1, ctx, node);
if (ctx['hasBdom']) {
const b4 = safeOutput(ctx['bdom']);
b3 = block3([], [b4]);
@@ -324,9 +309,9 @@ exports[`t-out t-out switch markup on bdom 1`] = `
`;
exports[`t-out t-out switch markup on escaped 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -339,9 +324,9 @@ exports[`t-out t-out switch markup on escaped 1`] = `
`;
exports[`t-out t-out with a <t/> in body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -351,9 +336,9 @@ exports[`t-out t-out with a <t/> in body 1`] = `
`;
exports[`t-out t-out with arbitrary object 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -366,9 +351,9 @@ exports[`t-out t-out with arbitrary object 1`] = `
`;
exports[`t-out t-out with arbitrary object 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -381,9 +366,9 @@ exports[`t-out t-out with arbitrary object 2 1`] = `
`;
exports[`t-out t-out with comment 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -396,48 +381,9 @@ exports[`t-out t-out with comment 1`] = `
`;
exports[`t-out t-out with just a t-set t-value in body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return safeOutput(ctx['var']);
}
}"
`;
exports[`t-out t-out with the 0 number 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return safeOutput(ctx['var']);
}
}"
`;
exports[`t-out t-out with the 0 number, in a p 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
const b2 = safeOutput(ctx['var']);
return block1([], [b2]);
}
}"
`;
exports[`t-out top level t-out with undefined 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -447,9 +393,9 @@ exports[`t-out top level t-out with undefined 1`] = `
`;
exports[`t-out variable 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -462,9 +408,9 @@ exports[`t-out variable 1`] = `
`;
exports[`t-out with a String class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -477,9 +423,9 @@ exports[`t-out with a String class 1`] = `
`;
exports[`t-out with an extended String class 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<span><block-child-0/></span>\`);
@@ -492,9 +438,9 @@ exports[`t-out with an extended String class 1`] = `
`;
exports[`t-raw is deprecated should warn 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -507,9 +453,9 @@ exports[`t-raw is deprecated should warn 1`] = `
`;
exports[`t-raw is deprecated t-out is actually called in t-raw's place 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
+30 -51
View File
@@ -1,60 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-ref can get a dynamic ref on a node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
const v1 = ctx['id'];
let ref1 = singleRefSetter(refs, \`myspan\${v1}\`);
return block1([ref1]);
}
}"
`;
exports[`t-ref can get a dynamic ref on a node, alternate syntax 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const v1 = ctx['id'];
let ref1 = singleRefSetter(refs, \`myspan\${v1}\`);
let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
return block1([ref1]);
}
}"
`;
exports[`t-ref can get a ref on a node 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = singleRefSetter(refs, \`myspan\`);
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`myspan\`] = el;
return block1([ref1]);
}
}"
`;
exports[`t-ref ref in a t-call 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -66,33 +48,31 @@ exports[`t-ref ref in a t-call 1`] = `
`;
exports[`t-ref ref in a t-call 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>1<span block-ref=\\"0\\"/>2</div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = singleRefSetter(refs, \`name\`);
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
return block1([ref1]);
}
}"
`;
exports[`t-ref ref in a t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = singleRefSetter(refs, \`name\`);
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
let b2;
if (ctx['condition']) {
b2 = block2([ref1]);
@@ -103,16 +83,16 @@ exports[`t-ref ref in a t-if 1`] = `
`;
exports[`t-ref refs in a loop 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, singleRefSetter, withKey } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div block-ref=\\"0\\"><block-text-1/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const refs = ctx.__owl__.refs;
ctx = Object.create(ctx);
const [k_block2, v_block2, l_block2, c_block2] = prepareList(ctx['items']);;
for (let i1 = 0; i1 < l_block2; i1++) {
@@ -120,7 +100,7 @@ exports[`t-ref refs in a loop 1`] = `
const key1 = ctx['item'];
const tKey_1 = ctx['item'];
const v1 = ctx['item'];
let ref1 = singleRefSetter(refs, (v1));
let ref1 = (el) => refs[\`\${v1}\`] = el;
let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1);
}
@@ -131,18 +111,17 @@ exports[`t-ref refs in a loop 1`] = `
`;
exports[`t-ref two refs, one in a t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { singleRefSetter } = helpers;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/><p block-ref=\\"0\\"/></div>\`);
let block2 = createBlock(\`<span block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = this.__owl__.refs;
const ref1 = singleRefSetter(refs, \`name\`);
const ref2 = singleRefSetter(refs, \`p\`);
const refs = ctx.__owl__.refs;
const ref1 = (el) => refs[\`name\`] = el;
const ref2 = (el) => refs[\`p\`] = el;
let b2;
if (ctx['condition']) {
b2 = block2([ref1]);
+71 -94
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`t-set evaluate value expression 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -19,9 +19,9 @@ exports[`t-set evaluate value expression 1`] = `
`;
exports[`t-set evaluate value expression, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -37,9 +37,9 @@ exports[`t-set evaluate value expression, part 2 1`] = `
`;
exports[`t-set set from attribute literal (no outside div) 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -52,9 +52,9 @@ exports[`t-set set from attribute literal (no outside div) 1`] = `
`;
exports[`t-set set from attribute literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -70,9 +70,9 @@ exports[`t-set set from attribute literal 1`] = `
`;
exports[`t-set set from attribute lookup 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -88,9 +88,9 @@ exports[`t-set set from attribute lookup 1`] = `
`;
exports[`t-set set from body literal (with t-if/t-else 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
function value1(ctx, node, key = \\"\\") {
@@ -106,16 +106,16 @@ exports[`t-set set from body literal (with t-if/t-else 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`value\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`value\`] = new LazyValue(value1, ctx, node);
return text(ctx['value']);
}
}"
`;
exports[`t-set set from body literal 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -128,9 +128,9 @@ exports[`t-set set from body literal 1`] = `
`;
exports[`t-set set from body lookup 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -142,7 +142,7 @@ exports[`t-set set from body lookup 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`stuff\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`stuff\`] = new LazyValue(value1, ctx, node);
let txt1 = ctx['stuff'];
return block1([txt1]);
}
@@ -150,9 +150,9 @@ exports[`t-set set from body lookup 1`] = `
`;
exports[`t-set set from empty body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -168,9 +168,9 @@ exports[`t-set set from empty body 1`] = `
`;
exports[`t-set t-set and t-if 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -189,9 +189,9 @@ exports[`t-set t-set and t-if 1`] = `
`;
exports[`t-set t-set body is evaluated immediately 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -206,7 +206,7 @@ exports[`t-set t-set body is evaluated immediately 1`] = `
ctx = Object.create(ctx);
ctx[isBoundary] = 1
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`v2\`] = new LazyValue(value1, ctx, node);
setContextValue(ctx, \\"v1\\", 'after');
const b3 = safeOutput(ctx['v2']);
return block1([], [b3]);
@@ -215,11 +215,11 @@ exports[`t-set t-set body is evaluated immediately 1`] = `
`;
exports[`t-set t-set can't alter from within callee 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
@@ -236,9 +236,9 @@ exports[`t-set t-set can't alter from within callee 1`] = `
`;
exports[`t-set t-set can't alter from within callee 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
@@ -255,11 +255,11 @@ exports[`t-set t-set can't alter from within callee 2`] = `
`;
exports[`t-set t-set can't alter in t-call body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
const callTemplate_1 = app.getTemplate(\`sub\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`sub\`);
let block1 = createBlock(\`<div><p><block-text-0/></p><block-child-0/><p><block-text-1/></p></div>\`);
@@ -280,9 +280,9 @@ exports[`t-set t-set can't alter in t-call body 1`] = `
`;
exports[`t-set t-set can't alter in t-call body 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
@@ -299,9 +299,9 @@ exports[`t-set t-set can't alter in t-call body 2`] = `
`;
exports[`t-set t-set does not modify render context existing key values 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -317,9 +317,9 @@ exports[`t-set t-set does not modify render context existing key values 1`] = `
`;
exports[`t-set t-set evaluates an expression only once 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/><block-text-1/></div>\`);
@@ -336,9 +336,9 @@ exports[`t-set t-set evaluates an expression only once 1`] = `
`;
exports[`t-set t-set outside modified in t-foreach 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
@@ -366,9 +366,9 @@ exports[`t-set t-set outside modified in t-foreach 1`] = `
`;
exports[`t-set t-set outside modified in t-foreach increment-after operator 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
@@ -396,9 +396,9 @@ exports[`t-set t-set outside modified in t-foreach increment-after operator 1`]
`;
exports[`t-set t-set outside modified in t-foreach increment-before operator 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/><p>EndLoop: <block-text-0/></p></div>\`);
@@ -426,9 +426,9 @@ exports[`t-set t-set outside modified in t-foreach increment-before operator 1`]
`;
exports[`t-set t-set should reuse variable if possible 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -455,9 +455,9 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
`;
exports[`t-set t-set with content and sub t-esc 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -471,7 +471,7 @@ exports[`t-set t-set with content and sub t-esc 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`setvar\`] = new LazyValue(value1, ctx, this, node, key);
ctx[\`setvar\`] = new LazyValue(value1, ctx, node);
let txt1 = ctx['setvar'];
return block1([txt1]);
}
@@ -479,9 +479,9 @@ exports[`t-set t-set with content and sub t-esc 1`] = `
`;
exports[`t-set t-set with t-value (falsy) and body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -497,7 +497,7 @@ exports[`t-set t-set with t-value (falsy) and body 1`] = `
ctx[isBoundary] = 1
setContextValue(ctx, \\"v3\\", false);
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node, key));
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", true);
const b3 = safeOutput(ctx['v2']);
@@ -507,9 +507,9 @@ exports[`t-set t-set with t-value (falsy) and body 1`] = `
`;
exports[`t-set t-set with t-value (truthy) and body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue, LazyValue, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -525,7 +525,7 @@ exports[`t-set t-set with t-value (truthy) and body 1`] = `
ctx[isBoundary] = 1
setContextValue(ctx, \\"v3\\", 'Truthy');
setContextValue(ctx, \\"v1\\", 'before');
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, this, node, key));
ctx[\`v2\`] = withDefault(ctx['v3'], new LazyValue(value1, ctx, node));
setContextValue(ctx, \\"v1\\", 'after');
setContextValue(ctx, \\"v3\\", false);
const b3 = safeOutput(ctx['v2']);
@@ -534,36 +534,13 @@ exports[`t-set t-set with t-value (truthy) and body 1`] = `
}"
`;
exports[`t-set t-set, multiple t-ifs, and a specific configuration 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<p><div><span>First div</span></div><div><block-child-0/></div></p>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
let b2;
if (ctx['flag']) {
setContextValue(ctx, \\"bouh\\", 2);
}
if (!ctx['flag']) {
b2 = text(\`Second\`);
}
return block1([], [b2]);
}
}"
`;
exports[`t-set t-set, t-if, and mix of expression/body lookup, 1 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block1 = createBlock(\`<div><block-child-0/><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -580,12 +557,12 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 1 1`] = `
`;
exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
let block1 = createBlock(\`<div><block-child-0/><block-child-0/><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
@@ -602,9 +579,9 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 2 1`] = `
`;
exports[`t-set t-set, t-if, and mix of expression/body lookup, 3 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
return function template(ctx, node, key = \\"\\") {
@@ -623,9 +600,9 @@ exports[`t-set t-set, t-if, and mix of expression/body lookup, 3 1`] = `
`;
exports[`t-set value priority (with non text body 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, LazyValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -638,7 +615,7 @@ exports[`t-set value priority (with non text body 1`] = `
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
ctx[isBoundary] = 1
ctx[\`value\`] = withDefault(1, new LazyValue(value1, ctx, this, node, key));
ctx[\`value\`] = withDefault(1, new LazyValue(value1, ctx, node));
let txt1 = ctx['value'];
return block1([txt1]);
}
@@ -646,9 +623,9 @@ exports[`t-set value priority (with non text body 1`] = `
`;
exports[`t-set value priority 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { isBoundary, withDefault, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
+16 -16
View File
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`qweb t-tag can fallback if falsy tag 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 'fallback'}/>\`);
@@ -15,9 +15,9 @@ exports[`qweb t-tag can fallback if falsy tag 1`] = `
`;
exports[`qweb t-tag can update 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}/>\`);
@@ -29,9 +29,9 @@ exports[`qweb t-tag can update 1`] = `
`;
exports[`qweb t-tag simple usecases 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}/>\`);
@@ -43,9 +43,9 @@ exports[`qweb t-tag simple usecases 1`] = `
`;
exports[`qweb t-tag simple usecases 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}>text</\${tag || 't'}>\`);
@@ -57,9 +57,9 @@ exports[`qweb t-tag simple usecases 2`] = `
`;
exports[`qweb t-tag with multiple attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'} class=\\"blueberry\\" taste=\\"raspberry\\">gooseberry</\${tag || 't'}>\`);
@@ -71,9 +71,9 @@ exports[`qweb t-tag with multiple attributes 1`] = `
`;
exports[`qweb t-tag with multiple child nodes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}> pear <span>apple</span> strawberry </\${tag || 't'}>\`);
@@ -85,9 +85,9 @@ exports[`qweb t-tag with multiple child nodes 1`] = `
`;
exports[`qweb t-tag with multiple t-tag in same template 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = tag => createBlock(\`<\${tag || 't'}><block-child-0/></\${tag || 't'}>\`);
let block2 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`);
@@ -102,9 +102,9 @@ exports[`qweb t-tag with multiple t-tag in same template 1`] = `
`;
exports[`qweb t-tag with multiple t-tag in same template, part 2 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = tag => createBlock(\`<\${tag || 't'}>bar</\${tag || 't'}>\`);
let block3 = tag => createBlock(\`<\${tag || 't'}>baz</\${tag || 't'}>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`loading templates addTemplates does not modify its xml document in place 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
@@ -15,9 +15,9 @@ exports[`loading templates addTemplates does not modify its xml document in plac
`;
exports[`loading templates can initialize qweb with a string 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>jupiler</div>\`);
@@ -28,9 +28,9 @@ exports[`loading templates can initialize qweb with a string 1`] = `
`;
exports[`loading templates can initialize qweb with an XMLDocument 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>jupiler</div>\`);
@@ -41,10 +41,11 @@ exports[`loading templates can initialize qweb with an XMLDocument 1`] = `
`;
exports[`loading templates can load a few templates from a xml string 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`items\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`items\`);
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
@@ -56,9 +57,9 @@ exports[`loading templates can load a few templates from a xml string 1`] = `
`;
exports[`loading templates can load a few templates from a xml string 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<li>ok</li>\`);
let block3 = createBlock(\`<li>foo</li>\`);
@@ -72,10 +73,11 @@ exports[`loading templates can load a few templates from a xml string 2`] = `
`;
exports[`loading templates can load a few templates from an XMLDocument 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const callTemplate_1 = app.getTemplate(\`items\`);
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { getTemplate } = helpers;
const callTemplate_1 = getTemplate(\`items\`);
let block1 = createBlock(\`<ul><block-child-0/></ul>\`);
@@ -87,9 +89,9 @@ exports[`loading templates can load a few templates from an XMLDocument 1`] = `
`;
exports[`loading templates can load a few templates from an XMLDocument 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<li>ok</li>\`);
let block3 = createBlock(\`<li>foo</li>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`translation support can set and remove translatable attributes 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div tomato=\\"word\\" potato=\\"mot\\" title=\\"mot\\" label=\\"word\\">text</div>\`);
@@ -14,9 +14,9 @@ exports[`translation support can set and remove translatable attributes 1`] = `
`;
exports[`translation support can translate node content 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>mot</div>\`);
@@ -27,9 +27,9 @@ exports[`translation support can translate node content 1`] = `
`;
exports[`translation support does not translate node content if disabled 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span>mot</span><span>word</span></div>\`);
@@ -40,9 +40,9 @@ exports[`translation support does not translate node content if disabled 1`] = `
`;
exports[`translation support some attributes are translated 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><p label=\\"mot\\">mot</p><p title=\\"mot\\">mot</p><p placeholder=\\"mot\\">mot</p><p alt=\\"mot\\">mot</p><p something=\\"word\\">mot</p></div>\`);
@@ -53,9 +53,9 @@ exports[`translation support some attributes are translated 1`] = `
`;
exports[`translation support translation is done on the trimmed text, with extra spaces readded after 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div> mot </div>\`);
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`white space handling consecutives whitespaces are condensed into a single space 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div> abc </div>\`);
@@ -14,9 +14,9 @@ exports[`white space handling consecutives whitespaces are condensed into a sing
`;
exports[`white space handling nothing is done in pre tags 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<pre> </pre>\`);
@@ -27,9 +27,9 @@ exports[`white space handling nothing is done in pre tags 1`] = `
`;
exports[`white space handling nothing is done in pre tags 2`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<pre>
some text
@@ -42,9 +42,9 @@ exports[`white space handling nothing is done in pre tags 2`] = `
`;
exports[`white space handling nothing is done in pre tags 3`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<pre>
@@ -57,9 +57,9 @@ exports[`white space handling nothing is done in pre tags 3`] = `
`;
exports[`white space handling pre inside a div with a new line 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><pre>SomeText</pre></div>\`);
@@ -70,9 +70,9 @@ exports[`white space handling pre inside a div with a new line 1`] = `
`;
exports[`white space handling white space only text nodes are condensed into a single space 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div> </div>\`);
@@ -83,9 +83,9 @@ exports[`white space handling white space only text nodes are condensed into a s
`;
exports[`white space handling whitespace only text nodes with newlines are removed 1`] = `
"function anonymous(app, bdom, helpers
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span>abc</span></div>\`);
+1 -119
View File
@@ -1,4 +1,4 @@
import { mount, patch } from "../../src/runtime/blockdom";
import { mount, patch } from "../../src/blockdom";
import { makeTestFixture, renderToBdom, renderToString, snapshotEverything } from "../helpers";
snapshotEverything();
@@ -12,11 +12,6 @@ describe("attributes", () => {
expect(renderToString(template)).toBe(`<div foo="a" bar="b" baz="c"></div>`);
});
test("static attributes with backslash or backtick", () => {
const template = `<div foo="\\a" bar="\\n" baz="\`"/>`;
expect(renderToString(template)).toBe(`<div foo="\\a" bar="\\n" baz="\`"></div>`);
});
test("two classes", () => {
const template = `<div class="a b"/>`;
expect(renderToString(template)).toBe(`<div class="a b"></div>`);
@@ -27,12 +22,6 @@ describe("attributes", () => {
expect(renderToString(template)).toBe(`<div aria-label="Close"></div>`);
});
test("static attributes with backticks", () => {
const template = '<div foo="`bar`"></div>';
const result = renderToString(template);
expect(result).toBe('<div foo="`bar`"></div>');
});
test("static attributes on void elements", () => {
const template = `<img src="/test.skip.jpg" alt="Test"/>`;
expect(renderToString(template)).toBe(`<img src="/test.skip.jpg" alt="Test">`);
@@ -44,12 +33,6 @@ describe("attributes", () => {
expect(result).toBe(`<div foo="bar"></div>`);
});
test("dynamic attributes with backticks", () => {
const template = '<div t-att-foo="`bar`"/>';
const result = renderToString(template);
expect(result).toBe(`<div foo="bar"></div>`);
});
test("two dynamic attributes", () => {
const template = `<div t-att-foo="'bar'" t-att-bar="'foo'"/>`;
const result = renderToString(template);
@@ -68,24 +51,6 @@ describe("attributes", () => {
expect(result).toBe(`<div></div>`);
});
test("dynamic class attribute which is only a space", () => {
const template = `<div t-att-class="c"/>`;
const result = renderToString(template, { c: " " });
expect(result).toBe(`<div></div>`);
});
test("dynamic class attribute with multiple consecutive spaces", () => {
const template = `<div t-att-class="c"/>`;
const result = renderToString(template, { c: "a b" });
expect(result).toBe(`<div class="a b"></div>`);
});
test("dynamic class attribute that starts and ends with a space", () => {
const template = `<div t-att-class="c"/>`;
const result = renderToString(template, { c: " a " });
expect(result).toBe(`<div class="a"></div>`);
});
test("dynamic undefined generic attribute", () => {
const template = `<div t-att-thing="c"/>`;
const result = renderToString(template, { c: undefined });
@@ -166,12 +131,6 @@ describe("attributes", () => {
expect(result).toBe(`<div foo="bar"></div>`);
});
test("string interpolation, alternate syntax", () => {
const template = `<div t-attf-foo="b#{value}r"/>`;
const result = renderToString(template, { value: "a" });
expect(result).toBe(`<div foo="bar"></div>`);
});
test("t-attf-class", () => {
const template = `<div t-attf-class="hello"/>`;
const result = renderToString(template);
@@ -283,14 +242,6 @@ describe("attributes", () => {
const template = `<div class="static" t-att-class="{a: b, c: d, e: f}"/>`;
const result = renderToString(template, { b: true, d: false, f: true });
expect(result).toBe(`<div class="static a e"></div>`);
// leading and trailing space in the key
expect(renderToString(`<div t-att-class="{' a ': value}" />`, { value: true })).toBe(
'<div class="a"></div>'
);
// whitespace only key
expect(renderToString(`<div t-att-class="{' ': value}" />`, { value: true })).toBe(
"<div></div>"
);
});
test("t-att-class with multiple classes", () => {
@@ -300,10 +251,6 @@ describe("attributes", () => {
expect(renderToString(`<div t-att-class="{['a b c']: value}" />`, { value: true })).toBe(
'<div class="a b c"></div>'
);
// multiple spaces between classes
expect(renderToString(`<div t-att-class="{'a b c': value}" />`, { value: true })).toBe(
'<div class="a b c"></div>'
);
});
test("t-att-class with multiple classes, some of which are duplicate", () => {
@@ -334,35 +281,6 @@ describe("attributes", () => {
expect(fixture.innerHTML).toBe('<div value=""></div>');
});
test("updating property with falsy value", async () => {
// render input with initial value
const template = `<input t-att-value="v"></input>`;
const bnode1 = renderToBdom(template, { v: false });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: false }));
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: undefined }));
expect(input.value).toBe("");
patch(bnode1, renderToBdom(template, { v: "owl" }));
expect(input.value).toBe("owl");
patch(bnode1, renderToBdom(template, { v: null }));
expect(input.value).toBe("");
});
test("changing a class with t-att-class", () => {
// render input with initial value
const template = `<div t-att-class="v"/>`;
@@ -463,42 +381,6 @@ describe("special cases for some specific html attributes/properties", () => {
expect(input.value).toBe("potato");
});
test("input with t-att-value (patching with same value", () => {
// render input with initial value
const template = `<input t-att-value="v"/>`;
const bnode1 = renderToBdom(template, { v: "zucchini" });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.value).toBe("zucchini");
// change value manually in input, to simulate user input
input.value = "tomato";
expect(input.value).toBe("tomato");
const bnode2 = renderToBdom(template, { v: "zucchini" });
patch(bnode1, bnode2);
expect(input.value).toBe("zucchini");
});
test("input, type checkbox, with t-att-checked (patching with same value", () => {
// render input with initial value
const template = `<input type="checkbox" t-att-checked="v"/>`;
const bnode1 = renderToBdom(template, { v: true });
const fixture = makeTestFixture();
mount(bnode1, fixture);
const input = fixture.querySelector("input")!;
expect(input.checked).toBe(true);
// change checked manually in input, to simulate user input
input.checked = false;
expect(input.checked).toBe(false);
const bnode2 = renderToBdom(template, { v: true });
patch(bnode1, bnode2);
expect(input.checked).toBe(true);
});
test("input of type checkbox with t-att-indeterminate", () => {
const template = `<input type="checkbox" t-att-indeterminate="v"/>`;
const bnode1 = renderToBdom(template, { v: true });
+9
View File
@@ -12,6 +12,15 @@ describe("error handling", () => {
expect(() => context.renderToString("invalidname")).toThrow("Missing template");
});
test("cannot add twice the same template", () => {
const context = new TestContext();
context.addTemplate("test", `<t></t>`);
expect(() => context.addTemplate("test", "<div/>", { allowDuplicate: true })).not.toThrow(
"already defined"
);
expect(() => context.addTemplate("test", "<div/>")).toThrow("already defined");
});
test("addTemplates throw if parser error", () => {
const context = new TestContext();
expect(() => {
+4 -7
View File
@@ -1,8 +1,8 @@
import { TemplateSet } from "../../src/runtime/template_set";
import { mount } from "../../src/runtime/blockdom";
import { TemplateSet } from "../../src/app/template_set";
import { mount } from "../../src/blockdom";
import { makeTestFixture, renderToBdom, renderToString, snapshotEverything } from "../helpers";
import { markup } from "../../src/runtime/utils";
import { STATUS } from "../../src/runtime/status";
import { markup } from "../../src/utils";
import { STATUS } from "../../src/component/status";
snapshotEverything();
// -----------------------------------------------------------------------------
@@ -284,9 +284,6 @@ describe("t-on", () => {
expect(this).toBe(owner);
expect(val).toBe(444);
},
get this() {
return owner;
},
value: 444,
};
+1 -14
View File
@@ -135,7 +135,7 @@ describe("expression evaluation", () => {
expect(compileExpr("color === 'black'")).toBe("ctx['color']==='black'");
expect(compileExpr("'li_'+item")).toBe("'li_'+ctx['item']");
expect(compileExpr("state.val > 1")).toBe("ctx['state'].val>1");
expect(compileExpr("a in b")).toBe("ctx['a'] in ctx['b']");
expect(compileExpr("a in b")).toBe("ctx['a']in ctx['b']");
});
test("boolean operations", () => {
@@ -215,17 +215,4 @@ describe("expression evaluation", () => {
expect(compileExpr("[a, {b, c},d]")).toBe("[ctx['a'],{b:ctx['b'],c:ctx['c']},ctx['d']]");
expect(compileExpr("{a:[b, {c, d: e}]}")).toBe("{a:[ctx['b'],{c:ctx['c'],d:ctx['e']}]}");
});
test("preserving spaces where needed for text operators", () => {
expect(compileExpr("new Date()")).toBe("new Date()");
expect(compileExpr("a.c in b")).toBe("ctx['a'].c in ctx['b']");
expect(compileExpr("typeof val")).toBe("typeof ctx['val']");
});
test("binary operators", () => {
expect(compileExpr("1 | 1")).toBe("1|1");
expect(compileExpr("1 & 1")).toBe("1&1");
expect(compileExpr("1 ^ 1")).toBe("1^1");
expect(compileExpr("~1")).toBe("~1");
});
});
+1 -15
View File
@@ -1033,7 +1033,6 @@ describe("qweb parser", () => {
type: ASTType.TCall,
name: "blap",
body: null,
context: null,
},
memo: "",
hasNoFirst: false,
@@ -1071,7 +1070,6 @@ describe("qweb parser", () => {
type: ASTType.TCall,
name: "blabla",
body: null,
context: null,
});
});
@@ -1079,20 +1077,10 @@ describe("qweb parser", () => {
expect(parse(`<t t-call="sub">ok</t>`)).toEqual({
type: ASTType.TCall,
name: "sub",
context: null,
body: [{ type: ASTType.Text, value: "ok" }],
});
});
test("t-call expression with t-call-context", async () => {
expect(parse(`<t t-call="blabla" t-call-context="someContext"/>`)).toEqual({
type: ASTType.TCall,
name: "blabla",
body: null,
context: "someContext",
});
});
test("t-call on a div node", async () => {
expect(parse(`<div t-call="blabla" />`)).toEqual({
type: ASTType.DomNode,
@@ -1108,7 +1096,6 @@ describe("qweb parser", () => {
type: ASTType.TCall,
name: "blabla",
body: null,
context: null,
},
],
});
@@ -1124,7 +1111,6 @@ describe("qweb parser", () => {
type: ASTType.TCall,
name: "blabla",
body: null,
context: null,
},
});
});
@@ -1561,7 +1547,7 @@ describe("qweb parser", () => {
on: null,
slots: {
default: {
content: { body: null, name: "subTemplate", type: ASTType.TCall, context: null },
content: { body: null, name: "subTemplate", type: ASTType.TCall },
attrs: null,
scope: null,
on: null,
+1 -1
View File
@@ -1,5 +1,5 @@
import { renderToString, renderToBdom, snapshotEverything, makeTestFixture } from "../helpers";
import { mount } from "../../src/runtime/blockdom";
import { mount } from "../../src/blockdom";
import { mount as mountComponent, Component, xml } from "../../src/index";
// NB: check the snapshots to see where the SVG namespaces are added

Some files were not shown because too many files have changed in this diff Show More