Compare commits

..

1 Commits

Author SHA1 Message Date
Géry Debongnie a5c07d918b add doc 2022-03-11 15:33:07 +01:00
154 changed files with 5333 additions and 10562 deletions
+1 -6
View File
@@ -261,12 +261,7 @@ This comes from the fact that Owl 2 supports fragments (arbitrary content).
Migration: if one need a reference to the root htmlelement of a template, it is
suggested to simply add a `ref` on it, and access the reference as needed.
Another way to get access to a root node or html element is the hook `useRoots`
Documentation:
- [Refs](doc/reference/refs.md)
- [useRoots](doc/reference/hooks.md#useroots)
Documentation: [Refs](doc/reference/refs.md)
### 10. style/class on components are now regular props
+2 -2
View File
@@ -74,6 +74,7 @@ Are you new to Owl? This is the place to start!
- [Tutorial: create a TodoList application](doc/learning/tutorial_todoapp.md)
- [How to start an Owl project](doc/learning/quick_start.md)
- [How to test Components](doc/learning/how_to_test.md)
- [How to organize Owl code](doc/miscellaneous/organizing_code.md)
### Reference
@@ -93,7 +94,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 +124,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)
+4 -5
View File
@@ -240,7 +240,7 @@ class Task extends Component {
static template = xml /* xml */`
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox" t-att-checked="props.task.isCompleted"/>
<span><t t-esc="props.task.text"/></span>
<span><t t-esc="props.task.title"/></span>
</div>`;
static props = ["task"];
}
@@ -743,7 +743,7 @@ the user experience.
```xml
<input type="checkbox" t-att-checked="props.task.isCompleted"
t-att-id="props.task.id"
t-on-click="() => store.toggleTask(props.task)"/>
t-on-click="dispatch('toggleTask', props.task.id)"/>
<label t-att-for="props.task.id"><t t-esc="props.task.text"/></label>
```
@@ -770,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>
```
+380
View File
@@ -0,0 +1,380 @@
# 🦉 Organising Owl code 🦉
## Content
- [Overview](#overview)
- [Reactivity](#reactivity)
- [Asynchrony](#asynchrony)
- [Basic design: Components and Props](#basic-design-components-and-props)
- [More advanced design: using the environment](#more-advanced-design-using-the-environment)
- [Even more advanced: completely separating model management](#even-more-advanced-completely-separating-model-management)
- [Special case: bypassing reactivity](#special-case-bypassing-reactivity)
## Overview
The topic of this document is to discuss how one could organize an Owl
application/component/feature/codebase. Clearly, good practices for a system depends
on its properties/semantics. For Owl 2.x applications, the most important
ideas to have in mind are the following:
- Owl provides a way to structure a component tree,
- communication between a parent and a child component is mostly done with props
(and callback props to go from child to parent),
- there is an additional communication channel: information can be propagated
through the environment,
- Owl implements a reactivity system, which tracks each components and values,
so that it is able to only rerender the relevant subset of components,
- asynchrony: owl components can delay renderings with `onWillStart`/`onWillUpdateProps`
- renderings are batched (10 calls to render in the same call stack will only
result in 1 actual rendering)
## Reactivity
With the reactivity system, each value created with the `useState` or the `reactive`
function is a proxy that allows Owl to trask which keys/values have been read
by which components. This means that Owl can then only update the components that
are impacted by a state change.
There are two important reactivity primitives:
- `useState`: a hook to turn a value into a reactive value, linked to a component
(so, each time the value is updated, the component is rerendered)
- `reactive`: a function to create a "standalone" reactive value
Also, it is good to know that one can call `useState` on a reactive value: this will
create another reactive value, connected to the same source, but linked to a
different component.
Let us consider the following component tree:
```mermaid
graph TD
A-->B
A-->C
B-->D
B-->E
B-->F
C-->G
C-->H
```
It is important to know how renderings are applied by Owl:
- if a render is initiated in A, it will render its template
- whenever it encounter a child component (here, B and C), it will shallow
compare the before and after props. If they are different, Owl will render the
corresponding child component, otherwise it will stop.
- each props object received by a (child) component is turned into a reactive
object.
Each (non primitive) value given by `A` to `B` and `C` will be transformed into
a reactive object.
basically, owl does a useState on props at each level, and compare
shallowly values
Notes:
- each component can be independently rendered (so, for example, only B and D)
- one can create reactive objects (just like useState, but not linked to any
component) with the `reactive` function
- escape hatch: one can mark an object as "raw" (non reactive) with `markRaw`, and get the target
object (with `toRaw`)
- note that it is bad practice to keep reference to the raw object: doing so means
that some => may miss
rendering
- note: reactivity is not free. It may be expensive for some large objects.
## Asynchrony
explain: onWillStart and onWillUpdateProps are async => can delay render
good usecase for lazyloading libs
note: most of the time, update should be done in an atomic way:
```js
// bad => will cause extra rendering, possibly corrupt
this.state.something = someValue;
const otherValue = await this.fetchSomething();
this.state.otherValue = otherValue;
```
```js
// good
const otherValue = await this.fetchSomething();
this.state.something = someValue;
this.state.otherValue = otherValue;
```
```js
// bad => will cause extra rendering, possibly corrupt
const someValue = getsomeValue();
const otherValue = await this.fetchSomething();
Object.assign(this.state, {
someValue,
otherValue,
});
```
other note: minimize async stuff
```js
setup() {
// strategy 1: have a loading screen
this.state = useState({loading: true});
}
```
```xml
<t t-if="state.loading">
</t>
...
```
// other strategy: not display a loading indicator, and update the UI atomically
```js
setup() {
onWillStart(() => this.loadData());
onWillUpdateProps(() => this.updateData());
}
```
## Baseline design: Components and props
Here is what I suppose many Owl systems will look like: `useState` in some components,
state is propagated down the tree with props, and potentially callbacks as well
(to communicate from child to parent)
A
/ \
B C
/ | \ | \
D E F G H
```js
// in A (and maybe some/all other components)
this.state = useState(...);
```
```xml
<!-- in A -->
<div>
<t t-if="state.message">
<span t-esc="state.message"/>
</t>
<B record="state.records[3]" updateValue.bind="updateValue">
</div>
```
Notice the `.bind` suffix here, very convenient.
```xml
<!-- in B. It is now subscribed to the 'some_field' value -->
<span t-esc="props.record.some_field"/>
```
With reactivity, any update to the state will only rerender the affected components.
So, if some code in `A` update the value of `some_field` (without reading it!),
only B will be rerendered.
## More advanced design: passing stuff through the environment
It may be tedious/impractical to pass props all along the tree when we have a deep
component tree.
One can then use the environment to communicate to children. Only issue with that
is that stuff in the environment bypass the reactivity system: if it comes from
a `useState` in `A` => only `A` will react to state changes, not the children that
reads it.
To solve that, one need to use `useState` on it:
```js
// in root component A
class A extends Component {
setup() {
this.posModel = {
state: useState(this.state),
updateSomeValue: () => this.updateSomeValue(),
doSomethingElse: () => this.doSomethingElse(),
};
useSubEnv({ posModel: this.posModel });
}
}
// in some child component D
class D extends Component {
setup() {
// this one is wrong! this.posModel.state is stated
this.posModel = this.env.posModel;
// this.posModel.state === the one in A, linked to the component A
// this one is ok!
this.posModel = useState(this.env.posModel);
}
}
```
Note that we can slightly simplify the use of the model by a hook:
```js
function usePosModel() {
const env = useEnv();
const model = env.posModel;
return useState(model);
}
```
This is not much simpler, but it makes sure that one does not forget to call
`useState` on the model from the environment.
## Even more advanced: completely separating model management
The baseline design above it nice for many usecases, but we sometimes may want
to separate the "model" management from the UI, especially as the model is doing
more complicated stuff. Useful to code some complex transitions.
Here is how we could use the environment and reactive object to organize code:
```js
// in my_model.js
class MyModel {
...
constructor() {
this.complicatedCacheObject = {};
markRaw(this.complicatedCacheObject);
}
async load(...) {
}
async update(...) {
}
async doSomeComplexThing() {
this.loading = true;
// coordinate here some thing
// fetch stuff...
this.loading = false;
this.data = ...;
...
}
...
}
// in root component A:
class A extends Component {
setup() {
const model = useState(new MyModel(...));
useSubEnv({ model });
}
}
// in some child component:
class D extends Component {
setup() {
// notice the useState: this is necessary to bind model changes to the
// component D
this.model = useState(this.env.model);
}
}
```
Notes:
- model could be created elsewhere, in a service, in the start code, ...
- one may want to mark some internal stuff as 'raw'...
- if created elsewhere, it should probably be done with `reactive`
- the call to `reactive` could be done in the model constructor directly:
```js
class MyModel {
constructor() {
...
return reactive(this);
}
}
```
- one could slightly simplify the model use with a hook:
```js
function useModel() {
const env = useEnv();
const model = env.model;
return useState(model);
}
```
This can be simply used like this in a child component:
```js
setup() {
this.model = useModel();
}
```
## Special case: bypassing reactivity
Sometimes, reactivity is not what we want. For example, the o_spreadsheet
library has a huge extremely complex model, and each state transition may
potentially update the full UI, so it needs to be fast anyway, and reactivity
has a cost that may outweight the benefits.
The strategy here is:
- mark the model as raw (not necessary in all cases, but potentially important
if model is passed through some props)
- find a way to be notified on update change (for example, by an event triggered
by an event bus)
- perform a deep rendering: render(true), at the root component.
Here is how one could organize the code then:
```js
class MainModel extends EventBus{
constructor() {
markRaw(this); // make sure this object will never be turned into a reactive
}
doSomething() {
...
// need to notify the outside world that a change occurred
this.trigger("UPDATE");
}
...
}
// in root component:
class A extends Component {
setup() {
const model = new MainModel();
// notice the 'render(true)', to do a deep render
model.addEventListener("UPDATE", () => this.render(true));
useSubEnv({ model });
}
}
// in child components:
class E extends Component {
setup() {
this.model = this.env.model; // not really necessary, but maybe nice
}
onClick() {
this.model.doSomething();
}
}
```
-2
View File
@@ -38,7 +38,6 @@ Other hooks:
- [`useRef`](reference/hooks.md#useref): get an object representing a reference (`t-ref`)
- [`useChildSubEnv`](reference/hooks.md#usesubenv-and-usechildsubenv): extend the current env with additional information (for child components)
- [`useSubEnv`](reference/hooks.md#usesubenv-and-usechildsubenv): extend the current env with additional information (for current component and child components)
- [`useRoots`](reference/hooks.md#useroots): returns an object that provides access to all root nodes or htmlelements
Utility/helpers:
@@ -46,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
-4
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
@@ -119,5 +117,3 @@ Dev mode activates some additional checks and developer amenities:
- [Props validation](./props.md#props-validation) is performed
- [t-foreach](./templates.md#loops) loops check for key unicity
- Lifecycle hooks are wrapped to report their errors in a more developer-friendly way
- onWillStart and onWillUpdateProps will emit a warning in the console when they
take longer than 3 seconds in an effort to ease debugging the presence of deadlocks
+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 -39
View File
@@ -13,7 +13,6 @@
- [`useComponent`](#usecomponent)
- [`useEnv`](#useenv)
- [`useEffect`](#useeffect)
- [`useRoots`](#useroots)
- [Example: Mouse Position](#example-mouse-position)
## Overview
@@ -235,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:
@@ -289,42 +287,6 @@ class SomeComponent extends Component {
}
```
### `useRoots`
`useRoots` is an alternative way to get a reference to the root notes or elements
of a component. It may be useful in some cases where `useRef` cannot be applied,
such as a higher order component, or a component with only text as content.
The return value of `useRoots` is an object with the following key/values:
- `node`: getter that evaluates to the first node of the component content (or null)
- `elem`: getter that evaluates to the first HTMLElement of the component content (or null)
- `nodes`: iterator that returns all content nodes
- `elems`: iterator that returns all HTMLElement nodes
```js
class Child extends Component {
static template = xml`<p>some content</p>`;
}
class Parent extends Component {
static template = xml`<Child/>`;
static components = { Child };
setup() {
this.roots = useRoots();
console.log(this.roots.elem); // null
onMounted(() => {
console.log(this.roots.elem); // log the `p` element from the child
for (let elem of this.roots.elems) {
console.log(elem); // log the `p` element from the child
}
});
}
}
```
## Example: mouse position
Here is the classical example of a non trivial hook to track the mouse position.
-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,
+3 -3
View File
@@ -26,9 +26,9 @@ To solve this issue, Owl provides two reactivity primitives:
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: reactive objects received as props are automatically subscribed to by the
component, so Owl can track which part of these props are consumed by each
component, and is therefore able to only rerender the impacted components.
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`
-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:
+2 -12
View File
@@ -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,15 +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 (so, the current component). 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),
```
+4 -7
View File
@@ -1,10 +1,11 @@
{
"name": "@odoo/owl",
"version": "2.0.0-beta-20",
"version": "2.0.0-beta.3",
"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",
@@ -26,8 +25,7 @@
"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",
"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",
@@ -54,7 +52,6 @@
"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",
+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
}),
]
};
+10 -78
View File
@@ -1,12 +1,10 @@
import { Component, ComponentConstructor, Props } from "./component";
import { ComponentNode } from "./component_node";
import { nodeErrorHandlers, OwlError } from "./error_handling";
import { Fiber, MountOptions } from "./fibers";
import { Scheduler } from "./scheduler";
import { validateProps } from "./template_helpers";
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 { validateTarget } from "./utils";
import { handleError } from "./error_handling";
import { nodeErrorHandlers } from "../component/error_handling";
import { validateTarget } from "../utils";
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
@@ -18,7 +16,6 @@ export interface AppConfig<P, E> extends TemplateSetConfig {
props?: P;
env?: E;
test?: boolean;
warnIfNoStaticProps?: boolean;
}
let hasBeenLogged = false;
@@ -44,7 +41,6 @@ export class App<
env: E;
scheduler = new Scheduler();
root: ComponentNode<P, E> | null = null;
warnIfNoStaticProps: boolean;
constructor(Root: ComponentConstructor<P, E>, config: AppConfig<P, E> = {}) {
super(config);
@@ -52,7 +48,6 @@ export class App<
if (config.test) {
this.dev = true;
}
this.warnIfNoStaticProps = config.warnIfNoStaticProps || false;
if (this.dev && !config.test && !hasBeenLogged) {
console.info(DEV_MSG());
hasBeenLogged = true;
@@ -65,9 +60,6 @@ export class App<
mount(target: HTMLElement, options?: MountOptions): Promise<Component<P, E> & InstanceType<T>> {
App.validateTarget(target);
if (this.dev) {
validateProps(this.Root, this.props, { app: this });
}
const node = this.makeNode(this.Root, this.props);
const prom = this.mountNode(node, target, options);
this.root = node;
@@ -75,7 +67,7 @@ export class App<
}
makeNode(Component: ComponentConstructor, props: any): ComponentNode {
return new ComponentNode(Component, props, this, null, null);
return new ComponentNode(Component, props, this);
}
mountNode(node: ComponentNode, target: HTMLElement, options?: MountOptions) {
@@ -95,7 +87,9 @@ export class App<
nodeErrorHandlers.set(node, handlers);
}
handlers.unshift((e) => {
if (!isResolved) {
if (isResolved) {
console.error(e);
} else {
reject(e);
}
throw e;
@@ -107,71 +101,9 @@ export class App<
destroy() {
if (this.root) {
this.scheduler.flush();
this.root.destroy();
}
}
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) {
C = parent.constructor.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<
+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;
@@ -143,8 +139,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 || "";
};
}
@@ -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,12 +507,6 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
return this.el!;
}
*nodes() {
if (this.el) {
yield this.el;
}
}
moveBefore(other: Block | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
@@ -6,67 +6,60 @@ type EventsSpec = { [name: string]: number };
type Catcher = (child: VNode, handlers: any[]) => VNode;
export function createCatcher(eventsSpec: EventsSpec): Catcher {
const n = Object.keys(eventsSpec).length;
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;
handlerData: any[];
handlerFns: any[] = [];
handlers: any[];
parentEl?: HTMLElement | undefined;
afterNode: Text | null = null;
afterNode: Node | null = null;
constructor(child: VNode, handlers: any[]) {
this.child = child;
this.handlerData = handlers;
this.handlers = handlers;
}
mount(parent: HTMLElement, afterNode: Node | null) {
this.parentEl = parent;
this.afterNode = afterNode;
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];
let origFn = this.handlers[i][0];
const self = this;
handler[idx] = function (ev: any) {
this.handlers[i][0] = function (ev: any) {
const target = ev.target;
for (let node of self.nodes()) {
if (node.contains(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);
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.handlers = other.handlers;
this.child.patch(other.child, withBeforeRemove);
}
@@ -76,20 +69,15 @@ export function createCatcher(eventsSpec: EventsSpec): Catcher {
remove() {
for (let i = 0; i < n; i++) {
this.handlerFns[i].remove.call(this.parentEl!);
removeFns[i].call(this.parentEl!);
}
this.child.remove();
this.afterNode!.remove();
}
firstNode(): Node | undefined {
return this.child.firstNode();
}
nodes(): Generator<Node> {
return this.child.nodes();
}
toString(): string {
return this.child.toString();
}
@@ -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);
@@ -78,12 +78,6 @@ class VHtml {
return this.content[0]!;
}
*nodes() {
for (let elem of this.content) {
yield elem;
}
}
toString() {
return this.html;
}
@@ -16,8 +16,6 @@ export interface VNode<T = any> {
remove(): void;
firstNode(): Node | undefined;
nodes(): Generator<Node>;
el?: undefined | HTMLElement | Text;
parentEl?: undefined | HTMLElement;
isOnlyChild?: boolean | undefined;
@@ -221,12 +221,6 @@ class VList {
return child ? child.firstNode() : undefined;
}
*nodes() {
for (let child of this.children) {
yield* child.nodes();
}
}
toString(): string {
return this.children.map((c) => c!.toString()).join("");
}
@@ -124,14 +124,6 @@ export class VMulti {
return child ? child.firstNode() : this.anchors![0];
}
*nodes() {
for (let child of this.children) {
if (child) {
yield* child.nodes();
}
}
}
toString(): string {
return this.children.map((c) => (c ? c!.toString() : "")).join("");
}
@@ -38,12 +38,6 @@ abstract class VSimpleNode {
return this.el!;
}
*nodes(): Generator<Node> {
if (this.el) {
yield this.el;
}
}
toString() {
return this.text;
}
@@ -55,10 +55,6 @@ class VToggler {
return this.child.firstNode();
}
nodes() {
return this.child.nodes();
}
toString(): string {
return this.child.toString();
}
+123 -175
View File
@@ -1,11 +1,4 @@
import { isProp } from "../runtime/blockdom/attributes";
import {
compileExpr,
compileExprToArray,
interpolate,
INTERP_REGEXP,
replaceDynamicParts,
} from "./inline_expressions";
import { compileExpr, compileExprToArray, interpolate, INTERP_REGEXP } from "./inline_expressions";
import {
AST,
ASTComment,
@@ -23,14 +16,13 @@ import {
ASTTif,
ASTTKey,
ASTTOut,
ASTTPortal,
ASTTranslation,
ASTTSet,
ASTTranslation,
ASTType,
Attrs,
ASTTPortal,
EventHandlers,
Attrs,
} from "./parser";
import { OwlError } from "../runtime/error_handling";
type BlockType = "block" | "text" | "multi" | "list" | "html" | "comment";
@@ -50,20 +42,17 @@ export interface CodeGenOptions extends Config {
const xmlDoc = document.implementation.createDocument(null, null, null);
const MODS = new Set(["stop", "capture", "prevent", "self", "synthetic"]);
let nextDataIds: { [key: string]: number } = {};
function generateId(prefix: string = "") {
nextDataIds[prefix] = (nextDataIds[prefix] || 0) + 1;
return prefix + nextDataIds[prefix];
}
// -----------------------------------------------------------------------------
// BlockDescription
// -----------------------------------------------------------------------------
class BlockDescription {
static nextBlockId = 1;
static nextDataIds: { [key: string]: number } = {};
static generateId(prefix: string) {
this.nextDataIds[prefix] = (this.nextDataIds[prefix] || 0) + 1;
return prefix + this.nextDataIds[prefix];
}
varName: string;
blockName: string;
@@ -89,7 +78,7 @@ class BlockDescription {
}
insertData(str: string, prefix: string = "d"): number {
const id = generateId(prefix);
const id = BlockDescription.generateId(prefix);
this.target.addLine(`let ${id} = ${str};`);
return this.data.push(id) - 1;
}
@@ -142,10 +131,9 @@ interface Context {
tKeyExpr: string | null;
nameSpace?: string;
tModelSelectedExpr?: string;
ctxVar?: string;
}
function createContext(parentCtx: Context, params?: Partial<Context>): Context {
function createContext(parentCtx: Context, params?: Partial<Context>) {
return Object.assign(
{
block: null,
@@ -221,6 +209,7 @@ const translationRE = /^(\s*)([\s\S]+?)(\s*)$/;
export class CodeGenerator {
blocks: BlockDescription[] = [];
ids: { [key: string]: number } = {};
nextBlockId = 1;
hasSafeContext: boolean;
isDebug: boolean = false;
@@ -232,7 +221,6 @@ export class CodeGenerator {
translatableAttributes: string[] = TRANSLATABLE_ATTRS;
ast: AST;
staticDefs: { id: string; expr: string }[] = [];
slotNames: Set<String> = new Set();
helpers: Set<string> = new Set();
constructor(ast: AST, options: CodeGenOptions) {
@@ -258,7 +246,7 @@ export class CodeGenerator {
const ast = this.ast;
this.isDebug = ast.type === ASTType.TDebug;
BlockDescription.nextBlockId = 1;
nextDataIds = {};
BlockDescription.nextDataIds = {};
this.compileAST(ast, {
block: null,
index: 0,
@@ -268,7 +256,9 @@ export class CodeGenerator {
tKeyExpr: null,
});
// define blocks and utility functions
let mainCode = [` let { text, createBlock, list, multi, html, toggler, comment } = bdom;`];
let mainCode = [
` let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;`,
];
if (this.helpers.size) {
mainCode.push(`let { ${[...this.helpers].join(", ")} } = helpers;`);
}
@@ -286,7 +276,6 @@ export class CodeGenerator {
for (let block of this.blocks) {
if (block.dom) {
let xmlString = block.asXmlString();
xmlString = xmlString.replace(/`/g, "\\`");
if (block.dynamicTagName) {
xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
@@ -319,7 +308,7 @@ export class CodeGenerator {
}
compileInNewTarget(prefix: string, ast: AST, ctx: Context, on?: EventHandlers | null): string {
const name = generateId(prefix);
const name = this.generateId(prefix);
const initialTarget = this.target;
const target = new CodeTarget(name, on);
this.targets.push(target);
@@ -337,8 +326,13 @@ export class CodeGenerator {
this.addLine(`const ${varName} = ${expr};`);
}
insertAnchor(block: BlockDescription, index: number = block.children.length) {
const tag = `block-child-${index}`;
generateId(prefix: string = ""): string {
this.ids[prefix] = (this.ids[prefix] || 0) + 1;
return prefix + this.ids[prefix];
}
insertAnchor(block: BlockDescription) {
const tag = `block-child-${block.children.length}`;
const anchor = xmlDoc.createElement(tag);
block.insert(anchor);
}
@@ -413,7 +407,7 @@ export class CodeGenerator {
.map((tok) => {
if (tok.varName && !tok.isLocal) {
if (!mapping.has(tok.varName)) {
const varId = generateId("v");
const varId = this.generateId("v");
mapping.set(tok.varName, varId);
this.define(varId, tok.value);
}
@@ -537,7 +531,7 @@ export class CodeGenerator {
.slice(1)
.map((m) => {
if (!MODS.has(m)) {
throw new OwlError(`Unknown event modifier: '${m}'`);
throw new Error(`Unknown event modifier: '${m}'`);
}
return `"${m}"`;
});
@@ -559,7 +553,7 @@ export class CodeGenerator {
block = this.createBlock(block, "block", ctx);
this.blocks.push(block);
if (ast.dynamicTag) {
const tagExpr = generateId("tag");
const tagExpr = this.generateId("tag");
this.define(tagExpr, compileExpr(ast.dynamicTag));
block.dynamicTagName = tagExpr;
}
@@ -581,22 +575,13 @@ export class CodeGenerator {
attrName = key.slice(7);
attrs["block-attribute-" + idx] = attrName;
} else if (key.startsWith("t-att")) {
attrName = key === "t-att" ? null : key.slice(6);
expr = compileExpr(ast.attrs[key]);
if (attrName && isProp(ast.tag, attrName)) {
// we force a new string or new boolean to bypass the equality check in blockdom when patching same value
if (attrName === "value") {
// When the expression is falsy, fall back to an empty string
expr = `new String((${expr}) || "")`;
} else {
expr = `new Boolean(${expr})`;
}
}
const idx = block!.insertData(expr, "attr");
if (key === "t-att") {
attrs[`block-attributes`] = String(idx);
} else {
attrs[`block-attribute-${idx}`] = attrName!;
attrName = key.slice(6);
attrs[`block-attribute-${idx}`] = attrName;
}
} else if (this.translatableAttributes.includes(key)) {
attrs[key] = this.translateFn(ast.attrs[key]);
@@ -624,8 +609,11 @@ export class CodeGenerator {
this.target.hasRef = true;
const isDynamic = INTERP_REGEXP.test(ast.ref);
if (isDynamic) {
const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
const idx = block!.insertData(`(el) => refs[${str}] = el`, "ref");
const str = ast.ref.replace(
INTERP_REGEXP,
(expr) => "${" + this.captureExpression(expr.slice(2, -2), true) + "}"
);
const idx = block!.insertData(`(el) => refs[\`${str}\`] = el`, "ref");
attrs["block-ref"] = String(idx);
} else {
let name = ast.ref;
@@ -637,7 +625,7 @@ export class CodeGenerator {
attrs["block-ref"] = String(index);
info[1] = `multiRefSetter(refs, \`${name}\`)`;
} else {
let id = generateId("ref");
let id = this.generateId("ref");
this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
const index = block!.data.push(id) - 1;
attrs["block-ref"] = String(index);
@@ -660,11 +648,11 @@ export class CodeGenerator {
} = ast.model;
const baseExpression = compileExpr(baseExpr);
const bExprId = generateId("bExpr");
const bExprId = this.generateId("bExpr");
this.define(bExprId, baseExpression);
const expression = compileExpr(expr);
const exprId = generateId("expr");
const exprId = this.generateId("expr");
this.define(exprId, expression);
const fullExpression = `${bExprId}[${exprId}]`;
@@ -674,7 +662,7 @@ export class CodeGenerator {
idx = block!.insertData(`${fullExpression} === '${attrs[targetAttr]}'`, "attr");
attrs[`block-attribute-${idx}`] = specialInitTargetAttr;
} else if (hasDynamicChildren) {
const bValueId = generateId("bValue");
const bValueId = this.generateId("bValue");
tModelSelectedExpr = `${bValueId}`;
this.define(tModelSelectedExpr, fullExpression);
} else {
@@ -704,7 +692,7 @@ export class CodeGenerator {
const children = ast.content;
for (let i = 0; i < children.length; i++) {
const child = ast.content[i];
const subCtx = createContext(ctx, {
const subCtx: Context = createContext(ctx, {
block,
index: block!.childNumber,
forceNewBlock: false,
@@ -766,37 +754,21 @@ export class CodeGenerator {
this.insertAnchor(block);
}
block = this.createBlock(block, "html", ctx);
let blockStr;
if (ast.expr === "0") {
this.helpers.add("zero");
blockStr = `ctx[zero]`;
} else if (ast.body) {
let bodyValue = null;
bodyValue = BlockDescription.nextBlockId;
const subCtx = createContext(ctx);
this.helpers.add(ast.expr === "0" ? "zero" : "safeOutput");
let expr = ast.expr === "0" ? "ctx[zero]" : `safeOutput(${compileExpr(ast.expr)})`;
if (ast.body) {
const nextId = BlockDescription.nextBlockId;
const subCtx: Context = createContext(ctx);
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
this.helpers.add("safeOutput");
blockStr = `safeOutput(${compileExpr(ast.expr)}, b${bodyValue})`;
} else {
this.helpers.add("safeOutput");
blockStr = `safeOutput(${compileExpr(ast.expr)})`;
this.helpers.add("withDefault");
expr = `withDefault(${expr}, b${nextId})`;
}
this.insertBlock(blockStr, block, ctx);
}
compileTIfBranch(content: AST, block: BlockDescription, ctx: Context) {
this.target.indentLevel++;
let childN = block.children.length;
this.compileAST(content, createContext(ctx, { block, index: ctx.index }));
if (block.children.length > childN) {
// we have some content => need to insert an anchor at correct index
this.insertAnchor(block!, childN);
}
this.target.indentLevel--;
this.insertBlock(`${expr}`, block, ctx);
}
compileTIf(ast: ASTTif, ctx: Context, nextNode?: ASTDomNode) {
let { block, forceNewBlock } = ctx;
let { block, forceNewBlock, index } = ctx;
let currentIndex = index;
const codeIdx = this.target.code.length;
const isNewBlock = !block || (block.type !== "multi" && forceNewBlock);
if (block) {
@@ -806,16 +778,28 @@ export class CodeGenerator {
block = this.createBlock(block, "multi", ctx);
}
this.addLine(`if (${compileExpr(ast.condition)}) {`);
this.compileTIfBranch(ast.content, block, ctx);
this.target.indentLevel++;
this.insertAnchor(block!);
const subCtx: Context = createContext(ctx, { block, index: currentIndex });
this.compileAST(ast.content, subCtx);
this.target.indentLevel--;
if (ast.tElif) {
for (let clause of ast.tElif) {
this.addLine(`} else if (${compileExpr(clause.condition)}) {`);
this.compileTIfBranch(clause.content, block, ctx);
this.target.indentLevel++;
this.insertAnchor(block);
const subCtx: Context = createContext(ctx, { block, index: currentIndex });
this.compileAST(clause.content, subCtx);
this.target.indentLevel--;
}
}
if (ast.tElse) {
this.addLine(`} else {`);
this.compileTIfBranch(ast.tElse, block, ctx);
this.target.indentLevel++;
this.insertAnchor(block);
const subCtx: Context = createContext(ctx, { block, index: currentIndex });
this.compileAST(ast.tElse, subCtx);
this.target.indentLevel--;
}
this.addLine("}");
if (isNewBlock) {
@@ -877,16 +861,15 @@ export class CodeGenerator {
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
if (this.dev) {
// Throw error on duplicate keys in dev mode
this.helpers.add("OwlError");
this.addLine(
`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`
`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new Error(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`
);
this.addLine(`keys${block.id}.add(key${this.target.loopLevel});`);
}
let id: string;
if (ast.memo) {
this.target.hasCache = true;
id = generateId();
id = this.generateId();
this.define(`memo${id}`, compileExpr(ast.memo));
this.define(`vnode${id}`, `cache[key${this.target.loopLevel}];`);
this.addLine(`if (vnode${id}) {`);
@@ -902,7 +885,7 @@ export class CodeGenerator {
this.addLine("}");
}
const subCtx = createContext(ctx, { block, index: loopVar });
const subCtx: Context = createContext(ctx, { block, index: loopVar });
this.compileAST(ast.body, subCtx);
if (ast.memo) {
this.addLine(
@@ -921,7 +904,7 @@ export class CodeGenerator {
}
compileTKey(ast: ASTTKey, ctx: Context) {
const tKeyExpr = generateId("tKey_");
const tKeyExpr = this.generateId("tKey_");
this.define(tKeyExpr, compileExpr(ast.expr));
ctx = createContext(ctx, {
tKeyExpr,
@@ -949,7 +932,7 @@ export class CodeGenerator {
for (let i = 0, l = ast.content.length; i < l; i++) {
const child = ast.content[i];
const isTSet = child.type === ASTType.TSet;
const subCtx = createContext(ctx, {
const subCtx: Context = createContext(ctx, {
block,
index,
forceNewBlock: !isTSet,
@@ -985,21 +968,16 @@ export class CodeGenerator {
compileTCall(ast: ASTTCall, ctx: Context) {
let { block, forceNewBlock } = ctx;
let ctxVar = ctx.ctxVar || "ctx";
if (ast.context) {
ctxVar = generateId("ctx");
this.addLine(`let ${ctxVar} = ${compileExpr(ast.context)};`);
}
if (ast.body) {
this.addLine(`${ctxVar} = Object.create(${ctxVar});`);
this.addLine(`${ctxVar}[isBoundary] = 1;`);
this.addLine(`ctx = Object.create(ctx);`);
this.addLine(`ctx[isBoundary] = 1;`);
this.helpers.add("isBoundary");
const nextId = BlockDescription.nextBlockId;
const subCtx = createContext(ctx, { preventRoot: true, ctxVar });
const subCtx: Context = createContext(ctx, { preventRoot: true });
this.compileAST({ type: ASTType.Multi, content: ast.body }, subCtx);
if (nextId !== BlockDescription.nextBlockId) {
this.helpers.add("zero");
this.addLine(`${ctxVar}[zero] = b${nextId};`);
this.addLine(`ctx[zero] = b${nextId};`);
}
}
const isDynamic = INTERP_REGEXP.test(ast.name);
@@ -1011,27 +989,26 @@ export class CodeGenerator {
}
const key = `key + \`${this.generateComponentKey()}\``;
if (isDynamic) {
const templateVar = generateId("template");
if (!this.staticDefs.find((d) => d.id === "call")) {
this.staticDefs.push({ id: "call", expr: `app.callTemplate.bind(app)` });
}
const templateVar = this.generateId("template");
this.define(templateVar, subTemplate);
block = this.createBlock(block, "multi", ctx);
this.insertBlock(`call(this, ${templateVar}, ${ctxVar}, node, ${key})`, block!, {
this.helpers.add("call");
this.insertBlock(`call(this, ${templateVar}, ctx, node, ${key})`, block!, {
...ctx,
forceNewBlock: !block,
});
} else {
const id = generateId(`callTemplate_`);
this.staticDefs.push({ id, expr: `app.getTemplate(${subTemplate})` });
const id = this.generateId(`callTemplate_`);
this.helpers.add("getTemplate");
this.staticDefs.push({ id, expr: `getTemplate(${subTemplate})` });
block = this.createBlock(block, "multi", ctx);
this.insertBlock(`${id}.call(this, ${ctxVar}, node, ${key})`, block!, {
this.insertBlock(`${id}.call(this, ctx, node, ${key})`, block!, {
...ctx,
forceNewBlock: !block,
});
}
if (ast.body && !ctx.isLast) {
this.addLine(`${ctxVar} = ${ctxVar}.__proto__;`);
this.addLine(`ctx = ctx.__proto__;`);
}
}
@@ -1054,7 +1031,7 @@ export class CodeGenerator {
this.helpers.add("LazyValue");
const bodyAst: AST = { type: ASTType.Multi, content: ast.body };
const name = this.compileInNewTarget("value", bodyAst, ctx);
let value = `new LazyValue(${name}, ctx, this, node)`;
let value = `new LazyValue(${name}, ctx, node)`;
value = ast.value ? (value ? `withDefault(${expr}, ${value})` : expr) : value;
this.addLine(`ctx[\`${ast.name}\`] = ${value};`);
} else {
@@ -1069,12 +1046,12 @@ export class CodeGenerator {
value = expr;
}
this.helpers.add("setContextValue");
this.addLine(`setContextValue(${ctx.ctxVar || "ctx"}, "${ast.name}", ${value});`);
this.addLine(`setContextValue(ctx, "${ast.name}", ${value});`);
}
}
generateComponentKey() {
const parts = [generateId("__")];
const parts = [this.generateId("__")];
for (let i = 0; i < this.target.loopLevel; i++) {
parts.push(`\${key${i + 1}}`);
}
@@ -1101,56 +1078,51 @@ export class CodeGenerator {
name = _name;
value = `bind(ctx, ${value || undefined})`;
} else {
throw new OwlError("Invalid prop suffix");
throw new Error("Invalid prop suffix");
}
}
name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
return `${name}: ${value || undefined}`;
}
formatPropObject(obj: { [prop: string]: any }): string[] {
return Object.entries(obj).map(([k, v]) => this.formatProp(k, v));
}
getPropString(props: string[], dynProps: string | null): string {
let propString = `{${props.join(",")}}`;
if (dynProps) {
propString = `Object.assign({}, ${compileExpr(dynProps)}${
props.length ? ", " + propString : ""
})`;
formatPropObject(obj: { [prop: string]: any }): string {
const params = [];
for (const [n, v] of Object.entries(obj)) {
params.push(this.formatProp(n, v));
}
return propString;
return params.join(", ");
}
compileComponent(ast: ASTComponent, ctx: Context) {
let { block } = ctx;
// props
const hasSlotsProp = "slots" in (ast.props || {});
const props: string[] = ast.props ? this.formatPropObject(ast.props) : [];
const props: string[] = [];
const propExpr = this.formatPropObject(ast.props || {});
if (propExpr) {
props.push(propExpr);
}
// slots
let slotDef: string = "";
if (ast.slots) {
let ctxStr = "ctx";
if (this.target.loopLevel || !this.hasSafeContext) {
ctxStr = generateId("ctx");
ctxStr = this.generateId("ctx");
this.helpers.add("capture");
this.define(ctxStr, `capture(ctx)`);
}
let slotStr: string[] = [];
for (let slotName in ast.slots) {
const slotAst = ast.slots[slotName];
const params = [];
if (slotAst.content) {
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
params.push(`__render: ${name}, __ctx: ${ctxStr}`);
}
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
const params = [`__render: ${name}, __ctx: ${ctxStr}`];
const scope = ast.slots[slotName].scope;
if (scope) {
params.push(`__scope: "${scope}"`);
}
if (ast.slots[slotName].attrs) {
params.push(...this.formatPropObject(ast.slots[slotName].attrs!));
params.push(this.formatPropObject(ast.slots[slotName].attrs!));
}
const slotInfo = `{${params.join(", ")}}`;
slotStr.push(`'${slotName}': ${slotInfo}`);
@@ -1163,11 +1135,18 @@ export class CodeGenerator {
props.push(`slots: markRaw(${slotDef})`);
}
let propString = this.getPropString(props, ast.dynamicProps);
const propStr = `{${props.join(",")}}`;
let propString = propStr;
if (ast.dynamicProps) {
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)}${
props.length ? ", " + propStr : ""
})`;
}
let propVar: string;
if ((slotDef && (ast.dynamicProps || hasSlotsProp)) || this.dev) {
propVar = generateId("props");
propVar = this.generateId("props");
this.define(propVar!, propString);
propString = propVar!;
}
@@ -1181,14 +1160,14 @@ export class CodeGenerator {
const key = this.generateComponentKey();
let expr: string;
if (ast.isDynamic) {
expr = generateId("Comp");
expr = this.generateId("Comp");
this.define(expr, compileExpr(ast.name));
} else {
expr = `\`${ast.name}\``;
}
if (this.dev) {
this.addLine(`helpers.validateProps(${expr}, ${propVar!}, node);`);
this.addLine(`helpers.validateProps(${expr}, ${propVar!}, ctx);`);
}
if (block && (ctx.forceNewBlock === false || ctx.tKeyExpr)) {
@@ -1200,17 +1179,8 @@ export class CodeGenerator {
if (ctx.tKeyExpr) {
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
}
let id = generateId("comp");
this.staticDefs.push({
id,
expr: `app.createComponent(${
ast.isDynamic ? null : expr
}, ${!ast.isDynamic}, ${!!ast.slots}, ${!!ast.dynamicProps}, ${
!ast.props && !ast.dynamicProps
})`,
});
let blockExpr = `${id}(${propString}, ${keyArg}, node, this, ${ast.isDynamic ? expr : null})`;
const blockArgs = `${expr}, ${propString}, ${keyArg}, node, ctx`;
let blockExpr = `component(${blockArgs})`;
if (ast.isDynamic) {
blockExpr = `toggler(${expr}, ${blockExpr})`;
}
@@ -1226,11 +1196,11 @@ export class CodeGenerator {
wrapWithEventCatcher(expr: string, on: EventHandlers): string {
this.helpers.add("createCatcher");
let name = generateId("catcher");
let name = this.generateId("catcher");
let spec: any = {};
let handlers: any[] = [];
for (let ev in on) {
let handlerId = generateId("hdlr");
let handlerId = this.generateId("hdlr");
let idx = handlers.push(handlerId) - 1;
spec[ev] = idx;
const handler = this.generateHandlerCode(ev, on[ev]);
@@ -1246,37 +1216,24 @@ export class CodeGenerator {
let blockString: string;
let slotName;
let dynamic = false;
let isMultiple = false;
if (ast.name.match(INTERP_REGEXP)) {
dynamic = true;
isMultiple = true;
slotName = interpolate(ast.name);
} else {
slotName = "'" + ast.name + "'";
isMultiple = isMultiple || this.slotNames.has(ast.name);
this.slotNames.add(ast.name);
}
const dynProps = ast.attrs ? ast.attrs["t-props"] : null;
if (ast.attrs) {
delete ast.attrs["t-props"];
}
let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
if (isMultiple) {
key = `${key} + \`${this.generateComponentKey()}\``;
}
const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
const scope = this.getPropString(props, dynProps);
const scope = ast.attrs ? `{${this.formatPropObject(ast.attrs)}}` : null;
if (ast.defaultContent) {
const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name})`;
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope}, ${name})`;
} else {
if (dynamic) {
let name = generateId("slot");
let name = this.generateId("slot");
this.define(name, slotName);
blockString = `toggler(${name}, callSlot(ctx, node, ${key}, ${name}, ${dynamic}, ${scope}))`;
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}), ${dynamic}, ${scope})`;
} else {
blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope})`;
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`;
}
}
// event handling
@@ -1297,27 +1254,18 @@ export class CodeGenerator {
}
}
compileTPortal(ast: ASTTPortal, ctx: Context) {
if (!this.staticDefs.find((d) => d.id === "Portal")) {
this.staticDefs.push({ id: "Portal", expr: `app.Portal` });
}
this.helpers.add("Portal");
let { block } = ctx;
const name = this.compileInNewTarget("slot", ast.content, ctx);
const key = this.generateComponentKey();
let ctxStr = "ctx";
if (this.target.loopLevel || !this.hasSafeContext) {
ctxStr = generateId("ctx");
ctxStr = this.generateId("ctx");
this.helpers.add("capture");
this.define(ctxStr, `capture(ctx)`);
this.define(ctxStr, `capture(ctx);`);
}
let id = generateId("comp");
this.staticDefs.push({
id,
expr: `app.createComponent(null, false, true, false, false)`,
});
const target = compileExpr(ast.target);
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
const blockString = `component(Portal, {target: ${ast.target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx)`;
if (block) {
this.insertAnchor(block);
}
+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;
}
+11 -22
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
/**
* Owl QWeb Expression Parser
*
@@ -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);
}
+38 -46
View File
@@ -1,5 +1,3 @@
import { OwlError } from "../runtime/error_handling";
// -----------------------------------------------------------------------------
// AST Type definition
// -----------------------------------------------------------------------------
@@ -117,11 +115,10 @@ export interface ASTTCall {
type: ASTType.TCall;
name: string;
body: AST[] | null;
context: string | null;
}
interface SlotDefinition {
content: AST | null;
content: AST;
scope: string | null;
on: EventHandlers | null;
attrs: Attrs | null;
@@ -321,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") {
@@ -342,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;
@@ -363,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");
@@ -394,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)) {
@@ -451,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;
}
@@ -507,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}")`
);
}
@@ -562,13 +557,11 @@ 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;
@@ -586,7 +579,6 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
type: ASTType.TCall,
name: subTemplate,
body: body.length ? body : null,
context,
};
}
@@ -690,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)) {
@@ -719,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 || {};
@@ -735,7 +725,7 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
for (let slotNode of slotNodes) {
if (slotNode.tagName !== "t") {
throw new OwlError(
throw new Error(
`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`
);
}
@@ -759,24 +749,26 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
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;
if (slotAst) {
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 };
}
slots = slots || {};
slots[name] = { content: slotAst, on, attrs, scope };
}
// default slot
@@ -910,7 +902,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"
);
}
@@ -919,19 +911,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"
);
}
@@ -952,7 +944,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");
@@ -1006,7 +998,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,24 +1,32 @@
import type { App, Env } from "./app";
import { BDom, VNode } from "./blockdom";
import { Component, ComponentConstructor, Props } from "./component";
import { fibersInError, OwlError } from "./error_handling";
import { Fiber, makeChildFiber, makeRootFiber, MountFiber, MountOptions } from "./fibers";
import type { App, Env } from "../app/app";
import { BDom, VNode } from "../blockdom";
import {
clearReactivesForCallback,
getSubscriptions,
NonReactive,
Reactive,
reactive,
TARGET,
} from "./reactivity";
NonReactive,
getSubscriptions,
} from "../reactivity";
import { batched, Callback } from "../utils";
import { Component, ComponentConstructor } from "./component";
import { fibersInError, handleError } from "./error_handling";
import {
Fiber,
makeChildFiber,
makeRootFiber,
MountFiber,
MountOptions,
RootFiber,
} from "./fibers";
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;
}
@@ -27,16 +35,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)
// -----------------------------------------------------------------------------
@@ -56,7 +54,7 @@ export function useState<T extends object>(state: T): Reactive<T> | NonReactive<
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));
@@ -64,13 +62,80 @@ export function useState<T extends object>(state: T): Reactive<T> | NonReactive<
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));
}
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;
@@ -78,11 +143,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 = {};
@@ -95,32 +159,16 @@ 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" && prop[TARGET]) {
props[key] = useState(prop);
}
}
this.component = new C(props, env, 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;
@@ -141,17 +189,17 @@ 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) {
fiber.render();
this._render(fiber);
}
}
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;
@@ -173,7 +221,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) {
@@ -191,7 +238,16 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
// embedded in a rendering coming from above, so the fiber will be rendered
// in the next microtick anyway, so we should not render it again.
if (this.fiber === fiber && (current || !fiber.parent)) {
fiber.render();
this._render(fiber);
}
}
_render(fiber: Fiber | RootFiber) {
try {
fiber.bdom = this.renderFn();
fiber.root!.counter--;
} catch (e) {
handleError({ node: this, error: e });
}
}
@@ -213,37 +269,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" && prop[TARGET]) {
props[key] = useState(prop);
}
}
props = useState(props);
currentNode = null;
const prom = Promise.all(this.willUpdateProps.map((f) => f.call(component, props)));
await prom;
@@ -251,8 +291,7 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
return;
}
component.props = props;
this.props = rawProps;
fiber.render();
this._render(fiber);
const parentRoot = parentFiber.root!;
if (this.willPatch.length) {
parentRoot.willPatch.push(fiber);
@@ -296,19 +335,12 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
return bdom ? bdom.firstNode() : undefined;
}
*nodes(): Generator<Node> {
if (this.bdom) {
yield* this.bdom.nodes();
}
}
mount(parent: HTMLElement, anchor: ChildNode) {
const bdom = this.fiber!.bdom!;
this.bdom = bdom;
bdom.mount(parent, anchor);
this.status = STATUS.MOUNTED;
this.fiber!.appliedToDom = true;
this.children = this.fiber!.childrenMap;
this.fiber = null;
}
@@ -325,15 +357,12 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
}
}
_patch() {
let hasChildren = false;
for (let _k in this.children) {
hasChildren = true;
break;
const hasChildren = Object.keys(this.children).length > 0;
this.bdom!.patch(this!.fiber!.bdom!, hasChildren);
if (hasChildren) {
this.cleanOutdatedChildren();
}
const fiber = this.fiber!;
this.children = fiber.childrenMap;
this.bdom!.patch(fiber.bdom!, hasChildren);
fiber.appliedToDom = true;
this.fiber!.appliedToDom = true;
this.fiber = null;
}
@@ -345,6 +374,20 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
this.bdom!.remove();
}
cleanOutdatedChildren() {
const children = this.children;
for (const key in children) {
const node = children[key];
const status = node.status;
if (status !== STATUS.MOUNTED) {
delete children[key];
if (status !== STATUS.DESTROYED) {
node.destroy();
}
}
}
}
// ---------------------------------------------------------------------------
// Some debug helpers
// ---------------------------------------------------------------------------
@@ -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,22 @@ 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) {
fiber.root!.counter--;
}
return true;
}
}
@@ -42,14 +40,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 +54,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 +62,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,14 +16,8 @@ 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;
root.counter = root.counter + 1 - cancelFibers(current.children);
current.children = [];
current.childrenMap = {};
current.bdom = null;
if (fibersInError.has(current)) {
fibersInError.delete(current);
@@ -42,23 +36,13 @@ 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
*/
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;
fiber.node.fiber = null;
if (fiber.bdom) {
// if fiber has been rendered, this means that the component props have
// been updated. however, this fiber will not be patched to the dom, so
@@ -66,7 +50,7 @@ function cancelFibers(fibers: Fiber[]): number {
// the same props, and skip the render completely. With the next line,
// we kindly request the component code to force a render, so it works as
// expected.
node.forceNextRender = true;
fiber.node.forceNextRender = true;
} else {
result++;
}
@@ -83,7 +67,6 @@ export class Fiber {
children: Fiber[] = [];
appliedToDom = false;
deep: boolean = false;
childrenMap: ComponentNode["children"] = {};
constructor(node: ComponentNode, parent: Fiber | null) {
this.node = node;
@@ -91,50 +74,13 @@ export class Fiber {
if (parent) {
this.deep = parent.deep;
const root = parent.root!;
root.setCounter(root.counter + 1);
root.counter++;
this.root = root;
parent.children.push(this);
} else {
this.root = this as any;
}
}
render() {
// if some parent has a fiber => register in followup
let prev = this.root!.node;
let scheduler = prev.app.scheduler;
let current = prev.parent;
while (current) {
if (current.fiber) {
let root = current.fiber.root!;
if (root.counter === 0 && prev.parentKey! in current.fiber.childrenMap) {
current = root.node;
} else {
scheduler.delayedRenders.push(this);
return;
}
}
prev = current;
current = current.parent;
}
// there are no current rendering from above => we can render
this._render();
}
_render() {
const node = this.node;
const root = this.root;
if (root) {
try {
(this.bdom as any) = true;
this.bdom = node.renderFn();
} catch (e) {
node.app.handleError({ node, error: e });
}
root.setCounter(root.counter - 1);
}
}
}
export class RootFiber extends Fiber {
@@ -195,14 +141,7 @@ export class RootFiber extends Fiber {
}
} catch (e) {
this.locked = false;
node.app.handleError({ fiber: current || this, error: e });
}
}
setCounter(newValue: number) {
this.counter = newValue;
if (newValue === 0) {
this.node.app.scheduler.flush();
handleError({ fiber: current || this, error: e });
}
}
}
@@ -226,7 +165,6 @@ export class MountFiber extends RootFiber {
let current: Fiber | undefined = this;
try {
const node = this.node;
node.children = this.childrenMap;
(node.app.constructor as any).validateTarget(this.target);
if (node.bdom) {
// this is a complicated situation: if we mount a fiber with an existing
@@ -259,7 +197,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,42 +1,28 @@
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 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(() => {}),
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber) {
console.warn(timeoutError);
}
});
}
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;
}
+77
View File
@@ -0,0 +1,77 @@
import { fibersInError } from "./error_handling";
import { Fiber, RootFiber } from "./fibers";
import { STATUS } from "./status";
// -----------------------------------------------------------------------------
// Scheduler
// -----------------------------------------------------------------------------
export class Scheduler {
// capture the value of requestAnimationFrame as soon as possible, to avoid
// interactions with other code, such as test frameworks that override them
static requestAnimationFrame = window.requestAnimationFrame.bind(window);
tasks: Set<RootFiber> = new Set();
isRunning: boolean = false;
requestAnimationFrame: Window["requestAnimationFrame"];
constructor() {
this.requestAnimationFrame = Scheduler.requestAnimationFrame;
}
start() {
this.isRunning = true;
this.scheduleTasks();
}
stop() {
this.isRunning = false;
}
addFiber(fiber: Fiber) {
this.tasks.add(fiber.root!);
if (!this.isRunning) {
this.start();
}
}
/**
* Process all current tasks. This only applies to the fibers that are ready.
* Other tasks are left unchanged.
*/
flush() {
this.tasks.forEach((fiber) => {
if (fiber.root !== fiber) {
this.tasks.delete(fiber);
return;
}
const hasError = fibersInError.has(fiber);
if (hasError && fiber.counter !== 0) {
this.tasks.delete(fiber);
return;
}
if (fiber.node.status === STATUS.DESTROYED) {
this.tasks.delete(fiber);
return;
}
if (fiber.counter === 0) {
if (!hasError) {
fiber.complete();
}
this.tasks.delete(fiber);
}
});
if (this.tasks.size === 0) {
this.stop();
}
}
scheduleTasks() {
this.requestAnimationFrame(() => {
this.flush();
if (this.isRunning) {
this.scheduleTasks();
}
});
}
}
+3 -39
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
@@ -127,39 +127,3 @@ export function useExternalListener(
onMounted(() => target.addEventListener(eventName, boundHandler, eventParams));
onWillUnmount(() => target.removeEventListener(eventName, boundHandler, eventParams));
}
// -----------------------------------------------------------------------------
// useRoots
// -----------------------------------------------------------------------------
interface DomRangeObj {
node: Node | null;
elem: HTMLElement | null;
elems: Iterable<HTMLElement>;
nodes: Iterable<Node>;
}
export function useRoots(): DomRangeObj {
const cnode = getCurrent();
function* _elems(): Generator<HTMLElement> {
for (let node of cnode.nodes()) {
if (node.nodeType === 1) {
yield node as HTMLElement;
}
}
}
return {
get node() {
return cnode.nodes().next().value || null;
},
get elem() {
return _elems().next().value || null;
},
get nodes() {
return cnode.nodes();
},
get elems() {
return _elems();
},
};
}
+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__ = {};
+5 -15
View File
@@ -1,7 +1,7 @@
import { onWillUnmount } from "./lifecycle_hooks";
import { onWillUnmount } from "./component/lifecycle_hooks";
import { xml } from "./utils";
import { BDom, text, VNode } from "./blockdom";
import { Component } from "./component";
import { OwlError } from "./error_handling";
import { Component } from "./component/component";
const VText: any = text("").constructor;
@@ -25,7 +25,7 @@ class VPortal extends VText implements Partial<VNode<VPortal>> {
}
this.target = el && el.querySelector(this.selector);
if (!this.target) {
throw new OwlError("invalid portal target");
throw new Error("invalid portal target");
}
}
this.realBDom!.mount(this.target!, null);
@@ -53,18 +53,8 @@ class VPortal extends VText implements Partial<VNode<VPortal>> {
}
}
/**
* <t t-slot="default"/>
*/
export function portalTemplate(app: any, bdom: any, helpers: any) {
let { callSlot } = helpers;
return function template(ctx: any, node: any, key = "") {
return callSlot(ctx, node, key, "default", false, null);
};
}
export class Portal extends Component {
static template = "__portal__";
static template = xml`<t t-slot="default"/>`;
static props = {
target: {
type: String,
@@ -1,5 +1,4 @@
import { Callback } from "./utils";
import { OwlError } from "./error_handling";
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
export const TARGET = Symbol("Target");
@@ -198,7 +197,7 @@ export function reactive<T extends Target>(
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 (SKIP in target) {
return target as NonReactive<T>;
@@ -208,7 +207,7 @@ export function reactive<T extends Target>(
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)) {
@@ -233,11 +232,6 @@ function basicProxyHandler<T extends Target>(callback: Callback): ProxyHandler<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, proxy);
}
observeTargetKey(target, key, callback);
return possiblyReactive(Reflect.get(target, key, proxy), callback);
},
-68
View File
@@ -1,68 +0,0 @@
import {
config,
createBlock,
html,
list,
mount as blockMount,
multi,
patch,
remove,
text,
toggler,
comment,
} from "./blockdom";
import { mainEventHandler } from "./event_handling";
export type { Reactive } from "./reactivity";
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,
useRoots,
} 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__ = {};
-76
View File
@@ -1,76 +0,0 @@
import { fibersInError } from "./error_handling";
import { Fiber, RootFiber } from "./fibers";
import { STATUS } from "./status";
// -----------------------------------------------------------------------------
// Scheduler
// -----------------------------------------------------------------------------
export class Scheduler {
// capture the value of requestAnimationFrame as soon as possible, to avoid
// interactions with other code, such as test frameworks that override them
static requestAnimationFrame = window.requestAnimationFrame.bind(window);
tasks: Set<RootFiber> = new Set();
requestAnimationFrame: Window["requestAnimationFrame"];
frame: number = 0;
delayedRenders: Fiber[] = [];
constructor() {
this.requestAnimationFrame = Scheduler.requestAnimationFrame;
}
addFiber(fiber: Fiber) {
this.tasks.add(fiber.root!);
}
/**
* Process all current tasks. This only applies to the fibers that are ready.
* Other tasks are left unchanged.
*/
flush() {
if (this.delayedRenders.length) {
let renders = this.delayedRenders;
this.delayedRenders = [];
for (let f of renders) {
if (f.root && f.node.status !== STATUS.DESTROYED && f.node.fiber === f) {
f.render();
}
}
}
if (this.frame === 0) {
this.frame = this.requestAnimationFrame(() => {
this.frame = 0;
this.tasks.forEach((fiber) => this.processFiber(fiber));
for (let task of this.tasks) {
if (task.node.status === STATUS.DESTROYED) {
this.tasks.delete(task);
}
}
});
}
}
processFiber(fiber: RootFiber) {
if (fiber.root !== fiber) {
this.tasks.delete(fiber);
return;
}
const hasError = fibersInError.has(fiber);
if (hasError && fiber.counter !== 0) {
this.tasks.delete(fiber);
return;
}
if (fiber.node.status === STATUS.DESTROYED) {
this.tasks.delete(fiber);
return;
}
if (fiber.counter === 0) {
if (!hasError) {
fiber.complete();
}
this.tasks.delete(fiber);
}
}
}
-271
View File
@@ -1,271 +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.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 = ObjectCreate(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 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;
constructor(fn: any, ctx: any, component: any, node: any) {
this.fn = fn;
this.ctx = capture(ctx);
this.component = component;
this.node = node;
}
evaluate(): any {
return this.fn.call(this.component, 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, 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(ctx: any, fn: Function): Function {
let component = ctx.__owl__.component;
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;
}
};
}
/**
* 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, node?: any) {
const ComponentClass =
typeof name !== "string"
? name
: (node.component.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 (node.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,
shallowEqual,
toNumber,
validateProps,
LazyValue,
safeOutput,
bind,
createCatcher,
markRaw,
OwlError,
};
-169
View File
@@ -1,169 +0,0 @@
import { OwlError } from "./error_handling";
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);
}
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;
}
+24 -19
View File
@@ -1,4 +1,3 @@
import { OwlError } from "./error_handling";
export type Callback = () => void;
/**
@@ -16,30 +15,22 @@ export function batched(callback: Callback): Callback {
await Promise.resolve();
if (!called) {
called = true;
// wait for all calls in this microtick to fall through before resetting "called"
// so that only the first call to the batched function calls the original callback.
// Schedule this before calling the callback so that calls to the batched function
// within the callback will proceed only after resetting called to false, and have
// a chance to execute the callback again
Promise.resolve().then(() => (called = false));
callback();
// wait for all calls in this microtick to fall through before resetting "called"
// so that only the first call to the batched function calls the original callback
await Promise.resolve();
called = false;
}
};
}
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 +52,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 +71,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";
//------------------------------------------------------------------------------
+2 -14
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";
//------------------------------------------------------------------------------
@@ -169,25 +169,13 @@ describe("properties", () => {
expect(input.value).toBe("potato");
});
test("input with value attribute, and falsy value given", () => {
test("input with value attribute, and undefined given", () => {
const block = createBlock(`<input block-attribute-0="value"/>`);
const tree = block([undefined]);
mount(tree, fixture);
const input = fixture.querySelector("input")!;
expect(input.value).toBe("");
patch(tree, block([null]));
expect(input.value).toBe("");
patch(tree, block([0]));
expect(input.value).toBe("0");
patch(tree, block([""]));
expect(input.value).toBe("");
patch(tree, block([false]));
expect(input.value).toBe("");
});
test("input type=checkbox with checked attribute", () => {
+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,23 +374,10 @@ exports[`attributes static attributes on void elements 1`] = `
}"
`;
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\\"/>\`);
@@ -456,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\\"/>\`);
@@ -485,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\\"/>\`);
@@ -499,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\\"/>\`);
@@ -512,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\\"/>\`);
@@ -541,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\\"/>\`);
@@ -554,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\\"/>\`);
@@ -597,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\\"/>\`);
@@ -611,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\\"/>\`);
@@ -625,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\\"/>\`);
@@ -639,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\\"/>\`);
@@ -653,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\\"/>\`);
@@ -667,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\\"/>\`);
@@ -680,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\\"/>\`);
@@ -695,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\\"/>\`);
@@ -708,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\\"/>\`);
@@ -739,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>\`);
@@ -752,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,9 +515,9 @@ 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>\`);
+28 -31
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 } = 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>
@@ -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 -264
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']);
@@ -335,10 +337,11 @@ exports[`t-call (template calling) inherit context 2`] = `
`;
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>\`);
@@ -353,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>\`);
@@ -374,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>\`);
@@ -408,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>\`);
@@ -429,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>\`);
@@ -463,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>\`);
@@ -485,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>\`);
@@ -521,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>\`);
@@ -544,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\`);
@@ -555,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>\`);
@@ -579,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']);
@@ -590,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>\`);
@@ -605,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>\`);
@@ -617,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>\`);
@@ -667,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>\`);
@@ -682,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>\`);
@@ -700,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>\`);
@@ -713,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>\`);
@@ -734,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>\`);
@@ -748,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>\`);
@@ -782,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>\`);
@@ -796,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>\`);
@@ -815,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>\`);
@@ -849,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>\`);
@@ -865,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>\`);
@@ -894,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>\`);
@@ -907,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>\`);
@@ -920,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>\`);
@@ -1001,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>\`);
@@ -1015,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);
@@ -1032,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>\`);
@@ -1045,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);
@@ -1063,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>\`);
@@ -1076,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);
@@ -1093,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>\`);
@@ -1108,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>\`);
@@ -1129,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);
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);
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);
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>\`);
+17 -32
View File
@@ -1,25 +1,9 @@
// 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 block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
return function template(ctx, node, key = \\"\\") {
const refs = ctx.__owl__.refs;
const v1 = ctx['id'];
let ref1 = (el) => refs[\`myspan\${v1}\`] = el;
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 { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
@@ -33,9 +17,9 @@ exports[`t-ref can get a dynamic ref on a node, alternate syntax 1`] = `
`;
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 { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><span block-ref=\\"0\\"/></div>\`);
@@ -48,10 +32,11 @@ exports[`t-ref can get a ref on a node 1`] = `
`;
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>\`);
@@ -63,9 +48,9 @@ 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 { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>1<span block-ref=\\"0\\"/>2</div>\`);
@@ -78,9 +63,9 @@ exports[`t-ref ref in a t-call 2`] = `
`;
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 { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block2 = createBlock(\`<span block-ref=\\"0\\"/>\`);
@@ -98,9 +83,9 @@ 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 { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, withKey } = helpers;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
@@ -115,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 = (el) => refs[(v1)] = el;
let ref1 = (el) => refs[\`\${v1}\`] = el;
let txt1 = ctx['item'];
c_block2[i1] = withKey(block3([ref1, txt1]), tKey_1 + key1);
}
@@ -126,9 +111,9 @@ 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 { 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\\"/>\`);
+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);
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);
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);
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);
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));
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));
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));
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 -114
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();
@@ -22,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">`);
@@ -39,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);
@@ -63,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 });
@@ -161,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);
@@ -278,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", () => {
@@ -295,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", () => {
@@ -329,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"/>`;
@@ -458,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 -4
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();
// -----------------------------------------------------------------------------
+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 -34
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,
},
});
});
@@ -1384,25 +1370,6 @@ describe("qweb parser", () => {
});
});
test("a component with an empty named slot", async () => {
expect(parse(`<MyComponent><t t-set-slot="mySlot"></t></MyComponent>`)).toEqual({
dynamicProps: null,
isDynamic: false,
name: "MyComponent",
on: null,
props: null,
slots: {
mySlot: {
attrs: null,
content: null,
on: null,
scope: null,
},
},
type: 11,
});
});
test("a component with a named slot", async () => {
expect(parse(`<MyComponent><t t-set-slot="name">foo</t></MyComponent>`)).toEqual({
type: ASTType.TComponent,
@@ -1561,7 +1528,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
-34
View File
@@ -445,38 +445,4 @@ describe("t-call (template calling)", () => {
const expected2 = "<div><bar>quux</bar></div>";
expect(context.renderToString("main", { template: "bar", val: "quux" })).toBe(expected2);
});
test("t-call-context", () => {
const context = new TestContext();
context.addTemplate("sub", `<span><t t-esc="value"/></span>`);
context.addTemplate("main", `<t t-call="sub" t-call-context="obj"/>`);
expect(context.renderToString("main", { obj: { value: 123 } })).toBe("<span>123</span>");
});
test("t-call on a div with t-call-context", () => {
const context = new TestContext();
context.addTemplate("sub", `<span><t t-esc="value"/></span>`);
context.addTemplate("main", `<div t-call="sub" t-call-context="obj"/>`);
expect(context.renderToString("main", { obj: { value: 123 } })).toBe(
"<div><span>123</span></div>"
);
});
test("t-call-context and value in body", () => {
const context = new TestContext();
context.addTemplate("sub", `<span><t t-esc="value1"/><t t-esc="value2"/></span>`);
context.addTemplate(
"main",
`
<t t-call="sub" t-call-context="obj">
<t t-set="value2" t-value="aaron" />
</t>`
);
expect(context.renderToString("main", { obj: { value1: 123 }, aaron: "lucas" })).toBe(
"<span>123lucas</span>"
);
});
});
+1 -16
View File
@@ -1,4 +1,4 @@
import { mount } from "../../src/runtime/blockdom";
import { mount } from "../../src/blockdom";
import {
makeTestFixture,
renderToBdom,
@@ -67,21 +67,6 @@ describe("t-esc", () => {
);
});
test("t-esc with the 0 number", () => {
const template = `<t t-esc="var"/>`;
expect(renderToString(template, { var: 0 })).toBe("0");
});
test("t-esc with the 0 number, in a p", () => {
const template = `<p><t t-esc="var"/></p>`;
expect(renderToString(template, { var: 0 })).toBe("<p>0</p>");
});
test("top level t-esc with undefined", () => {
const template = `<t t-esc="var"/>`;
expect(renderToString(template, { var: undefined })).toBe("");
});
test("falsy values in text nodes", () => {
const template = `
<t t-esc="v1"/>:<t t-esc="v2"/>:<t t-esc="v3"/>:<t t-esc="v4"/>:<t t-esc="v5"/>`;
+1 -1
View File
@@ -5,7 +5,7 @@ import {
TestContext,
makeTestFixture,
} from "../helpers";
import { mount, patch } from "../../src/runtime/blockdom";
import { mount, patch } from "../../src/blockdom";
snapshotEverything();
+1 -1
View File
@@ -1,5 +1,5 @@
// import { mountBlock } from "../../src/blockdom/block";
import { mount } from "../../src/runtime/blockdom";
import { mount } from "../../src/blockdom";
import { makeTestFixture, renderToBdom, renderToString, snapshotEverything } from "../helpers";
snapshotEverything();

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