mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14ceb382ef | |||
| 9846b2e997 | |||
| cfc2fb2ba2 | |||
| d57017b6ed | |||
| 5bf7a5c671 | |||
| 9b589af75a | |||
| 471fd49063 | |||
| 4fc3423682 | |||
| ffb3263c79 | |||
| e1acf66143 | |||
| 2a40907e35 | |||
| 1c0dd79955 |
@@ -18,20 +18,16 @@ related projects. OWL's main features are:
|
||||
|
||||
Here is a short example to illustrate interactive components:
|
||||
|
||||
```xml
|
||||
<templates>
|
||||
<button t-name="Counter" t-on-click="increment">
|
||||
Click Me! [<t t-esc="state.value"/>]
|
||||
</button>
|
||||
<div t-name="App">
|
||||
<span>Hello Owl</span>
|
||||
<Counter />
|
||||
</div>
|
||||
</templates>
|
||||
```
|
||||
|
||||
```javascript
|
||||
class Counter extends owl.Component {
|
||||
import { Component, QWeb } from 'owl'
|
||||
import { xml } from 'owl/tags'
|
||||
|
||||
class Counter extends Component {
|
||||
static template = xml`
|
||||
<button t-on-click="increment">
|
||||
Click Me! [<t t-esc="state.value"/>]
|
||||
</button>`;
|
||||
|
||||
state = { value: 0 };
|
||||
|
||||
increment() {
|
||||
@@ -39,17 +35,22 @@ class Counter extends owl.Component {
|
||||
}
|
||||
}
|
||||
|
||||
class App extends owl.Component {
|
||||
components = { Counter };
|
||||
class App extends Component {
|
||||
static template = xml`
|
||||
<div>
|
||||
<span>Hello Owl</span>
|
||||
<Counter />
|
||||
</div>`;
|
||||
|
||||
static components = { Counter };
|
||||
|
||||
}
|
||||
|
||||
const qweb = new owl.QWeb(TEMPLATES);
|
||||
const app = new App({ qweb });
|
||||
const app = new App({ qweb: new QWeb() });
|
||||
app.mount(document.body);
|
||||
```
|
||||
|
||||
Note that we assume here that the xml templates are available in the `TEMPLATES`
|
||||
string. More interesting examples can be found on the
|
||||
More interesting examples can be found on the
|
||||
[playground](https://odoo.github.io/owl/playground) application.
|
||||
|
||||
## OWL's Design Principles
|
||||
@@ -69,7 +70,7 @@ requirements are common and code needs to be maintained by large teams.
|
||||
it is not ok to use standard web tools based on `npm`.
|
||||
|
||||
Owl is not designed to be fast nor small (even though it is quite good on those
|
||||
two topics). It is a no nonsense framework to build applications. There is only
|
||||
two topics). It is a no nonsense framework to build applications. There is only
|
||||
one way to define components (with classes).
|
||||
|
||||
If you are interested in a comparison with React or Vue, you will
|
||||
@@ -90,8 +91,8 @@ Submit a PR!
|
||||
|
||||
If you want to use a simple `<script>` tag, the last release can be downloaded here:
|
||||
|
||||
- [owl-0.20.0.js](https://github.com/odoo/owl/releases/download/v0.20.0/owl.js)
|
||||
- [owl-0.20.0.min.js](https://github.com/odoo/owl/releases/download/v0.20.0/owl.min.js)
|
||||
- [owl-0.21.0.js](https://github.com/odoo/owl/releases/download/v0.21.0/owl.js)
|
||||
- [owl-0.21.0.min.js](https://github.com/odoo/owl/releases/download/v0.21.0/owl.min.js)
|
||||
|
||||
Some npm scripts are available:
|
||||
|
||||
|
||||
+4
-4
@@ -31,11 +31,11 @@ than React and Vue. Also, jQuery is not the same kind of framework, but it is in
|
||||
|
||||
## Class Based
|
||||
|
||||
Both React and Vue moved away from defining components with classes. They prefer
|
||||
Both React and Vue moved away from defining components with classes. They prefer
|
||||
a more functional approach, in particular, with the new `hooks` mechanisms.
|
||||
|
||||
This has some advantages and disadvantages. But the end result is that React
|
||||
and Vue both offers multiple different ways of defining new components. In
|
||||
This has some advantages and disadvantages. But the end result is that React
|
||||
and Vue both offers multiple different ways of defining new components. In
|
||||
contrast, Owl has only one mechanism: class-based components. We believe that Owl
|
||||
components are fast enough for all our usecases, and making it as simple as
|
||||
possible for developers is more valuable (for us).
|
||||
@@ -233,4 +233,4 @@ class Counter extends owl.ConnectedComponent {
|
||||
}
|
||||
|
||||
const counter = new Counter({ store, qweb });
|
||||
```
|
||||
```
|
||||
|
||||
+38
-12
@@ -72,7 +72,7 @@ Note that this code is written in ESNext style, so it will only run on the
|
||||
latest browsers without a transpilation step.
|
||||
|
||||
This example show how a component should be defined: it simply subclasses the
|
||||
Component class. If no `template` key is defined, then
|
||||
Component class. If no static `template` key is defined, then
|
||||
Owl will use the component's name as template name. Here,
|
||||
a state object is defined. It is not mandatory to use the state object, but it
|
||||
is certainly encouraged. The state object is [observed](observer.md), and any
|
||||
@@ -96,9 +96,6 @@ find a template with the component name (or one of its ancestor).
|
||||
|
||||
- **`env`** (Object): the component environment, which contains a QWeb instance.
|
||||
|
||||
- **`template`** (string, optional): if given, this is the name of the QWeb template that will render
|
||||
the component.
|
||||
|
||||
- **`state`** (Object): this is the location of the component's state, if there is
|
||||
any. After the willStart method, the `state` property is observed, and each
|
||||
change will cause the component to rerender itself.
|
||||
@@ -113,7 +110,20 @@ find a template with the component name (or one of its ancestor).
|
||||
|
||||
### Static Properties
|
||||
|
||||
- **`props`** (Object, optional): if given, this is an object that describes the
|
||||
- **`template`** (string, optional): if given, this is the name of the QWeb template that will render the component. Note that there is a helper `xml` to
|
||||
make it easy to define an inline template.
|
||||
|
||||
* **`components`** (Object, optional): if given, this is an object that contains
|
||||
the classes of any sub components needed by the template. This is the main way
|
||||
used by Owl to be able to create sub components.
|
||||
|
||||
```js
|
||||
class ParentComponent extends owl.Component {
|
||||
static components = { SubComponent };
|
||||
}
|
||||
```
|
||||
|
||||
* **`props`** (Object, optional): if given, this is an object that describes the
|
||||
type and shape of the (actual) props given to the component. If Owl mode is
|
||||
`dev`, this will be used to validate the props each time the component is
|
||||
created/updated. See [Props Validation](#props-validation) for more information.
|
||||
@@ -127,7 +137,7 @@ find a template with the component name (or one of its ancestor).
|
||||
}
|
||||
```
|
||||
|
||||
* **`defaultProps`** (Object, optional): if given, this object define default
|
||||
- **`defaultProps`** (Object, optional): if given, this object define default
|
||||
values for (top-level) props. Whenever `props` are given to the object, they
|
||||
will be altered to add default value (if missing). Note that it does not
|
||||
change the initial object, a new object will be created instead.
|
||||
@@ -420,7 +430,7 @@ to be capitalized.
|
||||
|
||||
```js
|
||||
class ParentComponent extends owl.Component {
|
||||
components = { MyComponent: MyComponent};
|
||||
static components = { MyComponent: MyComponent};
|
||||
...
|
||||
}
|
||||
```
|
||||
@@ -442,16 +452,16 @@ that the template can access `state`, `props`, `env`, or any methods defined in
|
||||
|
||||
```js
|
||||
class ParentComponent {
|
||||
components = { ChildComponent };
|
||||
static components = { ChildComponent };
|
||||
state = { val: 4 };
|
||||
}
|
||||
```
|
||||
|
||||
Whenever the template is rendered, it will automatically create the subcomponent
|
||||
`ChildComponent` at the correct place. It needs to find the reference to the
|
||||
actual component class in the special `components` key, or the class registered in
|
||||
actual component class in the special static `components` key, or the class registered in
|
||||
QWeb's global registry (see `register` function of QWeb). It first looks inside
|
||||
the local `components` key, then fallbacks on the global registry.
|
||||
the static `components` key, then fallbacks on the global registry.
|
||||
|
||||
_Props_: In this example, the child component will receive the object `{count: 4}` in its
|
||||
constructor. This will be assigned to the `props` variable, which can be accessed
|
||||
@@ -461,7 +471,8 @@ the sub component will also be updated automatically.
|
||||
Note that there are some restrictions on prop names: `class`, `style` and any
|
||||
string which starts with `t-` are not allowed.
|
||||
|
||||
The `t-component` directive can also be used to accept dynamic values with string interpolation (like the [`t-attf-`](qweb.md#dynamic-attributes) directive):
|
||||
It is not common, but sometimes we need a dynamic component name and/or dynamic props. In this case,
|
||||
the `t-component` directive can also be used to accept dynamic values with string interpolation (like the [`t-attf-`](qweb.md#dynamic-attributes) directive):
|
||||
|
||||
```xml
|
||||
<div t-name="ParentComponent">
|
||||
@@ -471,11 +482,26 @@ The `t-component` directive can also be used to accept dynamic values with strin
|
||||
|
||||
```js
|
||||
class ParentComponent {
|
||||
components = { ChildComponent1, ChildComponent2 };
|
||||
static components = { ChildComponent1, ChildComponent2 };
|
||||
state = { id: 1 };
|
||||
}
|
||||
```
|
||||
|
||||
And the `t-props` directive can be used to specify totally dynamic props:
|
||||
|
||||
```xml
|
||||
<div t-name="ParentComponent">
|
||||
<Child t-props="some.obj"/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```js
|
||||
class ParentComponent {
|
||||
static components = { Child };
|
||||
some = { obj: { a: 1, b: 2 } };
|
||||
}
|
||||
```
|
||||
|
||||
**CSS and style:** there is some specific support to allow the parent to declare
|
||||
additional css classes or style for the sub component: css declared in `class`, `style`, `t-att-class` or `t-att-style` will be added to the
|
||||
root component element.
|
||||
|
||||
+1
-1
@@ -73,9 +73,9 @@ Let us now add the javascript to make it work, in `app.js`:
|
||||
|
||||
```javascript
|
||||
class ClickCounter extends owl.Component {
|
||||
static template = "clickcounter";
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.template = "clickcounter";
|
||||
this.state = { value: 0 };
|
||||
}
|
||||
|
||||
|
||||
+22
-13
@@ -65,16 +65,16 @@ We present here a list of all standard QWeb directives:
|
||||
The component system in Owl requires additional directives, to express various
|
||||
needs. Here is a list of all Owl specific directives:
|
||||
|
||||
| Name | Description |
|
||||
| ------------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `t-component`, `t-keepalive`, `t-asyncroot` | [Defining a sub component](component.md#composition) |
|
||||
| `t-ref` | [Setting a reference to a dom node or a sub component](component.md#references) |
|
||||
| `t-key` | [Defining a key (to help virtual dom reconciliation)](component.md#t-key-directive) |
|
||||
| `t-on-*` | [Event handling](component.md#event-handling) |
|
||||
| `t-transition` | [Defining an animation](animations.md#css-transitions) |
|
||||
| `t-mounted` | [Callback when a node or component is mounted](component.md#t-mounted-directive) |
|
||||
| `t-slot` | [Rendering a slot](component.md#slots) |
|
||||
| `t-model` | [Form input bindings](component.md#form-input-bindings) |
|
||||
| Name | Description |
|
||||
| ------------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
||||
| `t-component`, `t-props`, `t-keepalive`, `t-asyncroot` | [Defining a sub component](component.md#composition) |
|
||||
| `t-ref` | [Setting a reference to a dom node or a sub component](component.md#references) |
|
||||
| `t-key` | [Defining a key (to help virtual dom reconciliation)](component.md#t-key-directive) |
|
||||
| `t-on-*` | [Event handling](component.md#event-handling) |
|
||||
| `t-transition` | [Defining an animation](animations.md#css-transitions) |
|
||||
| `t-mounted` | [Callback when a node or component is mounted](component.md#t-mounted-directive) |
|
||||
| `t-slot` | [Rendering a slot](component.md#slots) |
|
||||
| `t-model` | [Form input bindings](component.md#form-input-bindings) |
|
||||
|
||||
## QWeb Engine
|
||||
|
||||
@@ -101,7 +101,7 @@ It's API is quite simple:
|
||||
qweb.addTemplate("mytemplate", "<div>hello</div>");
|
||||
```
|
||||
|
||||
If the optional `allowDuplicate` is set to `true`, then `QWeb` will simply return whenever a template is added for a second time. Otherwise, `QWeb` will crash.
|
||||
If the optional `allowDuplicate` is set to `true`, then `QWeb` will simply return whenever a template is added for a second time. Otherwise, `QWeb` will crash.
|
||||
|
||||
- **`addTemplates(xmlStr)`**: add a list of templates (identified by `t-name`
|
||||
attribute).
|
||||
@@ -129,14 +129,23 @@ It's API is quite simple:
|
||||
const str = qweb.renderToString("someTemplate", somecontext);
|
||||
```
|
||||
|
||||
- **`register(name, Component)`**: static function to register an OWL Component
|
||||
- **`registerTemplate(name, template)`**: static function to register an global
|
||||
QWeb template. This is useful for commonly used components accross the
|
||||
application, and for making a template available to an application without
|
||||
having a reference to the actual QWeb instance.
|
||||
|
||||
```js
|
||||
QWeb.registerTemplate("mytemplate", `<div>some template`);
|
||||
```
|
||||
|
||||
- **`registerComponent(name, Component)`**: static function to register an OWL Component
|
||||
to QWeb's global registry. Globally registered Components can be used in
|
||||
templates (see the `t-component` directive). This is useful for commonly used
|
||||
components accross the application.
|
||||
|
||||
```js
|
||||
class Dialog extends owl.Component { ... }
|
||||
QWeb.register("Dialog", Dialog);
|
||||
QWeb.registerComponent("Dialog", Dialog);
|
||||
|
||||
...
|
||||
|
||||
|
||||
+6
-2
@@ -3,7 +3,7 @@
|
||||
## Owl Content
|
||||
|
||||
Owl is a javascript library that contains some core classes and function to help
|
||||
build applications. Here is a complete representation of its content:
|
||||
build applications. Here is a complete representation of its content:
|
||||
|
||||
```
|
||||
owl
|
||||
@@ -14,10 +14,13 @@ owl
|
||||
Observer
|
||||
router
|
||||
Link
|
||||
RouteComponent
|
||||
Router
|
||||
store
|
||||
Store
|
||||
ConnectedComponent
|
||||
tags
|
||||
xml
|
||||
utils
|
||||
debounce
|
||||
escape
|
||||
@@ -35,6 +38,7 @@ owl
|
||||
- [QWeb](qweb.md)
|
||||
- [Router](router.md)
|
||||
- [Store](store.md)
|
||||
- [Tags](tags.md)
|
||||
- [Utils](utils.md)
|
||||
- [Virtual DOM](vdom.md)
|
||||
|
||||
@@ -46,4 +50,4 @@ owl
|
||||
|
||||
- [Comparison with React/Vue](comparison.md)
|
||||
- [Tooling](tooling.md)
|
||||
- [Templates to start Owl applications (external link)](https://github.com/ged-odoo/owl-templates)
|
||||
- [Templates to start Owl applications (external link)](https://github.com/ged-odoo/owl-templates)
|
||||
|
||||
+7
-8
@@ -8,7 +8,7 @@
|
||||
- [Route Definition](#route-definition)
|
||||
- [Router](#router)
|
||||
- [Navigation Guards](#navigation-guards)
|
||||
- [`t-routecomponent`](#t-routecomponent)
|
||||
- [RouteComponent](#routecomponent)
|
||||
- [Link](#link)
|
||||
|
||||
## Overview
|
||||
@@ -26,8 +26,8 @@ The Owl router support the following features:
|
||||
- route redirection
|
||||
- navigation guards
|
||||
- parameterized routes
|
||||
- a `<Link>` component
|
||||
- a `t-routecomponent` directive
|
||||
- a `<Link/>` component
|
||||
- a `<RouteComponent/>` component
|
||||
|
||||
Note that it is still in early stage of developments, and there are probably
|
||||
still some issues.
|
||||
@@ -125,7 +125,7 @@ The router also has a `navigate` method, useful to programmatically change the
|
||||
application to another state (and the url):
|
||||
|
||||
```js
|
||||
router.navigate({to: 'USER', params: {id: 51}});
|
||||
router.navigate({ to: "USER", params: { id: 51 } });
|
||||
```
|
||||
|
||||
### Navigation Guards
|
||||
@@ -148,19 +148,18 @@ async function protectRoute({ env, to }) {
|
||||
A navigation guard is a function that returns a promise, which either resolves
|
||||
to `true` (the navigation is accepted), or to another destination object.
|
||||
|
||||
### `t-routecomponent`
|
||||
### `RouteComponent`
|
||||
|
||||
The `t-routecomponent` directive directs Owl to render the component associated
|
||||
The `RouteComponent` component directs Owl to render the component associated
|
||||
to the currently active route (if any):
|
||||
|
||||
```xml
|
||||
<div t-name="App">
|
||||
<NavBar />
|
||||
<t t-routecomponent="1"/>
|
||||
<RouteComponent />
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
### `Link`
|
||||
|
||||
The `Link` component is a Owl component which render as a `<a>` tag with any
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
# 🦉 Tags 🦉
|
||||
|
||||
Tags are very small helper to make it easy to write inline templates. There is
|
||||
only one currently available tag: `xml`, but we plan to add other tags later,
|
||||
such as a `css` tag, which will be used to write single file components.
|
||||
|
||||
## XML tag
|
||||
|
||||
Without tags, creating a standalone component would look like this:
|
||||
|
||||
```js
|
||||
import { Component } from 'owl'
|
||||
|
||||
const name = 'some-unique-name';
|
||||
const template = `
|
||||
<div>
|
||||
<span t-if="somecondition">text</span>
|
||||
<button t-on-click="someMethod">Click</button>
|
||||
</div>
|
||||
`;
|
||||
QWeb.registerTemplate(name, template);
|
||||
|
||||
class MyComponent extends Component {
|
||||
static template = name;
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
With tags, this process is slightly simplified. The name is uniquely generated,
|
||||
and the template is automatically registered:
|
||||
|
||||
```js
|
||||
import { Component } from 'owl'
|
||||
import { xml } from 'owl/tags'
|
||||
|
||||
class MyComponent extends Component {
|
||||
static template = xml`
|
||||
<div>
|
||||
<span t-if="somecondition">text</span>
|
||||
<button t-on-click="someMethod">Click</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
+1
-1
@@ -38,7 +38,7 @@ Note that templates compiled with the `prod` settings will not be recompiled.
|
||||
So, changing this setting is best done at startup.
|
||||
|
||||
An important job done by the `dev` mode is to validate props for each component
|
||||
creation and update. Also, extra props will cause an error.
|
||||
creation and update. Also, extra props will cause an error.
|
||||
|
||||
## Playground
|
||||
|
||||
|
||||
+1
-3
@@ -18,9 +18,7 @@ not ready yet, resolved directly otherwise). If called with a callback as
|
||||
argument, it executes it as soon as the DOM ready (or directly).
|
||||
|
||||
```js
|
||||
Promise.all([loadTemplates(), owl.utils.whenReady()]).then(function([
|
||||
templates
|
||||
]) {
|
||||
Promise.all([loadTemplates(), owl.utils.whenReady()]).then(function([templates]) {
|
||||
const qweb = new owl.QWeb(templates);
|
||||
const app = new App({ qweb });
|
||||
app.mount(document.body);
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "owl",
|
||||
"version": "0.20.0",
|
||||
"name": "owl-framework",
|
||||
"version": "0.21.0",
|
||||
"description": "Odoo Web Library (OWL)",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
@@ -21,11 +21,12 @@
|
||||
"url": "git+https://github.com/odoo/owl.git"
|
||||
},
|
||||
"author": "Odoo",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"license": "LGPL",
|
||||
"bugs": {
|
||||
"url": "https://github.com/odoo/owl/issues"
|
||||
},
|
||||
"homepage": "https://github.com/odoo/owl#readme",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^23.3.12",
|
||||
"cpx": "^1.5.0",
|
||||
@@ -42,7 +43,6 @@
|
||||
"typescript": "^3.2.2",
|
||||
"uglify-es": "^3.3.9"
|
||||
},
|
||||
"dependencies": {},
|
||||
"jest": {
|
||||
"roots": [
|
||||
"<rootDir>/src",
|
||||
|
||||
+15
-21
@@ -70,12 +70,6 @@ interface Internal<T extends Env, Props> {
|
||||
classObj: { [key: string]: boolean } | null;
|
||||
}
|
||||
|
||||
// If a component does not define explicitely a template
|
||||
// key, it needs to find a template with its name (or a parent's). This is
|
||||
// qweb dependant, so we need a place to store this information indexed by
|
||||
// qweb instances.
|
||||
const TEMPLATE_MAP: { [key: number]: { [name: string]: string } } = {};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Component
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -83,7 +77,8 @@ let nextId = 1;
|
||||
|
||||
export class Component<T extends Env, Props extends {}, State extends {}> {
|
||||
readonly __owl__: Internal<Env, Props>;
|
||||
template?: string;
|
||||
static template?: string | null = null;
|
||||
static _template?: string | null = null;
|
||||
|
||||
/**
|
||||
* The `el` is the root element of the component. Note that it could be null:
|
||||
@@ -92,6 +87,7 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
|
||||
get el(): HTMLElement | null {
|
||||
return this.__owl__.vnode ? (<any>this).__owl__.vnode.elm : null;
|
||||
}
|
||||
static components = {};
|
||||
|
||||
env: T;
|
||||
state?: State;
|
||||
@@ -526,30 +522,28 @@ export class Component<T extends Env, Props extends {}, State extends {}> {
|
||||
return Promise.resolve(h("div"));
|
||||
}
|
||||
const qweb = this.env.qweb;
|
||||
if (!this.template) {
|
||||
let tmap = TEMPLATE_MAP[qweb.id];
|
||||
if (!tmap) {
|
||||
tmap = {};
|
||||
TEMPLATE_MAP[qweb.id] = tmap;
|
||||
}
|
||||
let p = (<any>this).constructor;
|
||||
let name: string = p.name;
|
||||
let template = tmap[name];
|
||||
if (template) {
|
||||
this.template = template;
|
||||
let p = (<any>this).constructor;
|
||||
// console.warn(p, p.template, p._template, 'template' in p, p.hasOwnProperty('template'))
|
||||
if (!p.hasOwnProperty("_template")) {
|
||||
if (p.template) {
|
||||
p._template = p.template;
|
||||
} else {
|
||||
// here, the component and none of its superclasses defines a static `template`
|
||||
// key. So we fall back on looking for a template matching its name (or
|
||||
// one of its subclass).
|
||||
|
||||
let template: string;
|
||||
while ((template = p.name) && !(template in qweb.templates) && p !== Component) {
|
||||
p = p.__proto__;
|
||||
}
|
||||
if (p === Component) {
|
||||
throw new Error(`Could not find template for component "${this.constructor.name}"`);
|
||||
} else {
|
||||
tmap[name] = template;
|
||||
this.template = template;
|
||||
p._template = template;
|
||||
}
|
||||
}
|
||||
}
|
||||
__owl__.render = qweb.render.bind(qweb, this.template);
|
||||
__owl__.render = qweb.render.bind(qweb, p._template);
|
||||
this.__observeState();
|
||||
|
||||
return this.__render(false, [], scope, vars);
|
||||
|
||||
@@ -194,6 +194,7 @@ QWeb.addDirective({
|
||||
ctx.rootContext.shouldDefineParent = true;
|
||||
ctx.rootContext.shouldDefineUtils = true;
|
||||
let keepAlive = node.getAttribute("t-keepalive") ? true : false;
|
||||
let hasDynamicProps = node.getAttribute("t-props") ? true : false;
|
||||
let async = node.getAttribute("t-asyncroot") ? true : false;
|
||||
|
||||
// t-on- events and t-transition
|
||||
@@ -372,7 +373,12 @@ QWeb.addDirective({
|
||||
ctx.addLine(`result = vn${id};`);
|
||||
}
|
||||
}
|
||||
ctx.addLine(`let props${componentID} = {${propStr}};`);
|
||||
if (hasDynamicProps) {
|
||||
const dynamicProp = ctx.formatExpression(node.getAttribute("t-props")!);
|
||||
ctx.addLine(`let props${componentID} = Object.assign({${propStr}}, ${dynamicProp});`);
|
||||
} else {
|
||||
ctx.addLine(`let props${componentID} = {${propStr}};`);
|
||||
}
|
||||
ctx.addIf(
|
||||
`w${componentID} && w${componentID}.__owl__.renderPromise && !w${componentID}.__owl__.vnode`
|
||||
);
|
||||
@@ -388,7 +394,7 @@ QWeb.addDirective({
|
||||
// new component
|
||||
ctx.addLine(`let componentKey${componentID} = ${ctx.interpolate(value)};`);
|
||||
ctx.addLine(
|
||||
`let W${componentID} = context.components && context.components[componentKey${componentID}] || QWeb.components[componentKey${componentID}];`
|
||||
`let W${componentID} = context.constructor.components[componentKey${componentID}] || QWeb.components[componentKey${componentID}];`
|
||||
);
|
||||
// maybe only do this in dev mode...
|
||||
ctx.addLine(
|
||||
@@ -413,7 +419,7 @@ QWeb.addDirective({
|
||||
|
||||
const clone = <Element>node.cloneNode(true);
|
||||
const slotNodes = clone.querySelectorAll("[t-set]");
|
||||
const slotId = qweb.nextSlotId++;
|
||||
const slotId = QWeb.nextSlotId++;
|
||||
ctx.addLine(`w${componentID}.__owl__.slotId = ${slotId};`);
|
||||
if (slotNodes.length) {
|
||||
for (let i = 0, length = slotNodes.length; i < length; i++) {
|
||||
@@ -422,7 +428,7 @@ QWeb.addDirective({
|
||||
const key = slotNode.getAttribute("t-set")!;
|
||||
slotNode.removeAttribute("t-set");
|
||||
const slotFn = qweb._compile(`slot_${key}_template`, slotNode, ctx);
|
||||
qweb.slots[`${slotId}_${key}`] = slotFn;
|
||||
QWeb.slots[`${slotId}_${key}`] = slotFn;
|
||||
}
|
||||
}
|
||||
if (clone.childNodes.length) {
|
||||
@@ -431,7 +437,7 @@ QWeb.addDirective({
|
||||
t.appendChild(child);
|
||||
}
|
||||
const slotFn = qweb._compile(`slot_default_template`, t, ctx);
|
||||
qweb.slots[`${slotId}_default`] = slotFn;
|
||||
QWeb.slots[`${slotId}_default`] = slotFn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -10,16 +10,18 @@ import { QWeb } from "./qweb/index";
|
||||
import { ConnectedComponent } from "./store/connected_component";
|
||||
import { Store } from "./store/store";
|
||||
import * as _utils from "./utils";
|
||||
import * as _tags from "./tags";
|
||||
import { Link } from "./router/Link";
|
||||
import { RouteComponent } from "./router/RouteComponent";
|
||||
import { Router } from "./router/Router";
|
||||
|
||||
export { Component } from "./component/component";
|
||||
export { QWeb };
|
||||
export const core = { EventBus, Observer };
|
||||
export const router = { Router, Link };
|
||||
export const router = { Router, RouteComponent, Link };
|
||||
export const store = { Store, ConnectedComponent };
|
||||
export const utils = _utils;
|
||||
|
||||
export const tags = _tags;
|
||||
export const __info__ = {};
|
||||
|
||||
Object.defineProperty(__info__, "mode", {
|
||||
|
||||
@@ -55,6 +55,7 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) {
|
||||
ctx.rootContext.rootNode = nodeID;
|
||||
ctx.rootContext.parentTextNode = nodeID;
|
||||
ctx.addLine(`var vn${nodeID} = {text: ${exprID}};`);
|
||||
ctx.addLine(`result = vn${nodeID}`);
|
||||
}
|
||||
} else {
|
||||
let fragID = ctx.generateID();
|
||||
@@ -200,6 +201,7 @@ QWeb.addDirective({
|
||||
// extract variables from nodecopy
|
||||
const tempCtx = new Context();
|
||||
tempCtx.nextID = ctx.rootContext.nextID;
|
||||
tempCtx.allowMultipleRoots = true;
|
||||
qweb._compileNode(nodeCopy, tempCtx);
|
||||
const vars = Object.assign({}, ctx.variables, tempCtx.variables);
|
||||
ctx.rootContext.nextID = tempCtx.nextID;
|
||||
|
||||
+4
-1
@@ -19,7 +19,7 @@ export class Context {
|
||||
shouldDefineParent: boolean = false;
|
||||
shouldDefineQWeb: boolean = false;
|
||||
shouldDefineUtils: boolean = false;
|
||||
shouldDefineResult: boolean = false;
|
||||
shouldDefineResult: boolean = true;
|
||||
shouldProtectContext: boolean = false;
|
||||
shouldTrackScope: boolean = false;
|
||||
inLoop: boolean = false;
|
||||
@@ -93,6 +93,9 @@ export class Context {
|
||||
if (!this.rootContext.rootNode) {
|
||||
this.rootContext.rootNode = node;
|
||||
}
|
||||
if (!this.parentNode) {
|
||||
this.addLine(`result = vn${node};`);
|
||||
}
|
||||
return this.subContext("parentNode", node);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,9 @@ QWeb.addDirective({
|
||||
atNodeEncounter({ ctx, value }): boolean {
|
||||
const slotKey = ctx.generateID();
|
||||
ctx.rootContext.shouldDefineOwner = true;
|
||||
ctx.addLine(`const slot${slotKey} = this.slots[context.__owl__.slotId + '_' + '${value}'];`);
|
||||
ctx.addLine(
|
||||
`const slot${slotKey} = this.constructor.slots[context.__owl__.slotId + '_' + '${value}'];`
|
||||
);
|
||||
ctx.addIf(`slot${slotKey}`);
|
||||
ctx.addLine(
|
||||
`slot${slotKey}.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c${ctx.parentNode}, vars: extra.vars, parent: owner}));`
|
||||
|
||||
+28
-11
@@ -125,13 +125,11 @@ function parseXML(xml: string): Document {
|
||||
return doc;
|
||||
}
|
||||
|
||||
let nextID = 1;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// QWeb rendering engine
|
||||
//------------------------------------------------------------------------------
|
||||
export class QWeb extends EventBus {
|
||||
templates: { [name: string]: Template } = {};
|
||||
templates: { [name: string]: Template };
|
||||
static utils = UTILS;
|
||||
static components = Object.create(null);
|
||||
|
||||
@@ -143,19 +141,18 @@ export class QWeb extends EventBus {
|
||||
};
|
||||
static DIRECTIVES: Directive[] = [];
|
||||
|
||||
static TEMPLATES: { [name: string]: Template } = {};
|
||||
|
||||
static nextId: number = 1;
|
||||
|
||||
h = h;
|
||||
// dev mode enables better error messages or more costly validations
|
||||
static dev: boolean = false;
|
||||
|
||||
// the id field is useful to be able to hash qweb instances. The current
|
||||
// use case is that component's templates are qweb dependant, and need to be
|
||||
// able to map a qweb instance to a template name.
|
||||
id = nextID++;
|
||||
|
||||
// slots contains sub templates defined with t-set inside t-component nodes, and
|
||||
// are meant to be used by the t-slot directive.
|
||||
slots = {};
|
||||
nextSlotId = 1;
|
||||
static slots = {};
|
||||
static nextSlotId = 1;
|
||||
|
||||
// recursiveTemplates contains sub templates called with t-call, but which
|
||||
// ends up in recursive situations. This is very similar to the slot situation,
|
||||
@@ -166,6 +163,7 @@ export class QWeb extends EventBus {
|
||||
|
||||
constructor(data?: string) {
|
||||
super();
|
||||
this.templates = Object.create(QWeb.TEMPLATES);
|
||||
if (data) {
|
||||
this.addTemplates(data);
|
||||
}
|
||||
@@ -183,13 +181,27 @@ export class QWeb extends EventBus {
|
||||
}
|
||||
}
|
||||
|
||||
static register(name: string, Component: any) {
|
||||
static registerComponent(name: string, Component: any) {
|
||||
if (QWeb.components[name]) {
|
||||
throw new Error(`Component '${name}' has already been registered`);
|
||||
}
|
||||
QWeb.components[name] = Component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register globally a template. All QWeb instances will obtain their
|
||||
* templates from their own template map, and then, from the global static
|
||||
* TEMPLATES property.
|
||||
*/
|
||||
static registerTemplate(name: string, template: string) {
|
||||
if (QWeb.TEMPLATES[name]) {
|
||||
throw new Error(`Template '${name}' has already been registered`);
|
||||
}
|
||||
const qweb = new QWeb();
|
||||
qweb.addTemplate(name, template);
|
||||
QWeb.TEMPLATES[name] = qweb.templates[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a template to the internal template map. Note that it is not
|
||||
* immediately compiled.
|
||||
@@ -326,6 +338,9 @@ export class QWeb extends EventBus {
|
||||
_compile(name: string, elem: Element, parentContext?: Context): CompiledTemplate {
|
||||
const isDebug = elem.attributes.hasOwnProperty("t-debug");
|
||||
const ctx = new Context(name);
|
||||
if (elem.tagName !== "t") {
|
||||
ctx.shouldDefineResult = false;
|
||||
}
|
||||
if (parentContext) {
|
||||
ctx.templates = Object.create(parentContext.templates);
|
||||
ctx.variables = Object.create(parentContext.variables);
|
||||
@@ -333,6 +348,7 @@ export class QWeb extends EventBus {
|
||||
ctx.parentNode = parentContext.parentNode!;
|
||||
ctx.allowMultipleRoots = true;
|
||||
ctx.hasParentWidget = true;
|
||||
ctx.shouldDefineResult = false;
|
||||
ctx.addLine(`let c${ctx.parentNode} = extra.parentNode;`);
|
||||
|
||||
for (let v in parentContext.variables) {
|
||||
@@ -405,6 +421,7 @@ export class QWeb extends EventBus {
|
||||
// template rendering.
|
||||
let nodeID = ctx.generateID();
|
||||
ctx.addLine(`var vn${nodeID} = {text: \`${text}\`};`);
|
||||
ctx.addLine(`result = vn${nodeID};`);
|
||||
ctx.rootContext.rootNode = nodeID;
|
||||
ctx.rootContext.parentTextNode = nodeID;
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,18 +1,18 @@
|
||||
import { Component } from "../component/component";
|
||||
import { xml } from "../tags";
|
||||
import { Destination, RouterEnv } from "./Router";
|
||||
|
||||
export const LINK_TEMPLATE_NAME = "__owl__-router-link";
|
||||
export const LINK_TEMPLATE = `
|
||||
<a t-att-class="{'router-link-active': isActive }"
|
||||
t-att-href="href"
|
||||
t-on-click="navigate">
|
||||
<t t-slot="default"/>
|
||||
</a>`;
|
||||
|
||||
type Props = Destination;
|
||||
|
||||
export class Link<Env extends RouterEnv> extends Component<Env, Props, {}> {
|
||||
template = LINK_TEMPLATE_NAME;
|
||||
static template = xml`
|
||||
<a t-att-class="{'router-link-active': isActive }"
|
||||
t-att-href="href"
|
||||
t-on-click="navigate">
|
||||
<t t-slot="default"/>
|
||||
</a>
|
||||
`;
|
||||
|
||||
href: string = this.env.router.destToPath(this.props);
|
||||
|
||||
async willUpdateProps(nextProps) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component } from "../component/component";
|
||||
import { xml } from "../tags";
|
||||
|
||||
export class RouteComponent extends Component<any, {}, {}> {
|
||||
static template = xml`
|
||||
<t t-foreach="routes" t-as="route">
|
||||
<t t-if="env.router.currentRouteName === route.name">
|
||||
<t t-component="{{route.component}}" t-props="env.router.currentParams"/>
|
||||
</t>
|
||||
</t>
|
||||
`;
|
||||
|
||||
routes: any[] = [];
|
||||
constructor(parent, props) {
|
||||
super(parent, props);
|
||||
const router = this.env.router;
|
||||
for (let name of router.routeIds) {
|
||||
const route = router.routes[name];
|
||||
if (route.component) {
|
||||
this.routes.push({
|
||||
name: route.name,
|
||||
component: "__component__" + route.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Env } from "../component/component";
|
||||
import { QWeb } from "../qweb/index";
|
||||
import { makeDirective } from "./directive";
|
||||
import { LINK_TEMPLATE, LINK_TEMPLATE_NAME } from "./Link";
|
||||
import { shallowEqual } from "../utils";
|
||||
|
||||
type NavigationGuard = (info: {
|
||||
@@ -75,7 +73,7 @@ export class Router {
|
||||
partialRoute.name = "__route__" + nextId++;
|
||||
}
|
||||
if (partialRoute.component) {
|
||||
QWeb.register("__component__" + partialRoute.name, partialRoute.component);
|
||||
QWeb.registerComponent("__component__" + partialRoute.name, partialRoute.component);
|
||||
}
|
||||
if (partialRoute.redirect) {
|
||||
this.validateDestination(partialRoute.redirect);
|
||||
@@ -84,10 +82,6 @@ export class Router {
|
||||
this.routes[partialRoute.name] = partialRoute as Route;
|
||||
this.routeIds.push(partialRoute.name);
|
||||
}
|
||||
|
||||
// setup link and directive
|
||||
env.qweb.addTemplate(LINK_TEMPLATE_NAME, LINK_TEMPLATE);
|
||||
QWeb.addDirective(makeDirective(<RouterEnv>env));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { RouterEnv } from "./Router";
|
||||
|
||||
export function makeDirective(env: RouterEnv) {
|
||||
return {
|
||||
name: "routecomponent",
|
||||
priority: 13,
|
||||
atNodeEncounter({ node }): boolean {
|
||||
let first = true;
|
||||
const router = env.router;
|
||||
for (let name of router.routeIds) {
|
||||
const route = router.routes[name];
|
||||
if (route.component) {
|
||||
// make new t t-component element
|
||||
const comp = node.ownerDocument.createElement("t");
|
||||
comp.setAttribute("t-component", "__component__" + route.name);
|
||||
comp.setAttribute(
|
||||
first ? "t-if" : "t-elif",
|
||||
`env.router.currentRouteName === '${route.name}'`
|
||||
);
|
||||
first = false;
|
||||
for (let param of route.params) {
|
||||
comp.setAttribute(param, `env.router.currentParams.${param}`);
|
||||
}
|
||||
node.appendChild(comp);
|
||||
}
|
||||
}
|
||||
node.removeAttribute("t-routecomponent");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { QWeb } from "./qweb/index";
|
||||
|
||||
/**
|
||||
* Owl Tags
|
||||
*
|
||||
* We have here a (very) small collection of tag functions:
|
||||
*
|
||||
* - xml
|
||||
*
|
||||
* The plan is to add a few other tags such as css, globalcss.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* XML tag helper for defining templates. With this, one can simply define
|
||||
* an inline template with just the template xml:
|
||||
* ```js
|
||||
* class A extends Component {
|
||||
* static template = xml`<div>some template</div>`;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function xml(strings) {
|
||||
const name = `__template__${QWeb.nextId++}`;
|
||||
QWeb.registerTemplate(name, strings[0]);
|
||||
return name;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ exports[`animations t-transition combined with component 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -26,7 +27,7 @@ exports[`animations t-transition combined with component 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -54,6 +55,7 @@ exports[`animations t-transition combined with t-component and t-if 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['state'].display) {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
@@ -71,7 +73,7 @@ exports[`animations t-transition combined with t-component and t-if 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -97,6 +99,7 @@ exports[`animations t-transition with no delay/duration 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
p1.hook = {
|
||||
insert: vn => {
|
||||
utils.transitionInsert(vn, 'jupiler');
|
||||
@@ -117,6 +120,7 @@ exports[`animations t-transition, on a simple node (insert) 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
p1.hook = {
|
||||
insert: vn => {
|
||||
utils.transitionInsert(vn, 'chimay');
|
||||
|
||||
@@ -175,10 +175,10 @@ describe("animations", () => {
|
||||
|
||||
env.qweb.addTemplate("Parent", `<div><Child t-transition="chimay"/></div>`);
|
||||
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||
class Parent extends Widget {
|
||||
components = { Child: Child };
|
||||
}
|
||||
class Child extends Widget {}
|
||||
class Parent extends Widget {
|
||||
static components = { Child: Child };
|
||||
}
|
||||
const widget = new Parent(env);
|
||||
|
||||
let def = makeDeferred();
|
||||
@@ -214,11 +214,11 @@ describe("animations", () => {
|
||||
`<div><t t-if="state.display" t-component="Child" t-transition="chimay"/></div>`
|
||||
);
|
||||
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||
class Child extends Widget {}
|
||||
class Parent extends Widget {
|
||||
components = { Child: Child };
|
||||
static components = { Child: Child };
|
||||
state = { display: true };
|
||||
}
|
||||
class Child extends Widget {}
|
||||
const widget = new Parent(env);
|
||||
|
||||
let def = makeDeferred();
|
||||
@@ -356,7 +356,7 @@ describe("animations", () => {
|
||||
);
|
||||
class Child extends Widget {}
|
||||
class Parent extends Widget {
|
||||
components = { Child };
|
||||
static components = { Child };
|
||||
constructor(parent) {
|
||||
super(parent);
|
||||
this.state = { flag: false };
|
||||
|
||||
@@ -10,6 +10,7 @@ exports[`async rendering delayed component with t-asyncroot directive 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -39,7 +40,7 @@ exports[`async rendering delayed component with t-asyncroot directive 1`] = `
|
||||
}
|
||||
if (!w8) {
|
||||
let componentKey8 = \`Child\`;
|
||||
let W8 = context.components && context.components[componentKey8] || QWeb.components[componentKey8];
|
||||
let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8];
|
||||
if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')}
|
||||
w8 = new W8(parent, props8);
|
||||
parent.__owl__.cmap[8] = w8.__owl__.id;
|
||||
@@ -67,7 +68,7 @@ exports[`async rendering delayed component with t-asyncroot directive 1`] = `
|
||||
}
|
||||
if (!w11) {
|
||||
let componentKey11 = \`AsyncChild\`;
|
||||
let W11 = context.components && context.components[componentKey11] || QWeb.components[componentKey11];
|
||||
let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11];
|
||||
if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')}
|
||||
w11 = new W11(parent, props11);
|
||||
parent.__owl__.cmap[11] = w11.__owl__.id;
|
||||
@@ -92,6 +93,7 @@ exports[`async rendering fast component with t-asyncroot directive 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -122,7 +124,7 @@ exports[`async rendering fast component with t-asyncroot directive 1`] = `
|
||||
}
|
||||
if (!w8) {
|
||||
let componentKey8 = \`Child\`;
|
||||
let W8 = context.components && context.components[componentKey8] || QWeb.components[componentKey8];
|
||||
let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8];
|
||||
if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')}
|
||||
w8 = new W8(parent, props8);
|
||||
parent.__owl__.cmap[8] = w8.__owl__.id;
|
||||
@@ -149,7 +151,7 @@ exports[`async rendering fast component with t-asyncroot directive 1`] = `
|
||||
}
|
||||
if (!w11) {
|
||||
let componentKey11 = \`AsyncChild\`;
|
||||
let W11 = context.components && context.components[componentKey11] || QWeb.components[componentKey11];
|
||||
let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11];
|
||||
if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')}
|
||||
w11 = new W11(parent, props11);
|
||||
parent.__owl__.cmap[11] = w11.__owl__.id;
|
||||
@@ -174,6 +176,7 @@ exports[`async rendering t-component with t-asyncroot directive: mixed re-render
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -203,7 +206,7 @@ exports[`async rendering t-component with t-asyncroot directive: mixed re-render
|
||||
}
|
||||
if (!w8) {
|
||||
let componentKey8 = \`Child\`;
|
||||
let W8 = context.components && context.components[componentKey8] || QWeb.components[componentKey8];
|
||||
let W8 = context.constructor.components[componentKey8] || QWeb.components[componentKey8];
|
||||
if (!W8) {throw new Error('Cannot find the definition of component \\"' + componentKey8 + '\\"')}
|
||||
w8 = new W8(parent, props8);
|
||||
parent.__owl__.cmap[8] = w8.__owl__.id;
|
||||
@@ -231,7 +234,7 @@ exports[`async rendering t-component with t-asyncroot directive: mixed re-render
|
||||
}
|
||||
if (!w11) {
|
||||
let componentKey11 = \`AsyncChild\`;
|
||||
let W11 = context.components && context.components[componentKey11] || QWeb.components[componentKey11];
|
||||
let W11 = context.constructor.components[componentKey11] || QWeb.components[componentKey11];
|
||||
if (!W11) {throw new Error('Cannot find the definition of component \\"' + componentKey11 + '\\"')}
|
||||
w11 = new W11(parent, props11);
|
||||
parent.__owl__.cmap[11] = w11.__owl__.id;
|
||||
@@ -256,6 +259,7 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
const _5 = context['state'].style;
|
||||
@@ -273,7 +277,7 @@ exports[`class and style attributes with t-component dynamic t-att-style is prop
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -298,6 +302,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
const ref5 = \`child\`;
|
||||
@@ -317,7 +322,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -342,6 +347,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
Object.assign(_2, utils.toObj({d:context['state'].d}))
|
||||
let c3 = [], p3 = {key:3,class:_2};
|
||||
var vn3 = h('span', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -356,6 +362,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
const ref5 = \`child\`;
|
||||
@@ -375,7 +382,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -400,6 +407,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
Object.assign(_2, utils.toObj(context['state'].d?'d':''))
|
||||
let c3 = [], p3 = {key:3,class:_2};
|
||||
var vn3 = h('span', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -414,6 +422,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let _5 = {a:context['state'].a,b:context['state'].b};
|
||||
@@ -431,7 +440,7 @@ exports[`class and style attributes with t-component t-att-class is properly add
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -457,6 +466,7 @@ exports[`composition sub components dom state with t-keepalive is preserved 1`]
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['state'].ok) {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
@@ -474,7 +484,7 @@ exports[`composition sub components dom state with t-keepalive is preserved 1`]
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`InputWidget\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -501,6 +511,7 @@ exports[`composition sub components with some state rendered in a loop 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['state'].numbers;
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -533,7 +544,7 @@ exports[`composition sub components with some state rendered in a loop 1`] = `
|
||||
}
|
||||
if (!w7) {
|
||||
let componentKey7 = \`ChildWidget\`;
|
||||
let W7 = context.components && context.components[componentKey7] || QWeb.components[componentKey7];
|
||||
let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7];
|
||||
if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')}
|
||||
w7 = new W7(parent, props7);
|
||||
parent.__owl__.cmap[templateId9] = w7.__owl__.id;
|
||||
@@ -559,6 +570,7 @@ exports[`composition t-component with dynamic value 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -575,7 +587,7 @@ exports[`composition t-component with dynamic value 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = (context['state'].widget);
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -600,6 +612,7 @@ exports[`composition t-component with dynamic value 2 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -616,7 +629,49 @@ exports[`composition t-component with dynamic value 2 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Widget\${context['state'].widget}\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
def3 = w4.__prepare();
|
||||
def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def3 = def3 || w4.__updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||
}
|
||||
extra.promises.push(def3);
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`dynamic t-props basic use 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
let _2_index = c1.length;
|
||||
c1.push(null);
|
||||
let props4 = Object.assign({}, context['some'].obj);
|
||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props4, w4.__owl__.renderProps)) {
|
||||
def3 = w4.__owl__.renderPromise;
|
||||
} else {
|
||||
w4.destroy();
|
||||
w4 = false;
|
||||
}
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -641,6 +696,7 @@ exports[`lifecycle hooks willPatch/patched hook with t-keepalive 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['state'].flag) {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
@@ -658,7 +714,7 @@ exports[`lifecycle hooks willPatch/patched hook with t-keepalive 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`ChildWidget\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -684,6 +740,7 @@ exports[`other directives with t-component t-on with handler bound to argument 1
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -700,7 +757,7 @@ exports[`other directives with t-component t-on with handler bound to argument 1
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -725,6 +782,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -741,7 +799,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -766,6 +824,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -782,7 +841,7 @@ exports[`other directives with t-component t-on with handler bound to empty obje
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -807,6 +866,7 @@ exports[`other directives with t-component t-on with handler bound to object 1`]
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -823,7 +883,7 @@ exports[`other directives with t-component t-on with handler bound to object 1`]
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -848,6 +908,7 @@ exports[`other directives with t-component t-on with prevent and self modifiers
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -864,7 +925,7 @@ exports[`other directives with t-component t-on with prevent and self modifiers
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -889,6 +950,7 @@ exports[`other directives with t-component t-on with self and prevent modifiers
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -905,7 +967,7 @@ exports[`other directives with t-component t-on with self and prevent modifiers
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -930,6 +992,7 @@ exports[`other directives with t-component t-on with self modifier 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -946,7 +1009,7 @@ exports[`other directives with t-component t-on with self modifier 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -971,6 +1034,7 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -987,7 +1051,7 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -1012,6 +1076,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let key5 = 'key' + 'somestring';
|
||||
let def3;
|
||||
@@ -1030,7 +1095,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[templateId6] = w4.__owl__.id;
|
||||
@@ -1056,6 +1121,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['props'].items;
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -1089,7 +1155,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
|
||||
}
|
||||
if (!w7) {
|
||||
let componentKey7 = \`Child\`;
|
||||
let W7 = context.components && context.components[componentKey7] || QWeb.components[componentKey7];
|
||||
let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7];
|
||||
if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')}
|
||||
w7 = new W7(parent, props7);
|
||||
parent.__owl__.cmap[templateId9] = w7.__owl__.id;
|
||||
@@ -1111,6 +1177,7 @@ exports[`t-model directive .lazy modifier 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('input', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1134,6 +1201,7 @@ exports[`t-model directive basic use, on an input 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('input', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1157,6 +1225,7 @@ exports[`t-model directive on a select 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('select', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1201,6 +1270,7 @@ exports[`t-model directive on a sub state key 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('input', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1224,6 +1294,7 @@ exports[`t-model directive on an input type=radio 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'radio';
|
||||
var _3 = 'one';
|
||||
var _4 = 'One';
|
||||
@@ -1260,6 +1331,7 @@ exports[`t-model directive on an input, type=checkbox 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'checkbox';
|
||||
let c3 = [], p3 = {key:3,attrs:{type: _2},on:{}};
|
||||
var vn3 = h('input', p3, c3);
|
||||
@@ -1290,6 +1362,7 @@ exports[`t-slot directive can define and call slots 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -1306,7 +1379,7 @@ exports[`t-slot directive can define and call slots 1`] = `
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Dialog\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
@@ -1329,17 +1402,18 @@ exports[`t-slot directive can define and call slots 2`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('div', p2, c2);
|
||||
c1.push(vn2);
|
||||
const slot3 = this.slots[context.__owl__.slotId + '_' + 'header'];
|
||||
const slot3 = this.constructor.slots[context.__owl__.slotId + '_' + 'header'];
|
||||
if (slot3) {
|
||||
slot3.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c2, vars: extra.vars, parent: owner}));
|
||||
}
|
||||
let c4 = [], p4 = {key:4};
|
||||
var vn4 = h('div', p4, c4);
|
||||
c1.push(vn4);
|
||||
const slot5 = this.slots[context.__owl__.slotId + '_' + 'footer'];
|
||||
const slot5 = this.constructor.slots[context.__owl__.slotId + '_' + 'footer'];
|
||||
if (slot5) {
|
||||
slot5.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c4, vars: extra.vars, parent: owner}));
|
||||
}
|
||||
@@ -1482,7 +1556,8 @@ exports[`t-slot directive slots are rendered with proper context, part 2 1`] = `
|
||||
var _1 = context['props'].to;
|
||||
let c2 = [], p2 = {key:2,attrs:{href: _1}};
|
||||
var vn2 = h('a', p2, c2);
|
||||
const slot3 = this.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
result = vn2;
|
||||
const slot3 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
if (slot3) {
|
||||
slot3.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c2, vars: extra.vars, parent: owner}));
|
||||
}
|
||||
@@ -1502,6 +1577,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('u', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1545,7 +1621,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
|
||||
}
|
||||
if (!w9) {
|
||||
let componentKey9 = \`Link\`;
|
||||
let W9 = context.components && context.components[componentKey9] || QWeb.components[componentKey9];
|
||||
let W9 = context.constructor.components[componentKey9] || QWeb.components[componentKey9];
|
||||
if (!W9) {throw new Error('Cannot find the definition of component \\"' + componentKey9 + '\\"')}
|
||||
w9 = new W9(parent, props9);
|
||||
parent.__owl__.cmap[templateId10] = w9.__owl__.id;
|
||||
@@ -1584,7 +1660,8 @@ exports[`t-slot directive slots are rendered with proper context, part 3 1`] = `
|
||||
var _1 = context['props'].to;
|
||||
let c2 = [], p2 = {key:2,attrs:{href: _1}};
|
||||
var vn2 = h('a', p2, c2);
|
||||
const slot3 = this.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
result = vn2;
|
||||
const slot3 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
if (slot3) {
|
||||
slot3.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c2, vars: extra.vars, parent: owner}));
|
||||
}
|
||||
@@ -1604,6 +1681,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('u', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1648,7 +1726,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
|
||||
}
|
||||
if (!w10) {
|
||||
let componentKey10 = \`Link\`;
|
||||
let W10 = context.components && context.components[componentKey10] || QWeb.components[componentKey10];
|
||||
let W10 = context.constructor.components[componentKey10] || QWeb.components[componentKey10];
|
||||
if (!W10) {throw new Error('Cannot find the definition of component \\"' + componentKey10 + '\\"')}
|
||||
w10 = new W10(parent, props10);
|
||||
parent.__owl__.cmap[templateId11] = w10.__owl__.id;
|
||||
@@ -1688,6 +1766,7 @@ exports[`t-slot directive slots are rendered with proper context, part 4 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'User '+context['state'].user.name;
|
||||
//COMPONENT
|
||||
let def4;
|
||||
@@ -1705,7 +1784,7 @@ exports[`t-slot directive slots are rendered with proper context, part 4 1`] = `
|
||||
}
|
||||
if (!w5) {
|
||||
let componentKey5 = \`Link\`;
|
||||
let W5 = context.components && context.components[componentKey5] || QWeb.components[componentKey5];
|
||||
let W5 = context.constructor.components[componentKey5] || QWeb.components[componentKey5];
|
||||
if (!W5) {throw new Error('Cannot find the definition of component \\"' + componentKey5 + '\\"')}
|
||||
w5 = new W5(parent, props5);
|
||||
parent.__owl__.cmap[5] = w5.__owl__.id;
|
||||
@@ -1759,7 +1838,7 @@ exports[`top level sub widgets basic use 1`] = `
|
||||
}
|
||||
if (!w3) {
|
||||
let componentKey3 = \`Child\`;
|
||||
let W3 = context.components && context.components[componentKey3] || QWeb.components[componentKey3];
|
||||
let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3];
|
||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
||||
w3 = new W3(parent, props3);
|
||||
parent.__owl__.cmap[3] = w3.__owl__.id;
|
||||
@@ -1800,7 +1879,7 @@ exports[`top level sub widgets can select a sub widget 1`] = `
|
||||
}
|
||||
if (!w3) {
|
||||
let componentKey3 = \`Child\`;
|
||||
let W3 = context.components && context.components[componentKey3] || QWeb.components[componentKey3];
|
||||
let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3];
|
||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
||||
w3 = new W3(parent, props3);
|
||||
parent.__owl__.cmap[3] = w3.__owl__.id;
|
||||
@@ -1829,7 +1908,7 @@ exports[`top level sub widgets can select a sub widget 1`] = `
|
||||
}
|
||||
if (!w7) {
|
||||
let componentKey7 = \`OtherChild\`;
|
||||
let W7 = context.components && context.components[componentKey7] || QWeb.components[componentKey7];
|
||||
let W7 = context.constructor.components[componentKey7] || QWeb.components[componentKey7];
|
||||
if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')}
|
||||
w7 = new W7(parent, props7);
|
||||
parent.__owl__.cmap[7] = w7.__owl__.id;
|
||||
|
||||
@@ -14,6 +14,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] =
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
@@ -30,7 +31,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] =
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`Child\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
utils.validateProps(W4, props4)
|
||||
w4 = new W4(parent, props4);
|
||||
|
||||
+597
-499
File diff suppressed because it is too large
Load Diff
@@ -235,7 +235,7 @@ describe("props validation", () => {
|
||||
static props = ["message"];
|
||||
}
|
||||
class App extends Widget {
|
||||
components = { Child };
|
||||
static components = { Child };
|
||||
}
|
||||
const app = new App(env);
|
||||
await app.mount(fixture);
|
||||
|
||||
+22
-1
@@ -5,6 +5,27 @@ import "../src/qweb/base_directives";
|
||||
import "../src/qweb/extensions";
|
||||
import "../src/component/directive";
|
||||
|
||||
// Some static cleanup
|
||||
let nextSlotId;
|
||||
let slots;
|
||||
let nextId;
|
||||
let TEMPLATES;
|
||||
|
||||
beforeEach(() => {
|
||||
nextSlotId = QWeb.nextSlotId;
|
||||
slots = Object.assign({}, QWeb.slots);
|
||||
nextId = QWeb.nextId;
|
||||
TEMPLATES = Object.assign({}, QWeb.TEMPLATES);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
QWeb.nextSlotId = nextSlotId;
|
||||
QWeb.slots = slots;
|
||||
QWeb.nextId = nextId;
|
||||
QWeb.TEMPLATES = TEMPLATES;
|
||||
});
|
||||
|
||||
// helpers
|
||||
export function nextMicroTick(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -82,7 +103,7 @@ export function renderToString(qweb: QWeb, t: string, context: EvalContext = {})
|
||||
const node = renderToDOM(qweb, t, context);
|
||||
const result = node instanceof Text ? node.textContent! : node.outerHTML;
|
||||
if (result !== qweb.renderToString(t, context)) {
|
||||
throw new Error("HTML string returned by renderToString helper does not match QWeb render");
|
||||
throw new Error("HTML string returned by renderToString helper does not match QWeb render");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ exports[`attributes class and t-attf-class with ternary operation 1`] = `
|
||||
var _1 = 'hello ' + (context['value']?'world':'');
|
||||
let c2 = [], p2 = {key:2,attrs:{class: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -18,6 +19,7 @@ exports[`attributes dynamic attribute falsy variable 1`] = `
|
||||
var _1 = context['value'];
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -29,6 +31,7 @@ exports[`attributes dynamic attribute with a dash 1`] = `
|
||||
var _1 = context['id'];
|
||||
let c2 = [], p2 = {key:2,attrs:{\\"data-action-id\\": _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -40,6 +43,7 @@ exports[`attributes dynamic attributes 1`] = `
|
||||
var _1 = 'bar';
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -51,6 +55,7 @@ exports[`attributes dynamic formatted attributes with a dash 1`] = `
|
||||
var _1 = \`Some text \${context['id']}\`;
|
||||
let c2 = [], p2 = {key:2,attrs:{\\"aria-label\\": _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -62,6 +67,7 @@ exports[`attributes fixed variable 1`] = `
|
||||
var _1 = context['value'];
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -73,6 +79,7 @@ exports[`attributes format expression 1`] = `
|
||||
var _1 = (context['value']+37);
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -84,6 +91,7 @@ exports[`attributes format expression, other format 1`] = `
|
||||
var _1 = (context['value']+37);
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -95,6 +103,7 @@ exports[`attributes format literal 1`] = `
|
||||
var _1 = \`bar\`;
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -106,6 +115,7 @@ exports[`attributes format multiple 1`] = `
|
||||
var _1 = \`a \${context['value1']} is \${context['value2']} of \${context['value3']} ]\`;
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -117,6 +127,7 @@ exports[`attributes format value 1`] = `
|
||||
var _1 = \`b\${context['value']}r\`;
|
||||
let c2 = [], p2 = {key:2,attrs:{foo: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -128,6 +139,7 @@ exports[`attributes from object variables set previously 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = {a:'b'};
|
||||
let _3 = utils.toObj(_2.a);
|
||||
let c4 = [], p4 = {key:4,class:_3};
|
||||
@@ -144,6 +156,7 @@ exports[`attributes from variables set previously 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'def';
|
||||
let _3 = utils.toObj(_2);
|
||||
let c4 = [], p4 = {key:4,class:_3};
|
||||
@@ -167,6 +180,7 @@ exports[`attributes object 1`] = `
|
||||
}
|
||||
}
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -180,6 +194,7 @@ exports[`attributes static attributes 1`] = `
|
||||
var _3 = 'c';
|
||||
let c4 = [], p4 = {key:4,attrs:{foo: _1,bar: _2,baz: _3}};
|
||||
var vn4 = h('div', p4, c4);
|
||||
result = vn4;
|
||||
return vn4;
|
||||
}"
|
||||
`;
|
||||
@@ -192,6 +207,7 @@ exports[`attributes static attributes on void elements 1`] = `
|
||||
var _2 = 'Test';
|
||||
let c3 = [], p3 = {key:3,attrs:{src: _1,alt: _2}};
|
||||
var vn3 = h('img', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -203,6 +219,7 @@ exports[`attributes static attributes with dashes 1`] = `
|
||||
var _1 = 'Close';
|
||||
let c2 = [], p2 = {key:2,attrs:{\\"aria-label\\": _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -216,6 +233,7 @@ exports[`attributes t-att-class and class should combine together 1`] = `
|
||||
Object.assign(_2, utils.toObj(context['value']))
|
||||
let c3 = [], p3 = {key:3,class:_2};
|
||||
var vn3 = h('div', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -229,6 +247,7 @@ exports[`attributes t-att-class with object 1`] = `
|
||||
Object.assign(_2, utils.toObj({a:context['b'],c:context['d'],e:context['f']}))
|
||||
let c3 = [], p3 = {key:3,class:_2};
|
||||
var vn3 = h('div', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -240,6 +259,7 @@ exports[`attributes t-attf-class should combine with class 1`] = `
|
||||
var _1 = 'hello ' + \`world\`;
|
||||
let c2 = [], p2 = {key:2,attrs:{class: _1}};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -258,6 +278,7 @@ exports[`attributes tuple literal 1`] = `
|
||||
}
|
||||
}
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -276,6 +297,7 @@ exports[`attributes tuple variable 1`] = `
|
||||
}
|
||||
}
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
return vn2;
|
||||
}"
|
||||
`;
|
||||
@@ -287,6 +309,7 @@ exports[`debugging t-debug 1`] = `
|
||||
debugger;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (true) {
|
||||
debugger;
|
||||
let c2 = [], p2 = {key:2};
|
||||
@@ -304,6 +327,7 @@ exports[`debugging t-log 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 42;
|
||||
console.log(_2+3)
|
||||
return vn1;
|
||||
@@ -317,6 +341,7 @@ exports[`foreach does not pollute the rendering context 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = [1];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -347,6 +372,7 @@ exports[`foreach iterate on items (on a element node) 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = [1,2];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -381,6 +407,7 @@ exports[`foreach iterate on items 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = [3,2,1];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -423,6 +450,7 @@ exports[`foreach iterate, dict param 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['value'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -465,6 +493,7 @@ exports[`foreach iterate, position 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = Array(5);
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -504,6 +533,7 @@ exports[`foreach warn if no key in some case 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = [1,2];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -536,6 +566,7 @@ exports[`loading templates can initialize qweb with a string 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \`jupiler\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -547,6 +578,7 @@ exports[`loading templates can load a few templates from a xml string 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('ul', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('li', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -567,6 +599,7 @@ exports[`misc global 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = [4,5,6];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -651,6 +684,7 @@ exports[`special cases for some boolean html attributes/properties input type= c
|
||||
var _2 = context['flag'];
|
||||
let c3 = [], p3 = {key:3,attrs:{type: _1,checked: _2},props:{checked: _2}};
|
||||
var vn3 = h('input', p3, c3);
|
||||
result = vn3;
|
||||
return vn3;
|
||||
}"
|
||||
`;
|
||||
@@ -661,6 +695,7 @@ exports[`special cases for some boolean html attributes/properties various boole
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'checkbox';
|
||||
var _3 = 'checked';
|
||||
let c4 = [], p4 = {key:4,attrs:{type: _2,checked: _3},props:{checked: _3}};
|
||||
@@ -701,6 +736,7 @@ exports[`static templates div with a span child node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -715,6 +751,7 @@ exports[`static templates div with a text node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \`word\`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -726,6 +763,7 @@ exports[`static templates empty div 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -733,44 +771,75 @@ exports[`static templates empty div 1`] = `
|
||||
exports[`static templates simple dynamic value 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
var _1 = context['text'];
|
||||
if (_1 || _1 === 0) {
|
||||
var vn2 = {text: _1};
|
||||
result = vn2
|
||||
}
|
||||
return vn2;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`static templates simple string 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
var vn1 = {text: \`hello vdom\`};
|
||||
return vn1;
|
||||
result = vn1;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`static templates simple string, with some dynamic value 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
var vn1 = {text: \`hello \`};
|
||||
result = vn1;
|
||||
var _2 = context['text'];
|
||||
if (_2 || _2 === 0) {
|
||||
vn1.text += _2;
|
||||
}
|
||||
return vn1;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-call (template calling basic caller 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \`ok\`});
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-call (template calling call with several sub nodes on same line 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c5 = [], p5 = {key:5};
|
||||
var vn5 = h('div', p5, c5);
|
||||
c1.push(vn5);
|
||||
let c6 = [], p6 = {key:6};
|
||||
var vn6 = h('span', p6, c6);
|
||||
c5.push(vn6);
|
||||
c6.push({text: \`hey\`});
|
||||
c5.push({text: \` \`});
|
||||
let c7 = [], p7 = {key:7};
|
||||
var vn7 = h('span', p7, c7);
|
||||
c5.push(vn7);
|
||||
c7.push({text: \`yay\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -781,6 +850,7 @@ exports[`t-call (template calling inherit context 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 1;
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -796,6 +866,7 @@ exports[`t-call (template calling recursive template, part 1 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -836,6 +907,7 @@ exports[`t-call (template calling recursive template, part 2 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
{
|
||||
let _2 = context['root'];
|
||||
let c3 = [], p3 = {key:3};
|
||||
@@ -927,6 +999,7 @@ exports[`t-call (template calling recursive template, part 3 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
{
|
||||
let _2 = context['root'];
|
||||
let c3 = [], p3 = {key:3};
|
||||
@@ -1015,6 +1088,7 @@ exports[`t-call (template calling scoped parameters 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
{
|
||||
let _2 = 42;
|
||||
c1.push({text: \`ok\`});
|
||||
@@ -1033,6 +1107,7 @@ exports[`t-call (template calling t-call with t-if 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['flag']) {
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
@@ -1046,36 +1121,42 @@ exports[`t-call (template calling t-call with t-if 1`] = `
|
||||
exports[`t-call (template calling with unused body 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
c2.push({text: \`ok\`});
|
||||
return vn2;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-call (template calling with unused setbody 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
{
|
||||
let _1 = 3;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('div', p2, c2);
|
||||
result = vn2;
|
||||
c2.push({text: \`ok\`});
|
||||
}
|
||||
return vn2;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-call (template calling with used body 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('h1', p2, c2);
|
||||
result = vn2;
|
||||
c2.push({text: \`ok\`});
|
||||
return vn2;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -1085,6 +1166,7 @@ exports[`t-call (template calling with used set body 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
{
|
||||
let _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
@@ -1101,6 +1183,7 @@ exports[`t-esc escaping on a node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1115,6 +1198,7 @@ exports[`t-esc escaping on a node with a body 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1131,6 +1215,7 @@ exports[`t-esc escaping on a node with a body, as a default 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['var'];
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1147,6 +1232,7 @@ exports[`t-esc literal 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1161,6 +1247,7 @@ exports[`t-esc variable 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['var'];
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1175,6 +1262,7 @@ exports[`t-if boolean value condition elif 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['color']=='black') {
|
||||
c1.push({text: \`black pearl\`});
|
||||
}
|
||||
@@ -1197,6 +1285,7 @@ exports[`t-if boolean value condition else 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1221,6 +1310,7 @@ exports[`t-if boolean value condition false else 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1245,6 +1335,7 @@ exports[`t-if boolean value condition missing 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
if (context['condition']) {
|
||||
c1.push({text: \`fail\`});
|
||||
}
|
||||
@@ -1258,6 +1349,7 @@ exports[`t-if boolean value false condition 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['condition']) {
|
||||
c1.push({text: \`ok\`});
|
||||
}
|
||||
@@ -1271,6 +1363,7 @@ exports[`t-if boolean value true condition 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['condition']) {
|
||||
c1.push({text: \`ok\`});
|
||||
}
|
||||
@@ -1284,6 +1377,7 @@ exports[`t-if can use some boolean operators in expressions 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
if (context['cond1']&&context['cond2']) {
|
||||
c1.push({text: \`and\`});
|
||||
}
|
||||
@@ -1319,6 +1413,7 @@ exports[`t-key can use t-key directive on a node 1`] = `
|
||||
const nodeKey1 = context['beer'].id
|
||||
let c1 = [], p1 = {key:nodeKey1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['beer'].name;
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1334,6 +1429,7 @@ exports[`t-key t-key directive in a list 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('ul', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['beers'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -1370,6 +1466,7 @@ exports[`t-on can bind event handler 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['add']) {
|
||||
throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1387,6 +1484,7 @@ exports[`t-on can bind handlers with arguments 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['add']) {
|
||||
throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1403,6 +1501,7 @@ exports[`t-on can bind handlers with empty object (with non empty inner string)
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['doSomething']) {
|
||||
throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1419,6 +1518,7 @@ exports[`t-on can bind handlers with empty object 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['doSomething']) {
|
||||
throw new Error('Missing handler \\\\'' + 'doSomething' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1436,6 +1536,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('ul', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = ['someval'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -1474,6 +1575,7 @@ exports[`t-on can bind handlers with object arguments 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['add']) {
|
||||
throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1490,6 +1592,7 @@ exports[`t-on can bind two event handlers 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['handleClick']) {
|
||||
throw new Error('Missing handler \\\\'' + 'handleClick' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1512,6 +1615,7 @@ exports[`t-on handler is bound to proper owner 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1,on:{}};
|
||||
var vn1 = h('button', p1, c1);
|
||||
result = vn1;
|
||||
if (!context['add']) {
|
||||
throw new Error('Missing handler \\\\'' + 'add' + \`\\\\' when evaluating template 'test'\`)
|
||||
}
|
||||
@@ -1529,6 +1633,7 @@ exports[`t-on t-on with prevent and self modifiers (order matters) 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1552,6 +1657,7 @@ exports[`t-on t-on with prevent and/or stop modifiers 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1590,6 +1696,7 @@ exports[`t-on t-on with self and prevent modifiers (order matters) 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1613,6 +1720,7 @@ exports[`t-on t-on with self modifier 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1648,6 +1756,7 @@ exports[`t-raw literal 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
var frag3 = utils.getFragment(_2)
|
||||
@@ -1668,6 +1777,7 @@ exports[`t-raw not escaping 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['var'];
|
||||
if (_2 || _2 === 0) {
|
||||
var frag3 = utils.getFragment(_2)
|
||||
@@ -1688,6 +1798,7 @@ exports[`t-raw t-raw and another sibling node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1712,6 +1823,7 @@ exports[`t-raw variable 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('span', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['var'];
|
||||
if (_2 || _2 === 0) {
|
||||
var frag3 = utils.getFragment(_2)
|
||||
@@ -1731,6 +1843,7 @@ exports[`t-ref can get a dynamic ref on a node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1750,6 +1863,7 @@ exports[`t-ref can get a ref on a node 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
@@ -1770,6 +1884,7 @@ exports[`t-ref refs in a loop 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['items'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _3 = _4 = _2;
|
||||
@@ -1809,6 +1924,7 @@ exports[`t-set evaluate value expression 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 1+2;
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1823,6 +1939,7 @@ exports[`t-set evaluate value expression, part 2 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['somevariable']+2;
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1837,6 +1954,7 @@ exports[`t-set set from attribute literal 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 'ok';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1851,6 +1969,7 @@ exports[`t-set set from attribute lookup 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['value'];
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1862,9 +1981,11 @@ exports[`t-set set from attribute lookup 1`] = `
|
||||
exports[`t-set set from body literal 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let result;
|
||||
var h = this.h;
|
||||
var vn1 = {text: \`ok\`};
|
||||
return vn1;
|
||||
result = vn1;
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -1874,6 +1995,7 @@ exports[`t-set set from body lookup 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['value'];
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1888,6 +2010,7 @@ exports[`t-set set from empty body 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -1898,6 +2021,7 @@ exports[`t-set t-set and t-if 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['value'];
|
||||
if (_2==='ok') {
|
||||
c1.push({text: \`grimbergen\`});
|
||||
@@ -1912,6 +2036,7 @@ exports[`t-set t-set evaluates an expression only once 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = context['value']+' artois';
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1930,6 +2055,7 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 1;
|
||||
var _3 = context['list'];
|
||||
if (!_3) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
@@ -1968,6 +2094,7 @@ exports[`t-set value priority 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
var _2 = 1;
|
||||
if (_2 || _2 === 0) {
|
||||
c1.push({text: _2});
|
||||
@@ -1982,6 +2109,7 @@ exports[`whitespace handling consecutives whitespaces are condensed into a singl
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \` abc \`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -1993,6 +2121,7 @@ exports[`whitespace handling nothing is done in pre tags 1`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('pre', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \` \`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2004,6 +2133,7 @@ exports[`whitespace handling nothing is done in pre tags 2`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('pre', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \`
|
||||
some text
|
||||
\`});
|
||||
@@ -2017,6 +2147,7 @@ exports[`whitespace handling nothing is done in pre tags 3`] = `
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('pre', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \`
|
||||
|
||||
\`});
|
||||
@@ -2030,6 +2161,7 @@ exports[`whitespace handling white space only text nodes are condensed into a si
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
c1.push({text: \` \`});
|
||||
return vn1;
|
||||
}"
|
||||
@@ -2041,6 +2173,7 @@ exports[`whitespace handling whitespace only text nodes with newlines are remove
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
result = vn1;
|
||||
let c2 = [], p2 = {key:2};
|
||||
var vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
|
||||
+44
-6
@@ -11,6 +11,7 @@ import { normalize, renderToDOM, renderToString, trim, nextTick } from "../helpe
|
||||
let qweb: QWeb;
|
||||
|
||||
beforeEach(() => {
|
||||
QWeb.TEMPLATES = {};
|
||||
qweb = new QWeb();
|
||||
});
|
||||
|
||||
@@ -574,6 +575,24 @@ describe("t-call (template calling", () => {
|
||||
expect(trim(renderToString(qweb, "caller"))).toBe(expected);
|
||||
});
|
||||
|
||||
test("call with several sub nodes on same line", () => {
|
||||
qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="SubTemplate">
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
|
||||
<div t-name="main">
|
||||
<t t-call="SubTemplate">
|
||||
<span>hey</span> <span>yay</span>
|
||||
</t>
|
||||
</div>
|
||||
</templates>
|
||||
`);
|
||||
const expected = "<div><div><span>hey</span> <span>yay</span></div></div>";
|
||||
expect(renderToString(qweb, "main")).toBe(expected);
|
||||
});
|
||||
|
||||
test("recursive template, part 1", () => {
|
||||
qweb.addTemplates(`
|
||||
<templates>
|
||||
@@ -589,7 +608,6 @@ describe("t-call (template calling", () => {
|
||||
expect(renderToString(qweb, "recursive")).toBe(expected);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0];
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
|
||||
});
|
||||
|
||||
test("recursive template, part 2", () => {
|
||||
@@ -611,9 +629,9 @@ describe("t-call (template calling", () => {
|
||||
|
||||
</templates>
|
||||
`);
|
||||
const root = { val: "a", children: [{val: "b"}, {val: "c"}]};
|
||||
const root = { val: "a", children: [{ val: "b" }, { val: "c" }] };
|
||||
const expected = "<div><div><p>a</p><div><p>b</p></div><div><p>c</p></div></div></div>";
|
||||
expect(renderToString(qweb, "Parent", {root })).toBe(expected);
|
||||
expect(renderToString(qweb, "Parent", { root })).toBe(expected);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0];
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
});
|
||||
@@ -637,9 +655,10 @@ describe("t-call (template calling", () => {
|
||||
|
||||
</templates>
|
||||
`);
|
||||
const root = { val: "a", children: [{val: "b", children: [{val: "d"}]}, {val: "c"}]};
|
||||
const expected = "<div><div><p>a</p><div><p>b</p><div><p>d</p></div></div><div><p>c</p></div></div></div>";
|
||||
expect(renderToString(qweb, "Parent", {root })).toBe(expected);
|
||||
const root = { val: "a", children: [{ val: "b", children: [{ val: "d" }] }, { val: "c" }] };
|
||||
const expected =
|
||||
"<div><div><p>a</p><div><p>b</p><div><p>d</p></div></div><div><p>c</p></div></div></div>";
|
||||
expect(renderToString(qweb, "Parent", { root })).toBe(expected);
|
||||
const recursiveFn = Object.values(qweb.recursiveFns)[0];
|
||||
expect(recursiveFn.toString()).toMatchSnapshot();
|
||||
});
|
||||
@@ -1260,3 +1279,22 @@ describe("update on event bus", () => {
|
||||
expect(fn).toBeCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("global template registration", () => {
|
||||
test("can register template globally", () => {
|
||||
expect.assertions(5);
|
||||
let qweb = new QWeb();
|
||||
try {
|
||||
qweb.render("mytemplate");
|
||||
} catch (e) {
|
||||
expect(e.message).toMatch("Template mytemplate does not exist");
|
||||
}
|
||||
expect(qweb.templates.mytemplate).toBeUndefined();
|
||||
|
||||
QWeb.registerTemplate("mytemplate", "<div>global</div>");
|
||||
expect(qweb.templates.mytemplate).toBeDefined();
|
||||
const vnode = qweb.render("mytemplate");
|
||||
expect(vnode.sel).toBe("div");
|
||||
expect((vnode as any).children[0].text).toBe("global");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from "../../src/component/component";
|
||||
import { Link, LINK_TEMPLATE_NAME } from "../../src/router/Link";
|
||||
import { Link } from "../../src/router/Link";
|
||||
import { RouterEnv } from "../../src/router/Router";
|
||||
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
||||
import { TestRouter } from "./TestRouter";
|
||||
@@ -31,7 +31,7 @@ describe("Link component", () => {
|
||||
</templates>
|
||||
`);
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Link: Link };
|
||||
static components = { Link: Link };
|
||||
}
|
||||
|
||||
const routes = [{ name: "about", path: "/about" }, { name: "users", path: "/users" }];
|
||||
@@ -50,7 +50,7 @@ describe("Link component", () => {
|
||||
'<div><a href="/about" class="router-link-active">About</a></div>'
|
||||
);
|
||||
|
||||
expect(env.qweb.templates[LINK_TEMPLATE_NAME].fn.toString()).toMatchSnapshot();
|
||||
expect(env.qweb.templates[Link.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("do not redirect if right clicking", async () => {
|
||||
@@ -62,7 +62,7 @@ describe("Link component", () => {
|
||||
</templates>
|
||||
`);
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Link: Link };
|
||||
static components = { Link: Link };
|
||||
}
|
||||
|
||||
const routes = [{ name: "about", path: "/about" }, { name: "users", path: "/users" }];
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Component } from "../../src/component/component";
|
||||
import { RouterEnv } from "../../src/router/Router";
|
||||
import { RouteComponent } from "../../src/router/RouteComponent";
|
||||
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
||||
import { TestRouter } from "./TestRouter";
|
||||
|
||||
describe("router directive t-routecomponent", () => {
|
||||
describe("RouteComponent", () => {
|
||||
let fixture: HTMLElement;
|
||||
let env: RouterEnv;
|
||||
let router: TestRouter | null = null;
|
||||
@@ -25,7 +26,7 @@ describe("router directive t-routecomponent", () => {
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="App">
|
||||
<t t-routecomponent="1" />
|
||||
<RouteComponent />
|
||||
</div>
|
||||
<span t-name="About">About</span>
|
||||
<span t-name="Users">Users</span>
|
||||
@@ -34,7 +35,7 @@ describe("router directive t-routecomponent", () => {
|
||||
class About extends Component<any, any, any> {}
|
||||
class Users extends Component<any, any, any> {}
|
||||
class App extends Component<any, any, any> {
|
||||
components = { About, Users };
|
||||
static components = { RouteComponent };
|
||||
}
|
||||
|
||||
const routes = [
|
||||
@@ -51,21 +52,21 @@ describe("router directive t-routecomponent", () => {
|
||||
await router.navigate({ to: "users" });
|
||||
await nextTick();
|
||||
expect(fixture.innerHTML).toBe("<div><span>Users</span></div>");
|
||||
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
|
||||
expect(env.qweb.templates[RouteComponent.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("can render parameterized route", async () => {
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="App">
|
||||
<t t-routecomponent="1" />
|
||||
<RouteComponent />
|
||||
</div>
|
||||
<span t-name="Book">Book <t t-esc="props.title"/></span>
|
||||
</templates>
|
||||
`);
|
||||
class Book extends Component<any, any, any> {}
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Book };
|
||||
static components = { RouteComponent };
|
||||
}
|
||||
|
||||
const routes = [{ name: "book", path: "/book/{{title}}", component: Book }];
|
||||
@@ -74,14 +75,13 @@ describe("router directive t-routecomponent", () => {
|
||||
const app = new App(env);
|
||||
await app.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe("<div><span>Book 1984</span></div>");
|
||||
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("can render parameterized route with suffixes", async () => {
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="App">
|
||||
<t t-routecomponent="1" />
|
||||
<RouteComponent />
|
||||
</div>
|
||||
<span t-name="Book">Book <t t-esc="props.title"/>|<t t-esc="incVal"/></span>
|
||||
</templates>
|
||||
@@ -92,7 +92,7 @@ describe("router directive t-routecomponent", () => {
|
||||
}
|
||||
}
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Book };
|
||||
static components = { RouteComponent };
|
||||
}
|
||||
|
||||
const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }];
|
||||
@@ -101,6 +101,5 @@ describe("router directive t-routecomponent", () => {
|
||||
const app = new App(env);
|
||||
await app.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe("<div><span>Book 1984|124</span></div>");
|
||||
expect(env.qweb.templates.App.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -4,8 +4,6 @@ import { QWeb } from "../../src/qweb/index";
|
||||
export class TestRouter extends Router {
|
||||
destroy() {
|
||||
window.removeEventListener("popstate", (this as any)._listener);
|
||||
delete QWeb.DIRECTIVE_NAMES.routecomponent;
|
||||
QWeb.DIRECTIVES = QWeb.DIRECTIVES.filter(d => d.name !== "routecomponent");
|
||||
|
||||
// remove component defined inroutes
|
||||
for (let key in QWeb.components) {
|
||||
|
||||
@@ -10,12 +10,13 @@ exports[`Link component can render simple cases 1`] = `
|
||||
var _2 = context['href'];
|
||||
let c3 = [], p3 = {key:3,attrs:{href: _2},class:_1,on:{}};
|
||||
var vn3 = h('a', p3, c3);
|
||||
result = vn3;
|
||||
if (!context['navigate']) {
|
||||
throw new Error('Missing handler \\\\'' + 'navigate' + \`\\\\' when evaluating template '__owl__-router-link'\`)
|
||||
throw new Error('Missing handler \\\\'' + 'navigate' + \`\\\\' when evaluating template '__template__1'\`)
|
||||
}
|
||||
extra.handlers['click' + 3] = extra.handlers['click' + 3] || context['navigate'].bind(owner);
|
||||
p3.on['click'] = extra.handlers['click' + 3];
|
||||
const slot4 = this.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
const slot4 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
|
||||
if (slot4) {
|
||||
slot4.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c3, vars: extra.vars, parent: owner}));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`RouteComponent can render simple cases 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
let result;
|
||||
context = Object.create(context);
|
||||
var h = this.h;
|
||||
var _1 = context['routes'];
|
||||
if (!_1) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
var _2 = _3 = _1;
|
||||
if (!(_1 instanceof Array)) {
|
||||
_2 = Object.keys(_1);
|
||||
_3 = Object.values(_1);
|
||||
}
|
||||
var _length2 = _2.length;
|
||||
for (let i = 0; i < _length2; i++) {
|
||||
context.route_first = i === 0;
|
||||
context.route_last = i === _length2 - 1;
|
||||
context.route_index = i;
|
||||
context.route = _2[i];
|
||||
context.route_value = _3[i];
|
||||
if (context['env'].router.currentRouteName===context['route'].name) {
|
||||
//COMPONENT
|
||||
let def5;
|
||||
let templateId7 = String(-6 - i);
|
||||
let w6 = templateId7 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId7]] : false;
|
||||
let vn8 = {};
|
||||
result = vn8;
|
||||
let props6 = Object.assign({}, context['env'].router.currentParams);
|
||||
if (w6 && w6.__owl__.renderPromise && !w6.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props6, w6.__owl__.renderProps)) {
|
||||
def5 = w6.__owl__.renderPromise;
|
||||
} else {
|
||||
w6.destroy();
|
||||
w6 = false;
|
||||
}
|
||||
}
|
||||
if (!w6) {
|
||||
let componentKey6 = (context['route'].component);
|
||||
let W6 = context.constructor.components[componentKey6] || QWeb.components[componentKey6];
|
||||
if (!W6) {throw new Error('Cannot find the definition of component \\"' + componentKey6 + '\\"')}
|
||||
w6 = new W6(parent, props6);
|
||||
parent.__owl__.cmap[templateId7] = w6.__owl__.id;
|
||||
def5 = w6.__prepare();
|
||||
def5 = def5.then(vnode=>{if (w6.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: templateId7, hook: {insert(vn) {let nvn=w6.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w6.destroy();}}});utils.defineProxy(vn8, pvnode);w6.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def5 = def5 || w6.__updateProps(props6, extra.forceUpdate, extra.patchQueue);
|
||||
def5 = def5.then(()=>{if (w6.__owl__.isDestroyed) {return};let pvnode=w6.__owl__.pvnode;utils.defineProxy(vn8, pvnode);});
|
||||
}
|
||||
extra.promises.push(def5);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}"
|
||||
`;
|
||||
@@ -1,159 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`router directive t-routecomponent can render parameterized route 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
if (context['env'].router.currentRouteName==='book') {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
let _2_index = c1.length;
|
||||
c1.push(null);
|
||||
let props4 = {title:context['env'].router.currentParams.title};
|
||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props4, w4.__owl__.renderProps)) {
|
||||
def3 = w4.__owl__.renderPromise;
|
||||
} else {
|
||||
w4.destroy();
|
||||
w4 = false;
|
||||
}
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`__component__book\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
def3 = w4.__prepare();
|
||||
def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def3 = def3 || w4.__updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||
}
|
||||
extra.promises.push(def3);
|
||||
}
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`router directive t-routecomponent can render parameterized route with suffixes 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
if (context['env'].router.currentRouteName==='book') {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
let _2_index = c1.length;
|
||||
c1.push(null);
|
||||
let props4 = {title:context['env'].router.currentParams.title,val:context['env'].router.currentParams.val};
|
||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props4, w4.__owl__.renderProps)) {
|
||||
def3 = w4.__owl__.renderPromise;
|
||||
} else {
|
||||
w4.destroy();
|
||||
w4 = false;
|
||||
}
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`__component__book\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
def3 = w4.__prepare();
|
||||
def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def3 = def3 || w4.__updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||
}
|
||||
extra.promises.push(def3);
|
||||
}
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`router directive t-routecomponent can render simple cases 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
if (context['env'].router.currentRouteName==='about') {
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let w4 = 4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[4]] : false;
|
||||
let _2_index = c1.length;
|
||||
c1.push(null);
|
||||
let props4 = {};
|
||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props4, w4.__owl__.renderProps)) {
|
||||
def3 = w4.__owl__.renderPromise;
|
||||
} else {
|
||||
w4.destroy();
|
||||
w4 = false;
|
||||
}
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`__component__about\`;
|
||||
let W4 = context.components && context.components[componentKey4] || QWeb.components[componentKey4];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[4] = w4.__owl__.id;
|
||||
def3 = w4.__prepare();
|
||||
def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def3 = def3 || w4.__updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||
}
|
||||
extra.promises.push(def3);
|
||||
}
|
||||
else if (context['env'].router.currentRouteName==='users') {
|
||||
//COMPONENT
|
||||
let def6;
|
||||
let w7 = 7 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[7]] : false;
|
||||
let _5_index = c1.length;
|
||||
c1.push(null);
|
||||
let props7 = {};
|
||||
if (w7 && w7.__owl__.renderPromise && !w7.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props7, w7.__owl__.renderProps)) {
|
||||
def6 = w7.__owl__.renderPromise;
|
||||
} else {
|
||||
w7.destroy();
|
||||
w7 = false;
|
||||
}
|
||||
}
|
||||
if (!w7) {
|
||||
let componentKey7 = \`__component__users\`;
|
||||
let W7 = context.components && context.components[componentKey7] || QWeb.components[componentKey7];
|
||||
if (!W7) {throw new Error('Cannot find the definition of component \\"' + componentKey7 + '\\"')}
|
||||
w7 = new W7(parent, props7);
|
||||
parent.__owl__.cmap[7] = w7.__owl__.id;
|
||||
def6 = w7.__prepare();
|
||||
def6 = def6.then(vnode=>{if (w7.__owl__.isDestroyed){return}let pvnode=h(vnode.sel, {key: 7, hook: {insert(vn) {let nvn=w7.__mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;});
|
||||
} else {
|
||||
def6 = def6 || w7.__updateProps(props7, extra.forceUpdate, extra.patchQueue);
|
||||
def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;c1[_5_index]=pvnode;});
|
||||
}
|
||||
extra.promises.push(def6);
|
||||
}
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -27,13 +27,13 @@ describe("connecting a component to store", () => {
|
||||
<span t-name="Todo"><t t-esc="props.msg"/></span>
|
||||
</templates>
|
||||
`);
|
||||
class Todo extends Component<any, any, any> {}
|
||||
class App extends ConnectedComponent<any, any, any> {
|
||||
components = { Todo };
|
||||
static components = { Todo };
|
||||
static mapStoreToProps(s) {
|
||||
return { todos: s.todos };
|
||||
}
|
||||
}
|
||||
class Todo extends Component<any, any, any> {}
|
||||
const state = { todos: [] };
|
||||
const actions = {
|
||||
addTodo({ state }, msg) {
|
||||
@@ -122,7 +122,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
});
|
||||
class App extends ConnectedComponent<any, any, any> {
|
||||
components = { Todo };
|
||||
static components = { Todo };
|
||||
static mapStoreToProps(s) {
|
||||
return { todos: s.todos };
|
||||
}
|
||||
@@ -200,7 +200,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class Parent extends Component<any, any, any> {
|
||||
components = { Child };
|
||||
static components = { Child };
|
||||
|
||||
constructor(env: Env) {
|
||||
super(env);
|
||||
@@ -248,7 +248,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class TodoList extends ConnectedComponent<any, any, any> {
|
||||
components = { TodoItem };
|
||||
static components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return { todos: state.todos };
|
||||
}
|
||||
@@ -305,7 +305,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class TodoList extends ConnectedComponent<any, any, any> {
|
||||
components = { TodoItem };
|
||||
static components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return { todos: state.todos };
|
||||
}
|
||||
@@ -337,7 +337,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Beer };
|
||||
static components = { Beer };
|
||||
state = { beerId: 1 };
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Beer };
|
||||
static components = { Beer };
|
||||
state = { beerId: 0 };
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Beer };
|
||||
static components = { Beer };
|
||||
state = { beerId: 0 };
|
||||
}
|
||||
|
||||
@@ -559,20 +559,19 @@ describe("connecting a component to store", () => {
|
||||
</templates>
|
||||
`);
|
||||
|
||||
class Parent extends ConnectedComponent<any, any, any> {
|
||||
components = { Child };
|
||||
static mapStoreToProps(s) {
|
||||
steps.push("parent");
|
||||
return { current: s.current, isvisible: s.isvisible };
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends ConnectedComponent<any, any, any> {
|
||||
static mapStoreToProps(s, props) {
|
||||
steps.push("child");
|
||||
return { msg: s.msg[props.key] };
|
||||
}
|
||||
}
|
||||
class Parent extends ConnectedComponent<any, any, any> {
|
||||
static components = { Child };
|
||||
static mapStoreToProps(s) {
|
||||
steps.push("parent");
|
||||
return { current: s.current, isvisible: s.isvisible };
|
||||
}
|
||||
}
|
||||
|
||||
const state = { current: "a", msg: { a: "a", b: "b" } };
|
||||
const actions = {
|
||||
@@ -609,8 +608,14 @@ describe("connecting a component to store", () => {
|
||||
</templates>
|
||||
`);
|
||||
|
||||
class Child extends ConnectedComponent<any, any, any> {
|
||||
static mapStoreToProps(s, props) {
|
||||
steps.push("child");
|
||||
return { msg: s.messages[props.someId] };
|
||||
}
|
||||
}
|
||||
class Parent extends ConnectedComponent<any, any, any> {
|
||||
components = { Child };
|
||||
static components = { Child };
|
||||
static mapStoreToProps(s) {
|
||||
steps.push("parent");
|
||||
return { flag: s.flag, someId: s.someId };
|
||||
@@ -621,13 +626,6 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends ConnectedComponent<any, any, any> {
|
||||
static mapStoreToProps(s, props) {
|
||||
steps.push("child");
|
||||
return { msg: s.messages[props.someId] };
|
||||
}
|
||||
}
|
||||
|
||||
const state = { someId: 1, flag: true, messages: { 1: "abc" } };
|
||||
const actions = {
|
||||
setFlagToFalse({ state }) {
|
||||
@@ -685,15 +683,6 @@ describe("connecting a component to store", () => {
|
||||
</templates>
|
||||
`);
|
||||
|
||||
class TodoApp extends ConnectedComponent<any, any, any> {
|
||||
components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return {
|
||||
todos: state.todos
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let renderCount = 0;
|
||||
let fCount = 0;
|
||||
|
||||
@@ -714,6 +703,14 @@ describe("connecting a component to store", () => {
|
||||
return super.__render(...args);
|
||||
}
|
||||
}
|
||||
class TodoApp extends ConnectedComponent<any, any, any> {
|
||||
static components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return {
|
||||
todos: state.todos
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
(<any>env).store = store;
|
||||
const app = new TodoApp(env);
|
||||
@@ -764,15 +761,6 @@ describe("connecting a component to store", () => {
|
||||
</templates>
|
||||
`);
|
||||
|
||||
class TodoApp extends ConnectedComponent<any, any, any> {
|
||||
components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return {
|
||||
todos: state.todos
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let renderCount = 0;
|
||||
let fCount = 0;
|
||||
|
||||
@@ -794,6 +782,15 @@ describe("connecting a component to store", () => {
|
||||
}
|
||||
}
|
||||
|
||||
class TodoApp extends ConnectedComponent<any, any, any> {
|
||||
static components = { TodoItem };
|
||||
static mapStoreToProps(state) {
|
||||
return {
|
||||
todos: state.todos
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
(<any>env).store = store;
|
||||
const app = new TodoApp(env);
|
||||
|
||||
@@ -879,7 +876,7 @@ describe("connected components and default values", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Greeter };
|
||||
static components = { Greeter };
|
||||
}
|
||||
|
||||
const store = new Store({ state: {} });
|
||||
@@ -903,7 +900,7 @@ describe("connected components and default values", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Greeter };
|
||||
static components = { Greeter };
|
||||
}
|
||||
|
||||
const store = new Store({ state: {} });
|
||||
@@ -948,7 +945,7 @@ describe("connected components and default values", () => {
|
||||
}
|
||||
|
||||
class Thread extends ConnectedComponent<any, any, any> {
|
||||
components = { Message };
|
||||
static components = { Message };
|
||||
static defaultProps = { showMessages: true };
|
||||
static mapStoreToProps = function(state, ownProps) {
|
||||
const thread = state.threads[ownProps.threadId];
|
||||
@@ -959,7 +956,7 @@ describe("connected components and default values", () => {
|
||||
}
|
||||
|
||||
class App extends Component<any, any, any> {
|
||||
components = { Thread };
|
||||
static components = { Thread };
|
||||
static defaultProps = { threadId: 1 };
|
||||
}
|
||||
|
||||
@@ -1026,7 +1023,7 @@ describe("connected components and default values", () => {
|
||||
}
|
||||
|
||||
class Parent extends Component<any, any, any> {
|
||||
components = { Child };
|
||||
static components = { Child };
|
||||
state = { child: true };
|
||||
}
|
||||
|
||||
@@ -1157,7 +1154,7 @@ describe("various scenarios", () => {
|
||||
attachmentIds: state.messages[10].attachmentIds
|
||||
};
|
||||
}
|
||||
components = { Attachment };
|
||||
static components = { Attachment };
|
||||
state = { isAttachmentDeleted: false };
|
||||
doStuff() {
|
||||
this.dispatch("deleteAttachment", 100);
|
||||
|
||||
@@ -15,7 +15,7 @@ class Counter extends owl.Component {
|
||||
// Message Widget
|
||||
//------------------------------------------------------------------------------
|
||||
class Message extends owl.Component {
|
||||
components = { Counter };
|
||||
static components = { Counter };
|
||||
|
||||
shouldUpdate(nextProps) {
|
||||
return nextProps.message !== this.props.message;
|
||||
@@ -31,7 +31,7 @@ class Message extends owl.Component {
|
||||
// Root Widget
|
||||
//------------------------------------------------------------------------------
|
||||
class App extends owl.Component {
|
||||
components = { Message };
|
||||
static components = { Message };
|
||||
state = { messages: [], multipleFlag: false, clearAfterFlag: false };
|
||||
|
||||
mounted() {
|
||||
|
||||
+92
-91
@@ -150,6 +150,97 @@ Promise.all([loadTemplates(), owl.utils.whenReady()]).then(start);
|
||||
return zip.generateAsync({ type: "blob" });
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tabbed editor
|
||||
//------------------------------------------------------------------------------
|
||||
class TabbedEditor extends owl.Component {
|
||||
constructor(parent, props) {
|
||||
super(parent, props);
|
||||
this.state = {
|
||||
currentTab: props.js ? "js" : props.xml ? "xml" : "css"
|
||||
};
|
||||
this.setTab = owl.utils.debounce(this.setTab, 250, true);
|
||||
|
||||
this.sessions = {};
|
||||
this._setupSessions(props);
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.editor = this.editor || ace.edit(this.refs.editor);
|
||||
|
||||
this.editor.setValue(this.props[this.state.currentTab], -1);
|
||||
this.editor.setFontSize("12px");
|
||||
this.editor.setTheme("ace/theme/monokai");
|
||||
this.editor.setSession(this.sessions[this.state.currentTab]);
|
||||
const tabSize = this.state.currentTab === "xml" ? 2 : 4;
|
||||
this.editor.session.setOption("tabSize", tabSize);
|
||||
this.editor.on("blur", () => {
|
||||
const editorValue = this.editor.getValue();
|
||||
const propsValue = this.props[this.state.currentTab];
|
||||
if (editorValue !== propsValue) {
|
||||
this.trigger("updateCode", {
|
||||
type: this.state.currentTab,
|
||||
value: editorValue
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
willUpdateProps(nextProps) {
|
||||
this._setupSessions(nextProps);
|
||||
}
|
||||
|
||||
patched() {
|
||||
const session = this.sessions[this.state.currentTab];
|
||||
let content = this.props[this.state.currentTab];
|
||||
if (content === false) {
|
||||
const tab = this.props.js ? "js" : this.props.xml ? "xml" : "css";
|
||||
content = this.props[tab];
|
||||
this.state.currentTab = tab;
|
||||
}
|
||||
session.setValue(content, -1);
|
||||
this.editor.setSession(session);
|
||||
this.editor.resize();
|
||||
}
|
||||
|
||||
setTab(tab) {
|
||||
if (this.state.currentTab !== tab) {
|
||||
this.state.currentTab = tab;
|
||||
const session = this.sessions[this.state.currentTab];
|
||||
session.doc.setValue(this.props[tab], -1);
|
||||
this.editor.setSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
onMouseDown(ev) {
|
||||
if (ev.target.tagName === "DIV") {
|
||||
let y = ev.clientY;
|
||||
const resizer = ev => {
|
||||
const delta = ev.clientY - y;
|
||||
y = ev.clientY;
|
||||
this.trigger("updatePanelHeight", { delta });
|
||||
};
|
||||
document.body.addEventListener("mousemove", resizer);
|
||||
document.body.addEventListener("mouseup", () => {
|
||||
document.body.removeEventListener("mousemove", resizer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_setupSessions(props) {
|
||||
for (let tab of ["js", "xml", "css"]) {
|
||||
if (props[tab] && !this.sessions[tab]) {
|
||||
this.sessions[tab] = new ace.EditSession(props[tab], MODES[tab]);
|
||||
this.sessions[tab].setOption("useWorker", false);
|
||||
const tabSize = tab === "xml" ? 2 : 4;
|
||||
this.sessions[tab].setOption("tabSize", tabSize);
|
||||
this.sessions[tab].setUndoManager(new ace.UndoManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// MAIN APP
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -158,7 +249,6 @@ class App extends owl.Component {
|
||||
super(...args);
|
||||
this.version = owl.__info__.version;
|
||||
this.SAMPLES = SAMPLES;
|
||||
this.components = { TabbedEditor };
|
||||
|
||||
this.state = {
|
||||
js: SAMPLES[0].code,
|
||||
@@ -270,97 +360,8 @@ class App extends owl.Component {
|
||||
saveAs(content, "app.zip");
|
||||
}
|
||||
}
|
||||
App.components = { TabbedEditor };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tabbed editor
|
||||
//------------------------------------------------------------------------------
|
||||
class TabbedEditor extends owl.Component {
|
||||
constructor(parent, props) {
|
||||
super(parent, props);
|
||||
this.state = {
|
||||
currentTab: props.js ? "js" : props.xml ? "xml" : "css"
|
||||
};
|
||||
this.setTab = owl.utils.debounce(this.setTab, 250, true);
|
||||
|
||||
this.sessions = {};
|
||||
this._setupSessions(props);
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.editor = this.editor || ace.edit(this.refs.editor);
|
||||
|
||||
this.editor.setValue(this.props[this.state.currentTab], -1);
|
||||
this.editor.setFontSize("12px");
|
||||
this.editor.setTheme("ace/theme/monokai");
|
||||
this.editor.setSession(this.sessions[this.state.currentTab]);
|
||||
const tabSize = this.state.currentTab === "xml" ? 2 : 4;
|
||||
this.editor.session.setOption("tabSize", tabSize);
|
||||
this.editor.on("blur", () => {
|
||||
const editorValue = this.editor.getValue();
|
||||
const propsValue = this.props[this.state.currentTab];
|
||||
if (editorValue !== propsValue) {
|
||||
this.trigger("updateCode", {
|
||||
type: this.state.currentTab,
|
||||
value: editorValue
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
willUpdateProps(nextProps) {
|
||||
this._setupSessions(nextProps);
|
||||
}
|
||||
|
||||
patched() {
|
||||
const session = this.sessions[this.state.currentTab];
|
||||
let content = this.props[this.state.currentTab];
|
||||
if (content === false) {
|
||||
const tab = this.props.js ? "js" : this.props.xml ? "xml" : "css";
|
||||
content = this.props[tab];
|
||||
this.state.currentTab = tab;
|
||||
}
|
||||
session.setValue(content, -1);
|
||||
this.editor.setSession(session);
|
||||
this.editor.resize();
|
||||
}
|
||||
|
||||
setTab(tab) {
|
||||
if (this.state.currentTab !== tab) {
|
||||
this.state.currentTab = tab;
|
||||
const session = this.sessions[this.state.currentTab];
|
||||
session.doc.setValue(this.props[tab], -1);
|
||||
this.editor.setSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
onMouseDown(ev) {
|
||||
if (ev.target.tagName === "DIV") {
|
||||
let y = ev.clientY;
|
||||
const resizer = ev => {
|
||||
const delta = ev.clientY - y;
|
||||
y = ev.clientY;
|
||||
this.trigger("updatePanelHeight", { delta });
|
||||
};
|
||||
document.body.addEventListener("mousemove", resizer);
|
||||
document.body.addEventListener("mouseup", () => {
|
||||
document.body.removeEventListener("mousemove", resizer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_setupSessions(props) {
|
||||
for (let tab of ["js", "xml", "css"]) {
|
||||
if (props[tab] && !this.sessions[tab]) {
|
||||
this.sessions[tab] = new ace.EditSession(props[tab], MODES[tab]);
|
||||
this.sessions[tab].setOption("useWorker", false);
|
||||
const tabSize = tab === "xml" ? 2 : 4;
|
||||
this.sessions[tab].setOption("tabSize", tabSize);
|
||||
this.sessions[tab].setUndoManager(new ace.UndoManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Application initialization
|
||||
|
||||
+28
-29
@@ -10,7 +10,7 @@ class Greeter extends owl.Component {
|
||||
|
||||
// Main root component
|
||||
class App extends owl.Component {
|
||||
components = { Greeter };
|
||||
static components = { Greeter };
|
||||
state = { name: 'World'};
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class Counter extends owl.Component {
|
||||
|
||||
class App extends owl.Component {
|
||||
state = { flag: false, componentFlag: false, numbers: [] };
|
||||
components = { Counter };
|
||||
static components = { Counter };
|
||||
|
||||
toggle(key) {
|
||||
this.state[key] = !this.state[key];
|
||||
@@ -214,7 +214,7 @@ class DemoComponent extends owl.Component {
|
||||
}
|
||||
|
||||
class App extends owl.Component {
|
||||
components = { DemoComponent };
|
||||
static components = { DemoComponent };
|
||||
state = { n: 0, flag: true };
|
||||
|
||||
increment() {
|
||||
@@ -388,7 +388,7 @@ class TodoItem extends owl.Component {
|
||||
// TodoApp
|
||||
//------------------------------------------------------------------------------
|
||||
class TodoApp extends owl.store.ConnectedComponent {
|
||||
components = { TodoItem };
|
||||
static components = { TodoItem };
|
||||
state = { filter: "all" };
|
||||
|
||||
static mapStoreToProps(state) {
|
||||
@@ -896,25 +896,24 @@ const RESPONSIVE = `// In this example, we show how we can modify keys in the gl
|
||||
//------------------------------------------------------------------------------
|
||||
class Navbar extends owl.Component {}
|
||||
|
||||
class ControlPanel extends owl.Component {
|
||||
components = { MobileSearchView };
|
||||
}
|
||||
class MobileSearchView extends owl.Component {}
|
||||
|
||||
class FormView extends owl.Component {
|
||||
components = { AdvancedComponent };
|
||||
class ControlPanel extends owl.Component {
|
||||
static components = { MobileSearchView };
|
||||
}
|
||||
|
||||
class AdvancedComponent extends owl.Component {}
|
||||
|
||||
class FormView extends owl.Component {
|
||||
static components = { AdvancedComponent };
|
||||
}
|
||||
|
||||
class Chatter extends owl.Component {
|
||||
messages = Array.from(Array(100).keys());
|
||||
}
|
||||
|
||||
class MobileSearchView extends owl.Component {}
|
||||
|
||||
|
||||
class App extends owl.Component {
|
||||
components = { Navbar, ControlPanel, FormView, Chatter };
|
||||
static components = { Navbar, ControlPanel, FormView, Chatter };
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1072,7 +1071,7 @@ class Counter extends owl.Component {
|
||||
|
||||
// Main root component
|
||||
class App extends owl.Component {
|
||||
components = {Card, Counter};
|
||||
static components = {Card, Counter};
|
||||
state = {a: 1, b: 3};
|
||||
|
||||
inc(key, delta) {
|
||||
@@ -1170,8 +1169,18 @@ const ASYNC_COMPONENTS = `// This example will not work if your browser does not
|
||||
// because of the slow component. We use the 't-asyncroot' directive for this
|
||||
// purpose. Try removing it to see the difference.
|
||||
|
||||
class SlowComponent extends owl.Component {
|
||||
willUpdateProps() {
|
||||
// simulate a component that needs to perform async stuff (e.g. an RPC)
|
||||
// with the updated props before re-rendering itself
|
||||
return new Promise(resolve => setTimeout(resolve, 1500));
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationList extends owl.Component {}
|
||||
|
||||
class App extends owl.Component {
|
||||
components = {SlowComponent, NotificationList};
|
||||
static components = {SlowComponent, NotificationList};
|
||||
state = { value: 0, notifs: [] };
|
||||
|
||||
increment() {
|
||||
@@ -1185,16 +1194,6 @@ class App extends owl.Component {
|
||||
}
|
||||
}
|
||||
|
||||
class SlowComponent extends owl.Component {
|
||||
willUpdateProps() {
|
||||
// simulate a component that needs to perform async stuff (e.g. an RPC)
|
||||
// with the updated props before re-rendering itself
|
||||
return new Promise(resolve => setTimeout(resolve, 1500));
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationList extends owl.Component {}
|
||||
|
||||
const qweb = new owl.QWeb(TEMPLATES);
|
||||
const app = new App({ qweb });
|
||||
app.mount(document.body);
|
||||
@@ -1368,7 +1367,7 @@ class Window extends owl.Component {
|
||||
}
|
||||
|
||||
class WindowManager extends owl.Component {
|
||||
components = { Window };
|
||||
static components = { Window };
|
||||
windows = [];
|
||||
nextId = 1;
|
||||
currentZindex = 1;
|
||||
@@ -1384,12 +1383,12 @@ class WindowManager extends owl.Component {
|
||||
left: 0,
|
||||
zindex: this.currentZindex++
|
||||
});
|
||||
this.components[id] = info.component;
|
||||
this.constructor.components[id] = info.component;
|
||||
this.render();
|
||||
}
|
||||
closeWindow(ev) {
|
||||
const id = ev.detail.id;
|
||||
delete this.components[id];
|
||||
delete this.constructor.components[id];
|
||||
const index = this.windows.findIndex(w => w.id === id);
|
||||
this.windows.splice(index, 1);
|
||||
this.render();
|
||||
@@ -1409,7 +1408,7 @@ class WindowManager extends owl.Component {
|
||||
}
|
||||
|
||||
class App extends owl.Component {
|
||||
components = { WindowManager };
|
||||
static components = { WindowManager };
|
||||
|
||||
addWindow(name) {
|
||||
this.refs.wm.addWindow(name);
|
||||
|
||||
Reference in New Issue
Block a user