mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2d86dceb4 | |||
| 401b2a5b48 | |||
| 52f027fe46 |
@@ -110,8 +110,8 @@ npm install @odoo/owl
|
|||||||
|
|
||||||
If you want to use a simple `<script>` tag, the last release can be downloaded here:
|
If you want to use a simple `<script>` tag, the last release can be downloaded here:
|
||||||
|
|
||||||
- [owl-1.0.3.js](https://github.com/odoo/owl/releases/download/v1.0.3/owl.js)
|
- [owl-1.0.0-beta5.js](https://github.com/odoo/owl/releases/download/v1.0.0-beta5/owl.js)
|
||||||
- [owl-1.0.3.min.js](https://github.com/odoo/owl/releases/download/v1.0.3/owl.min.js)
|
- [owl-1.0.0-beta5.min.js](https://github.com/odoo/owl/releases/download/v1.0.0-beta5/owl.min.js)
|
||||||
|
|
||||||
Some npm scripts are available:
|
Some npm scripts are available:
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ to be called in the constructor.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`style`** (string, optional): it should be the return value of the [`css` tag](tags.md#css-tag),
|
- **`style`** (string, optional): it should be the return value of the [`css tag](tags.md#css-tag),
|
||||||
which is used to inject stylesheet whenever the component is visible on the
|
which is used to inject stylesheet whenever the component is visible on the
|
||||||
screen.
|
screen.
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ likely via a change in its state/props or environment).
|
|||||||
|
|
||||||
This method is not called on the initial render. It is useful to interact
|
This method is not called on the initial render. It is useful to interact
|
||||||
with the DOM (for example, through an external library) whenever the
|
with the DOM (for example, through an external library) whenever the
|
||||||
component was patched. Note that this hook will not be called if the component is
|
component was patched. Note that this hook will not be called if the compoent is
|
||||||
not in the DOM.
|
not in the DOM.
|
||||||
|
|
||||||
Updating the component state in this hook is possible, but not encouraged.
|
Updating the component state in this hook is possible, but not encouraged.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ a rendering that is no longer relevant, restart it, reuse it in some cases.
|
|||||||
But even though using concurrency is quite simple (and is the default behaviour),
|
But even though using concurrency is quite simple (and is the default behaviour),
|
||||||
asynchrony is difficult, because it introduces an additional dimension that
|
asynchrony is difficult, because it introduces an additional dimension that
|
||||||
vastly increase the complexity of an application. This section will explain
|
vastly increase the complexity of an application. This section will explain
|
||||||
how Owl manages this complexity, how concurrent rendering works in a general way.
|
how Owl manages this complexity, how concuurent rendering works in a general way.
|
||||||
|
|
||||||
## Rendering Components
|
## Rendering Components
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ Here is what Owl will do:
|
|||||||
1. hook `willUpdateProps` is called on `D` (async)
|
1. hook `willUpdateProps` is called on `D` (async)
|
||||||
2. template `D` is rerendered
|
2. template `D` is rerendered
|
||||||
- component `F` is created:
|
- component `F` is created:
|
||||||
1. hook `willStart` is called on `F` (async)
|
1. hook `willStart` is called on `E` (async)
|
||||||
2. template `F` is rendered
|
2. template `F` is rendered
|
||||||
|
|
||||||
3. `willPatch` hooks are called recursively on components `C`, `D` (not on `F`,
|
3. `willPatch` hooks are called recursively on components `C`, `D` (not on `F`,
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ all templates.
|
|||||||
Whenever a root component `App` is mounted, Owl will setup a valid environment by
|
Whenever a root component `App` is mounted, Owl will setup a valid environment by
|
||||||
following the next steps:
|
following the next steps:
|
||||||
|
|
||||||
- take the `env` object defined on `App.env` (if no `env` was explicitly setup,
|
- take the `env` object defined on `App.env` (if no `env` was explicitely setup,
|
||||||
this will return the empty `env` object defined on `Component`)
|
this will be return the empty `env` object defined on `Component`)
|
||||||
- if `env.qweb` is not set, then Owl will create a `QWeb` instance.
|
- if `env.qweb` is not set, then Owl will create a `QWeb` instance.
|
||||||
|
|
||||||
The correct way to customize an environment is to simply set it up on the root
|
The correct way to customize an environment is to simply set it up on the root
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
- [`useContext`](#usecontext)
|
- [`useContext`](#usecontext)
|
||||||
- [`useRef`](#useref)
|
- [`useRef`](#useref)
|
||||||
- [`useSubEnv`](#usesubenv)
|
- [`useSubEnv`](#usesubenv)
|
||||||
- [`useExternalListener`](#useexternallistener)
|
|
||||||
- [`useStore`](#usestore)
|
- [`useStore`](#usestore)
|
||||||
- [`useDispatch`](#usedispatch)
|
- [`useDispatch`](#usedispatch)
|
||||||
- [`useGetters`](#usegetters)
|
- [`useGetters`](#usegetters)
|
||||||
@@ -355,17 +354,6 @@ will be added to the parent environment. Note that it will extend, not replace
|
|||||||
the parent environment. And of course, the parent environment will not be
|
the parent environment. And of course, the parent environment will not be
|
||||||
affected.
|
affected.
|
||||||
|
|
||||||
### `useExternalListener`
|
|
||||||
|
|
||||||
The `useExternalListener` hook helps solve a very common problem: adding and removing
|
|
||||||
a listener on some target whenever a component is mounted/unmounted. For example,
|
|
||||||
a dropdown menu (or its parent) may need to listen to a `click` event on `window`
|
|
||||||
to be closed:
|
|
||||||
|
|
||||||
```js
|
|
||||||
useExternalListener(window, "click", this.closeMenu);
|
|
||||||
```
|
|
||||||
|
|
||||||
### `useStore`
|
### `useStore`
|
||||||
|
|
||||||
The `useStore` hook is the entry point for a component to connect to the store.
|
The `useStore` hook is the entry point for a component to connect to the store.
|
||||||
|
|||||||
@@ -101,52 +101,6 @@ will be formatted as:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This extension brings another useful feature: the `&` selector which refers to
|
|
||||||
the parent selector. For example, we want our component to be red when hovered.
|
|
||||||
We would like to write something like:
|
|
||||||
|
|
||||||
```scss
|
|
||||||
.my-component {
|
|
||||||
display: block;
|
|
||||||
:hover {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
but it will be formatted as:
|
|
||||||
|
|
||||||
```css
|
|
||||||
.my-component {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.my-component :hover {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `&` selector can be used to solve this problem:
|
|
||||||
|
|
||||||
```scss
|
|
||||||
.my-component {
|
|
||||||
display: block;
|
|
||||||
&:hover {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
will be formatted as:
|
|
||||||
|
|
||||||
```css
|
|
||||||
.my-component {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.my-component:hover {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, there is no additional processing done by the `css` tag. However, since it
|
Now, there is no additional processing done by the `css` tag. However, since it
|
||||||
is done in javascript at runtime, we actually have more power. For example:
|
is done in javascript at runtime, we actually have more power. For example:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ logging useful information is extremely valuable. There is a [javascript file](.
|
|||||||
Once it is executed, it will log a lot of information on each component main hooks. The following code is a minified version to make it easier to copy/paste:
|
Once it is executed, it will log a lot of information on each component main hooks. The following code is a minified version to make it easier to copy/paste:
|
||||||
|
|
||||||
```
|
```
|
||||||
function debugOwl(t,e){let n,o="[OWL_DEBUG]";function r(t){let e;try{e=JSON.stringify(t||{})}catch(t){e="<JSON error>"}return e.length>200&&(e=e.slice(0,200)+"..."),e}if(Object.defineProperty(t.Component,"current",{get:()=>n,set(s){n=s;const i=s.constructor.name;if(e.componentBlackList&&e.componentBlackList.test(i))return;if(e.componentWhiteList&&!e.componentWhiteList.test(i))return;let l;Object.defineProperty(n,"__owl__",{get:()=>l,set(n){!function(n,s,i){let l=`${s}<id=${i}>`,c=t=>console.log(`${o} ${l} ${t}`),u=t=>(!e.methodBlackList||!e.methodBlackList.includes(t))&&!(e.methodWhiteList&&!e.methodWhiteList.includes(t));u("constructor")&&c(`constructor, props=${r(n.props)}`);u("willStart")&&t.hooks.onWillStart(()=>{c("willStart")});u("mounted")&&t.hooks.onMounted(()=>{c("mounted")});u("willUpdateProps")&&t.hooks.onWillUpdateProps(t=>{c(`willUpdateProps, nextprops=${r(t)}`)});u("willPatch")&&t.hooks.onWillPatch(()=>{c("willPatch")});u("patched")&&t.hooks.onPatched(()=>{c("patched")});u("willUnmount")&&t.hooks.onWillUnmount(()=>{c("willUnmount")});const d=n.__render.bind(n);n.__render=function(...t){c("rendering template"),d(...t)};const h=n.render.bind(n);n.render=function(...t){const e=n.__owl__;let o="render";return e.isMounted||e.currentFiber||(o+=" (warning: component is not mounted, this render has no effect)"),c(o),h(...t)};const p=n.mount.bind(n);n.mount=function(...t){return c("mount"),p(...t)}}(s,i,(l=n).id)}})}}),e.logScheduler){let e=t.Component.scheduler.start,n=t.Component.scheduler.stop;t.Component.scheduler.start=function(){this.isRunning||console.log(`${o} scheduler: start running tasks queue`),e.call(this)},t.Component.scheduler.stop=function(){this.isRunning&&console.log(`${o} scheduler: stop running tasks queue`),n.call(this)}}if(e.logStore){let e=t.Store.prototype.dispatch;t.Store.prototype.dispatch=function(t,...n){return console.log(`${o} store: action '${t}' dispatched. Payload: '${r(n)}'`),e.call(this,t,...n)}}}
|
function debugOwl(t,n){let e,o="[OWL_DEBUG]";function s(t){let n=JSON.stringify(t||{});return n.length>200&&(n=n.slice(0,200)+"..."),n}if(Object.defineProperty(t.Component,"current",{get:()=>e,set(i){e=i;const r=i.constructor.name;if(n.componentBlackList&&n.componentBlackList.test(r))return;if(n.componentWhiteList&&!n.componentWhiteList.test(r))return;let l;Object.defineProperty(e,"__owl__",{get:()=>l,set(e){!function(e,i,r){let l=`${i}<id=${r}>`,c=t=>console.log(`${o} ${l} ${t}`),u=t=>(!n.methodBlackList||!n.methodBlackList.includes(t))&&!(n.methodWhiteList&&!n.methodWhiteList.includes(t));u("constructor")&&c(`constructor, props=${s(e.props)}`);u("willStart")&&t.hooks.onWillStart(()=>{c("willStart")});u("mounted")&&t.hooks.onMounted(()=>{c("mounted")});u("willUpdateProps")&&t.hooks.onWillUpdateProps(t=>{c(`willUpdateProps, nextprops=${s(t)}`)});u("willPatch")&&t.hooks.onWillPatch(()=>{c("willPatch")});u("patched")&&t.hooks.onPatched(()=>{c("patched")});u("willUnmount")&&t.hooks.onWillUnmount(()=>{c("willUnmount")});const d=e.__render.bind(e);e.__render=function(...t){c("rendering template"),d(...t)};const h=e.render.bind(e);e.render=function(...t){const n=e.__owl__;let o="render";return n.isMounted||n.currentFiber||(o+=" (warning: component is not mounted, this render has no effect)"),c(o),h(...t)};const p=e.mount.bind(e);e.mount=function(...t){return c("mount"),p(...t)}}(i,r,(l=e).id)}})}}),n.logScheduler){let n=t.Component.scheduler.start,e=t.Component.scheduler.stop;t.Component.scheduler.start=function(){this.isRunning||console.log(`${o} scheduler: start running tasks queue`),n.call(this)},t.Component.scheduler.stop=function(){this.isRunning&&console.log(`${o} scheduler: stop running tasks queue`),e.call(this)}}if(n.logStore){let n=t.Store.prototype.dispatch;t.Store.prototype.dispatch=function(t,...e){return console.log(`${o} store: action '${t}' dispatched. Payload: '${s(e)}'`),n.call(this,t,...e)}}}
|
||||||
debugOwl(owl, {
|
debugOwl(owl, {
|
||||||
// componentBlackList: /App/, // regexp
|
// componentBlackList: /App/, // regexp
|
||||||
// componentWhiteList: /SomeComponent/, // regexp
|
// componentWhiteList: /SomeComponent/, // regexp
|
||||||
|
|||||||
+6
-6
@@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "1.0.3",
|
"version": "1.0.0-beta5",
|
||||||
"description": "Odoo Web Library (OWL)",
|
"description": "Odoo Web Library (OWL)",
|
||||||
"main": "dist/owl.js",
|
"main": "dist/owl/index.js",
|
||||||
"types": "dist/types/index.d.ts",
|
"types": "dist/owl/index.d.ts",
|
||||||
"files": ["dist/types/", "dist/owl.js"],
|
"prepublish": "npm run build",
|
||||||
|
"files": ["dist/owl/"],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.15.3"
|
"node": ">=10.15.3"
|
||||||
},
|
},
|
||||||
@@ -20,8 +21,7 @@
|
|||||||
"tools": "npm run build && npm run tools:serve",
|
"tools": "npm run build && npm run tools:serve",
|
||||||
"pretools:watch": "npm run build",
|
"pretools:watch": "npm run build",
|
||||||
"tools:watch": "npm-run-all --parallel tools:serve \"build:* -- --watch\"",
|
"tools:watch": "npm-run-all --parallel tools:serve \"build:* -- --watch\"",
|
||||||
"prettier": "prettier {src/*.ts,src/**/*.ts,tests/*.ts,tests/**/*.ts,doc/*.md,doc/**/*.md} --write",
|
"prettier": "prettier {src/*.ts,src/**/*.ts,tests/*.ts,tests/**/*.ts,doc/*.md,doc/**/*.md} --write"
|
||||||
"publish": "npm run buildcommonjs && npm publish"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
# 🦉 OWL Roadmap 🦉
|
# 🦉 OWL Roadmap 🦉
|
||||||
|
|
||||||
- Current version: 1.0.3
|
- Current version: 1.0.0-beta5
|
||||||
- Status: stable
|
- Status: mostly stable
|
||||||
|
|
||||||
This roadmap is only an attempt at predicting Owl's future. Everything may
|
This roadmap is only an attempt at predicting Owl's future. Everything may
|
||||||
change!
|
change!
|
||||||
|
|||||||
@@ -15,16 +15,13 @@ export function processSheet(str: string): string {
|
|||||||
function generateSelector(stackIndex: number, parentSelector?: string) {
|
function generateSelector(stackIndex: number, parentSelector?: string) {
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
for (const selector of selectorStack[stackIndex]) {
|
for (const selector of selectorStack[stackIndex]) {
|
||||||
let part = (parentSelector && parentSelector + " " + selector) || selector;
|
let part = parentSelector && parentSelector + ' ' + selector || selector;
|
||||||
if (part.includes("&")) {
|
|
||||||
part = selector.replace(/&/g, parentSelector || "");
|
|
||||||
}
|
|
||||||
if (stackIndex < selectorStack.length - 1) {
|
if (stackIndex < selectorStack.length - 1) {
|
||||||
part = generateSelector(stackIndex + 1, part);
|
part = generateSelector(stackIndex + 1, part);
|
||||||
}
|
}
|
||||||
parts.push(part);
|
parts.push(part);
|
||||||
}
|
}
|
||||||
return parts.join(", ");
|
return parts.join(', ');
|
||||||
}
|
}
|
||||||
function generateRules() {
|
function generateRules() {
|
||||||
if (rules.length) {
|
if (rules.length) {
|
||||||
|
|||||||
@@ -131,27 +131,3 @@ export function useSubEnv(nextEnv) {
|
|||||||
const component = Component.current!;
|
const component = Component.current!;
|
||||||
component.env = Object.assign(Object.create(component.env), nextEnv);
|
component.env = Object.assign(Object.create(component.env), nextEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// useExternalListener
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When a component needs to listen to DOM Events on element(s) that are not
|
|
||||||
* part of his hierarchy, we can use the `useExternalListener` hook.
|
|
||||||
* It will correctly add and remove the event listener, whenever the
|
|
||||||
* component is mounted and unmounted.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* a menu needs to listen to the click on window to be closed automatically
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* in the constructor of the OWL component that needs to be notified,
|
|
||||||
* `useExternalListener(window, 'click', this._doSomething);`
|
|
||||||
* */
|
|
||||||
export function useExternalListener(target: HTMLElement, eventName: string, handler, eventParams?) {
|
|
||||||
const boundHandler = handler.bind(Component.current);
|
|
||||||
|
|
||||||
onMounted(() => target.addEventListener(eventName, boundHandler, eventParams));
|
|
||||||
onWillUnmount(() => target.removeEventListener(eventName, boundHandler, eventParams));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -128,12 +128,7 @@ QWeb.addDirective({
|
|||||||
qwebvar.expr = `scope.${variable}`;
|
qwebvar.expr = `scope.${variable}`;
|
||||||
if (value) {
|
if (value) {
|
||||||
const formattedValue = ctx.formatExpression(value);
|
const formattedValue = ctx.formatExpression(value);
|
||||||
let scopeExpr = `scope`;
|
ctx.addLine(`${qwebvar.expr} = ${formattedValue};`);
|
||||||
if (ctx.protectedScopeNumber) {
|
|
||||||
ctx.rootContext.shouldDefineUtils = true;
|
|
||||||
scopeExpr = `utils.getScope(scope, '${variable}')`;
|
|
||||||
}
|
|
||||||
ctx.addLine(`${scopeExpr}.${variable} = ${formattedValue};`);
|
|
||||||
qwebvar.value = formattedValue;
|
qwebvar.value = formattedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,9 +265,9 @@ QWeb.addDirective({
|
|||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
const callingScope = hasBody ? "scope" : "Object.assign(Object.create(context), scope)";
|
const callingScope = hasBody ? "scope" : "Object.assign(Object.create(context), scope)";
|
||||||
const parentComponent = `utils.getComponent(context)`;
|
const parentComponent = `utils.getComponent(context)`;
|
||||||
const key = ctx.generateTemplateKey();
|
const keyCode = ctx.loopNumber || ctx.hasKey0 ? `, key: ${ctx.generateTemplateKey()}` : "";
|
||||||
const parentNode = ctx.parentNode ? `c${ctx.parentNode}` : "result";
|
const parentNode = ctx.parentNode ? `c${ctx.parentNode}` : "result";
|
||||||
const extra = `Object.assign({}, extra, {parentNode: ${parentNode}, parent: ${parentComponent}, key: ${key}})`;
|
const extra = `Object.assign({}, extra, {parentNode: ${parentNode}, parent: ${parentComponent}${keyCode}})`;
|
||||||
if (ctx.parentNode) {
|
if (ctx.parentNode) {
|
||||||
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
|
ctx.addLine(`this.subTemplates['${subTemplate}'].call(this, ${callingScope}, ${extra});`);
|
||||||
} else {
|
} else {
|
||||||
@@ -318,7 +313,7 @@ QWeb.addDirective({
|
|||||||
ctx.addLine(`_${valuesID} = Object.values(_${arrayID});`);
|
ctx.addLine(`_${valuesID} = Object.values(_${arrayID});`);
|
||||||
ctx.closeIf();
|
ctx.closeIf();
|
||||||
ctx.addLine(`let _length${keysID} = _${keysID}.length;`);
|
ctx.addLine(`let _length${keysID} = _${keysID}.length;`);
|
||||||
let varsID = ctx.startProtectScope(true);
|
let varsID = ctx.startProtectScope();
|
||||||
const loopVar = `i${ctx.loopNumber}`;
|
const loopVar = `i${ctx.loopNumber}`;
|
||||||
ctx.addLine(`for (let ${loopVar} = 0; ${loopVar} < _length${keysID}; ${loopVar}++) {`);
|
ctx.addLine(`for (let ${loopVar} = 0; ${loopVar} < _length${keysID}; ${loopVar}++) {`);
|
||||||
ctx.indent();
|
ctx.indent();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { compileExpr, compileExprToArray, QWebVar } from "./expression_parser";
|
import { compileExpr, QWebVar } from "./expression_parser";
|
||||||
|
|
||||||
export const INTERP_REGEXP = /\{\{.*?\}\}/g;
|
export const INTERP_REGEXP = /\{\{.*?\}\}/g;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -17,7 +17,6 @@ export class CompilationContext {
|
|||||||
rootContext: CompilationContext;
|
rootContext: CompilationContext;
|
||||||
shouldDefineParent: boolean = false;
|
shouldDefineParent: boolean = false;
|
||||||
shouldDefineScope: boolean = false;
|
shouldDefineScope: boolean = false;
|
||||||
protectedScopeNumber: number = 0;
|
|
||||||
shouldDefineQWeb: boolean = false;
|
shouldDefineQWeb: boolean = false;
|
||||||
shouldDefineUtils: boolean = false;
|
shouldDefineUtils: boolean = false;
|
||||||
shouldDefineRefs: boolean = false;
|
shouldDefineRefs: boolean = false;
|
||||||
@@ -156,24 +155,6 @@ export class CompilationContext {
|
|||||||
this.rootContext.shouldDefineScope = true;
|
this.rootContext.shouldDefineScope = true;
|
||||||
return compileExpr(expr, this.variables);
|
return compileExpr(expr, this.variables);
|
||||||
}
|
}
|
||||||
captureExpression(expr: string): string {
|
|
||||||
this.rootContext.shouldDefineScope = true;
|
|
||||||
const argId = this.generateID();
|
|
||||||
const tokens = compileExprToArray(expr, this.variables);
|
|
||||||
const done = new Set();
|
|
||||||
return tokens
|
|
||||||
.map(tok => {
|
|
||||||
if (tok.varName) {
|
|
||||||
if (!done.has(tok.varName)) {
|
|
||||||
done.add(tok.varName);
|
|
||||||
this.addLine(`const ${tok.varName}_${argId} = ${tok.value};`);
|
|
||||||
}
|
|
||||||
tok.value = `${tok.varName}_${argId}`;
|
|
||||||
}
|
|
||||||
return tok.value;
|
|
||||||
})
|
|
||||||
.join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform string interpolation on the given string. Note that if the whole
|
* Perform string interpolation on the given string. Note that if the whole
|
||||||
@@ -192,19 +173,18 @@ export class CompilationContext {
|
|||||||
let r = s.replace(/\{\{.*?\}\}/g, s => "${" + this.formatExpression(s.slice(2, -2)) + "}");
|
let r = s.replace(/\{\{.*?\}\}/g, s => "${" + this.formatExpression(s.slice(2, -2)) + "}");
|
||||||
return "`" + r + "`";
|
return "`" + r + "`";
|
||||||
}
|
}
|
||||||
startProtectScope(codeBlock?: boolean): number {
|
startProtectScope(): number {
|
||||||
const protectID = this.generateID();
|
const protectID = this.generateID();
|
||||||
this.rootContext.protectedScopeNumber++;
|
|
||||||
this.rootContext.shouldDefineScope = true;
|
this.rootContext.shouldDefineScope = true;
|
||||||
const scopeExpr = codeBlock
|
|
||||||
? `Object.create(scope);`
|
|
||||||
: `Object.assign(Object.create(context), scope);`;
|
|
||||||
this.addLine(`let _origScope${protectID} = scope;`);
|
this.addLine(`let _origScope${protectID} = scope;`);
|
||||||
this.addLine(`scope = ${scopeExpr}`);
|
this.addLine(`let _origScope${protectID} = scope;`);
|
||||||
|
// dict of origscopes
|
||||||
|
// export protectID in compiled string form
|
||||||
|
// fetch in subsequent code the relevant scope
|
||||||
|
this.addLine(`scope = Object.assign(Object.create(context), scope);`);
|
||||||
return protectID;
|
return protectID;
|
||||||
}
|
}
|
||||||
stopProtectScope(protectID: number) {
|
stopProtectScope(protectID: number) {
|
||||||
this.rootContext.protectedScopeNumber--;
|
|
||||||
this.addLine(`scope = _origScope${protectID};`);
|
this.addLine(`scope = _origScope${protectID};`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ interface Token {
|
|||||||
value: string;
|
value: string;
|
||||||
originalValue?: string;
|
originalValue?: string;
|
||||||
size?: number;
|
size?: number;
|
||||||
varName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const STATIC_TOKEN_MAP: { [key: string]: TKind } = {
|
const STATIC_TOKEN_MAP: { [key: string]: TKind } = {
|
||||||
@@ -82,7 +81,7 @@ const STATIC_TOKEN_MAP: { [key: string]: TKind } = {
|
|||||||
|
|
||||||
// note that the space after typeof is relevant. It makes sure that the formatted
|
// note that the space after typeof is relevant. It makes sure that the formatted
|
||||||
// expression has a space after typeof
|
// expression has a space after typeof
|
||||||
const OPERATORS = "...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ".split(",");
|
const OPERATORS = "...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;".split(",");
|
||||||
|
|
||||||
type Tokenizer = (expr: string) => Token | false;
|
type Tokenizer = (expr: string) => Token | false;
|
||||||
|
|
||||||
@@ -235,7 +234,7 @@ export function tokenize(expr: string): Token[] {
|
|||||||
* the arrow operator, then we add the current (or some previous tokens) token to
|
* the arrow operator, then we add the current (or some previous tokens) token to
|
||||||
* the list of variables so it does not get replaced by a lookup in the context
|
* the list of variables so it does not get replaced by a lookup in the context
|
||||||
*/
|
*/
|
||||||
export function compileExprToArray(expr: string, scope: { [key: string]: QWebVar }): Token[] {
|
export function compileExpr(expr: string, scope: { [key: string]: QWebVar }): string {
|
||||||
scope = Object.create(scope);
|
scope = Object.create(scope);
|
||||||
const tokens = tokenize(expr);
|
const tokens = tokenize(expr);
|
||||||
for (let i = 0; i < tokens.length; i++) {
|
for (let i = 0; i < tokens.length; i++) {
|
||||||
@@ -270,7 +269,6 @@ export function compileExprToArray(expr: string, scope: { [key: string]: QWebVar
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isVar) {
|
if (isVar) {
|
||||||
token.varName = token.value;
|
|
||||||
if (token.value in scope && "id" in scope[token.value]) {
|
if (token.value in scope && "id" in scope[token.value]) {
|
||||||
token.value = scope[token.value].expr!;
|
token.value = scope[token.value].expr!;
|
||||||
} else {
|
} else {
|
||||||
@@ -279,11 +277,5 @@ export function compileExprToArray(expr: string, scope: { [key: string]: QWebVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tokens;
|
return tokens.map(t => t.value).join("");
|
||||||
}
|
|
||||||
|
|
||||||
export function compileExpr(expr: string, scope: { [key: string]: QWebVar }): string {
|
|
||||||
return compileExprToArray(expr, scope)
|
|
||||||
.map(t => t.value)
|
|
||||||
.join("");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function makeHandlerCode(
|
|||||||
ctx.rootContext.shouldDefineUtils = true;
|
ctx.rootContext.shouldDefineUtils = true;
|
||||||
const comp = `utils.getComponent(context)`;
|
const comp = `utils.getComponent(context)`;
|
||||||
if (args) {
|
if (args) {
|
||||||
const argId = ctx.generateID();
|
let argId = ctx.generateID();
|
||||||
ctx.addLine(`let args${argId} = [${ctx.formatExpression(args)}];`);
|
ctx.addLine(`let args${argId} = [${ctx.formatExpression(args)}];`);
|
||||||
code = `${comp}['${name}'](...args${argId}, e);`;
|
code = `${comp}['${name}'](...args${argId}, e);`;
|
||||||
putInCache = false;
|
putInCache = false;
|
||||||
@@ -67,9 +67,8 @@ export function makeHandlerCode(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we get here, then it is an expression
|
// if we get here, then it is an expression
|
||||||
// we need to capture every variable in it
|
|
||||||
putInCache = false;
|
putInCache = false;
|
||||||
code = ctx.captureExpression(value);
|
code = ctx.formatExpression(value);
|
||||||
}
|
}
|
||||||
const modCode = mods.map(mod => modcodes[mod]).join("");
|
const modCode = mods.map(mod => modcodes[mod]).join("");
|
||||||
let handler = `function (e) {if (!context.__owl__.isMounted){return}${modCode}${code}}`;
|
let handler = `function (e) {if (!context.__owl__.isMounted){return}${modCode}${code}}`;
|
||||||
|
|||||||
+2
-16
@@ -86,10 +86,6 @@ interface Utils {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isComponent(obj) {
|
|
||||||
return obj && obj.hasOwnProperty("__owl__");
|
|
||||||
}
|
|
||||||
|
|
||||||
const UTILS: Utils = {
|
const UTILS: Utils = {
|
||||||
zero: Symbol("zero"),
|
zero: Symbol("zero"),
|
||||||
toObj(expr) {
|
toObj(expr) {
|
||||||
@@ -126,21 +122,10 @@ const UTILS: Utils = {
|
|||||||
.join("");
|
.join("");
|
||||||
},
|
},
|
||||||
getComponent(obj) {
|
getComponent(obj) {
|
||||||
while (obj && !isComponent(obj)) {
|
while (obj && !obj.hasOwnProperty("__owl__")) {
|
||||||
obj = obj.__proto__;
|
obj = obj.__proto__;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
},
|
|
||||||
getScope(obj, property: string) {
|
|
||||||
const obj0 = obj;
|
|
||||||
while (obj && !obj.hasOwnProperty(property)) {
|
|
||||||
const newObj = obj.__proto__;
|
|
||||||
if (!newObj || isComponent(newObj)) {
|
|
||||||
return obj0;
|
|
||||||
}
|
|
||||||
obj = newObj;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -298,6 +283,7 @@ export class QWeb extends EventBus {
|
|||||||
fn: function(this: QWeb, context, extra) {
|
fn: function(this: QWeb, context, extra) {
|
||||||
const compiledFunction = this._compile(name, elem);
|
const compiledFunction = this._compile(name, elem);
|
||||||
template.fn = compiledFunction;
|
template.fn = compiledFunction;
|
||||||
|
console.warn('CompiledFn', compiledFunction.toString());
|
||||||
return compiledFunction.call(this, context, extra);
|
return compiledFunction.call(this, context, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.section_first = i1 === 0
|
scope.section_first = i1 === 0
|
||||||
scope.section_last = i1 === _length3 - 1
|
scope.section_last = i1 === _length3 - 1
|
||||||
@@ -75,7 +75,7 @@ exports[`basic widget properties reconciliation alg works for t-foreach in t-for
|
|||||||
}
|
}
|
||||||
let _length7 = _7.length;
|
let _length7 = _7.length;
|
||||||
let _origScope9 = scope;
|
let _origScope9 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i2 = 0; i2 < _length7; i2++) {
|
for (let i2 = 0; i2 < _length7; i2++) {
|
||||||
scope.blip_first = i2 === 0
|
scope.blip_first = i2 === 0
|
||||||
scope.blip_last = i2 === _length7 - 1
|
scope.blip_last = i2 === _length7 - 1
|
||||||
@@ -432,7 +432,7 @@ exports[`composition sub components with some state rendered in a loop 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.number_first = i1 === 0
|
scope.number_first = i1 === 0
|
||||||
scope.number_last = i1 === _length3 - 1
|
scope.number_last = i1 === _length3 - 1
|
||||||
@@ -587,256 +587,6 @@ exports[`dynamic t-props basic use 1`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`other directives with t-component slot setted value (with t-set) not accessible with t-esc 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__2\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let QWeb = this.constructor;
|
|
||||||
let parent = context;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 'source';
|
|
||||||
let c2 = [], p2 = {key:2};
|
|
||||||
let vn2 = h('p', p2, c2);
|
|
||||||
c1.push(vn2);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c2.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
// Component 'ChildWidget'
|
|
||||||
let w3 = '__4__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__4__']] : false;
|
|
||||||
let props3 = {};
|
|
||||||
if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) {
|
|
||||||
w3.destroy();
|
|
||||||
w3 = false;
|
|
||||||
}
|
|
||||||
if (w3) {
|
|
||||||
w3.__updateProps(props3, extra.fiber, Object.assign(Object.create(context), scope));
|
|
||||||
let pvnode = w3.__owl__.pvnode;
|
|
||||||
c1.push(pvnode);
|
|
||||||
} else {
|
|
||||||
let componentKey3 = \`ChildWidget\`;
|
|
||||||
let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3]|| scope['ChildWidget'];
|
|
||||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
|
||||||
w3 = new W3(parent, props3);
|
|
||||||
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
|
||||||
w3.__owl__.slotId = 1;
|
|
||||||
let fiber = w3.__prepare(extra.fiber, Object.assign(Object.create(context), scope), () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; });
|
|
||||||
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
|
||||||
c1.push(pvnode);
|
|
||||||
w3.__owl__.pvnode = pvnode;
|
|
||||||
}
|
|
||||||
w3.__owl__.parentLastFiberId = extra.fiber.id;
|
|
||||||
let c5 = [], p5 = {key:5};
|
|
||||||
let vn5 = h('p', p5, c5);
|
|
||||||
c1.push(vn5);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c5.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-on expression captured in t-foreach 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 0;
|
|
||||||
let _2 = scope['arr'];
|
|
||||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
|
||||||
let _3 = _4 = _2;
|
|
||||||
if (!(_2 instanceof Array)) {
|
|
||||||
_3 = Object.keys(_2);
|
|
||||||
_4 = Object.values(_2);
|
|
||||||
}
|
|
||||||
let _length3 = _3.length;
|
|
||||||
let _origScope5 = scope;
|
|
||||||
scope = Object.create(scope);
|
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
|
||||||
scope.val_first = i1 === 0
|
|
||||||
scope.val_last = i1 === _length3 - 1
|
|
||||||
scope.val_index = i1
|
|
||||||
scope.val = _3[i1]
|
|
||||||
scope.val_value = _4[i1]
|
|
||||||
let key1 = scope['val'];
|
|
||||||
let c6 = [], p6 = {key:\`\${key1}_6\`};
|
|
||||||
let vn6 = h('div', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
let c7 = [], p7 = {key:\`\${key1}_7\`,on:{}};
|
|
||||||
let vn7 = h('button', p7, c7);
|
|
||||||
c6.push(vn7);
|
|
||||||
const otherState_8 = scope['otherState'];
|
|
||||||
const iter_8 = scope.iter;
|
|
||||||
p7.on['click'] = function (e) {if (!context.__owl__.isMounted){return}otherState_8.vals.push(iter_8+'_'+iter_8)};
|
|
||||||
c7.push({text: \`expr\`});
|
|
||||||
utils.getScope(scope, 'iter').iter = scope.iter+1;
|
|
||||||
}
|
|
||||||
scope = _origScope5;
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-on expression in t-foreach 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
let _2 = scope['state'].values;
|
|
||||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
|
||||||
let _3 = _4 = _2;
|
|
||||||
if (!(_2 instanceof Array)) {
|
|
||||||
_3 = Object.keys(_2);
|
|
||||||
_4 = Object.values(_2);
|
|
||||||
}
|
|
||||||
let _length3 = _3.length;
|
|
||||||
let _origScope5 = scope;
|
|
||||||
scope = Object.create(scope);
|
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
|
||||||
scope.val_first = i1 === 0
|
|
||||||
scope.val_last = i1 === _length3 - 1
|
|
||||||
scope.val_index = i1
|
|
||||||
scope.val = _3[i1]
|
|
||||||
scope.val_value = _4[i1]
|
|
||||||
let key1 = scope['val'];
|
|
||||||
let c6 = [], p6 = {key:\`\${key1}_6\`};
|
|
||||||
let vn6 = h('div', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
let _7 = scope['val_index'];
|
|
||||||
if (_7 != null) {
|
|
||||||
c6.push({text: _7});
|
|
||||||
}
|
|
||||||
c6.push({text: \`: \`});
|
|
||||||
let _8 = scope['val']+'';
|
|
||||||
if (_8 != null) {
|
|
||||||
c6.push({text: _8});
|
|
||||||
}
|
|
||||||
let c9 = [], p9 = {key:\`\${key1}_9\`,on:{}};
|
|
||||||
let vn9 = h('button', p9, c9);
|
|
||||||
c6.push(vn9);
|
|
||||||
const otherState_10 = scope['otherState'];
|
|
||||||
const val_10 = scope['val'];
|
|
||||||
p9.on['click'] = function (e) {if (!context.__owl__.isMounted){return}otherState_10.vals.push(val_10)};
|
|
||||||
c9.push({text: \`Expr\`});
|
|
||||||
}
|
|
||||||
scope = _origScope5;
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-on expression in t-foreach with t-set 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.bossa = 'nova';
|
|
||||||
let _2 = scope['state'].values;
|
|
||||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
|
||||||
let _3 = _4 = _2;
|
|
||||||
if (!(_2 instanceof Array)) {
|
|
||||||
_3 = Object.keys(_2);
|
|
||||||
_4 = Object.values(_2);
|
|
||||||
}
|
|
||||||
let _length3 = _3.length;
|
|
||||||
let _origScope5 = scope;
|
|
||||||
scope = Object.create(scope);
|
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
|
||||||
scope.val_first = i1 === 0
|
|
||||||
scope.val_last = i1 === _length3 - 1
|
|
||||||
scope.val_index = i1
|
|
||||||
scope.val = _3[i1]
|
|
||||||
scope.val_value = _4[i1]
|
|
||||||
let key1 = scope['val'];
|
|
||||||
let c6 = [], p6 = {key:\`\${key1}_6\`};
|
|
||||||
let vn6 = h('div', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
utils.getScope(scope, 'bossa').bossa = scope.bossa+'_'+scope['val_index'];
|
|
||||||
let _7 = scope['val_index'];
|
|
||||||
if (_7 != null) {
|
|
||||||
c6.push({text: _7});
|
|
||||||
}
|
|
||||||
c6.push({text: \`: \`});
|
|
||||||
let _8 = scope['val']+'';
|
|
||||||
if (_8 != null) {
|
|
||||||
c6.push({text: _8});
|
|
||||||
}
|
|
||||||
let c9 = [], p9 = {key:\`\${key1}_9\`,on:{}};
|
|
||||||
let vn9 = h('button', p9, c9);
|
|
||||||
c6.push(vn9);
|
|
||||||
const otherState_10 = scope['otherState'];
|
|
||||||
const val_10 = scope['val'];
|
|
||||||
const bossa_10 = scope.bossa;
|
|
||||||
p9.on['click'] = function (e) {if (!context.__owl__.isMounted){return}otherState_10.vals.push(val_10+'_'+bossa_10)};
|
|
||||||
c9.push({text: \`Expr\`});
|
|
||||||
}
|
|
||||||
scope = _origScope5;
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-on method call in t-foreach 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
let _2 = scope['state'].values;
|
|
||||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
|
||||||
let _3 = _4 = _2;
|
|
||||||
if (!(_2 instanceof Array)) {
|
|
||||||
_3 = Object.keys(_2);
|
|
||||||
_4 = Object.values(_2);
|
|
||||||
}
|
|
||||||
let _length3 = _3.length;
|
|
||||||
let _origScope5 = scope;
|
|
||||||
scope = Object.create(scope);
|
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
|
||||||
scope.val_first = i1 === 0
|
|
||||||
scope.val_last = i1 === _length3 - 1
|
|
||||||
scope.val_index = i1
|
|
||||||
scope.val = _3[i1]
|
|
||||||
scope.val_value = _4[i1]
|
|
||||||
let key1 = scope['val'];
|
|
||||||
let c6 = [], p6 = {key:\`\${key1}_6\`};
|
|
||||||
let vn6 = h('div', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
let _7 = scope['val_index'];
|
|
||||||
if (_7 != null) {
|
|
||||||
c6.push({text: _7});
|
|
||||||
}
|
|
||||||
c6.push({text: \`: \`});
|
|
||||||
let _8 = scope['val']+'';
|
|
||||||
if (_8 != null) {
|
|
||||||
c6.push({text: _8});
|
|
||||||
}
|
|
||||||
let c9 = [], p9 = {key:\`\${key1}_9\`,on:{}};
|
|
||||||
let vn9 = h('button', p9, c9);
|
|
||||||
c6.push(vn9);
|
|
||||||
let args10 = [scope['val']];
|
|
||||||
p9.on['click'] = function (e) {if (!context.__owl__.isMounted){return}utils.getComponent(context)['addVal'](...args10, e);};
|
|
||||||
c9.push({text: \`meth call\`});
|
|
||||||
}
|
|
||||||
scope = _origScope5;
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-on with getter as handler 1`] = `
|
exports[`other directives with t-component t-on with getter as handler 1`] = `
|
||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
@@ -1051,7 +801,6 @@ exports[`other directives with t-component t-on with inline statement 1`] = `
|
|||||||
c1.push({text: _2});
|
c1.push({text: _2});
|
||||||
}
|
}
|
||||||
// Component 'Child'
|
// Component 'Child'
|
||||||
const state_5 = scope['state'];
|
|
||||||
let w3 = '__4__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__4__']] : false;
|
let w3 = '__4__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__4__']] : false;
|
||||||
let props3 = {};
|
let props3 = {};
|
||||||
if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) {
|
if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) {
|
||||||
@@ -1068,7 +817,7 @@ exports[`other directives with t-component t-on with inline statement 1`] = `
|
|||||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
||||||
w3 = new W3(parent, props3);
|
w3 = new W3(parent, props3);
|
||||||
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
||||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (!context.__owl__.isMounted){return}state_5.counter++});}};});
|
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {if (!context.__owl__.isMounted){return}scope['state'].counter++});}};});
|
||||||
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
||||||
c1.push(pvnode);
|
c1.push(pvnode);
|
||||||
w3.__owl__.pvnode = pvnode;
|
w3.__owl__.pvnode = pvnode;
|
||||||
@@ -1268,195 +1017,6 @@ exports[`other directives with t-component t-on with stop and/or prevent modifie
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`other directives with t-component t-set can't alter component 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
let c2 = [], p2 = {key:2};
|
|
||||||
let vn2 = h('p', p2, c2);
|
|
||||||
c1.push(vn2);
|
|
||||||
let _3 = scope['iter'];
|
|
||||||
if (_3 != null) {
|
|
||||||
c2.push({text: _3});
|
|
||||||
}
|
|
||||||
scope.iter = 5;
|
|
||||||
let c4 = [], p4 = {key:4};
|
|
||||||
let vn4 = h('p', p4, c4);
|
|
||||||
c1.push(vn4);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c4.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-set can't alter from within callee 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 'source';
|
|
||||||
let c2 = [], p2 = {key:2};
|
|
||||||
let vn2 = h('p', p2, c2);
|
|
||||||
c1.push(vn2);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c2.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
this.subTemplates['ChildWidget'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
|
||||||
let c5 = [], p5 = {key:5};
|
|
||||||
let vn5 = h('p', p5, c5);
|
|
||||||
c1.push(vn5);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c5.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-set can't alter in t-call body 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 'source';
|
|
||||||
let c2 = [], p2 = {key:2};
|
|
||||||
let vn2 = h('p', p2, c2);
|
|
||||||
c1.push(vn2);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c2.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let _origScope4 = scope;
|
|
||||||
scope = Object.assign(Object.create(context), scope);
|
|
||||||
{
|
|
||||||
let c__0 = [];
|
|
||||||
utils.getScope(scope, 'iter').iter = 'inCall';
|
|
||||||
scope[utils.zero] = c__0;
|
|
||||||
}
|
|
||||||
this.subTemplates['ChildWidget'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
|
|
||||||
scope = _origScope4;
|
|
||||||
}
|
|
||||||
let c6 = [], p6 = {key:6};
|
|
||||||
let vn6 = h('p', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c6.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-set not altered by child widget 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__2\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let QWeb = this.constructor;
|
|
||||||
let parent = context;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 'source';
|
|
||||||
let c2 = [], p2 = {key:2};
|
|
||||||
let vn2 = h('p', p2, c2);
|
|
||||||
c1.push(vn2);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c2.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
// Component 'ChildWidget'
|
|
||||||
let w3 = '__4__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__4__']] : false;
|
|
||||||
let props3 = {};
|
|
||||||
if (w3 && w3.__owl__.currentFiber && !w3.__owl__.vnode) {
|
|
||||||
w3.destroy();
|
|
||||||
w3 = false;
|
|
||||||
}
|
|
||||||
if (w3) {
|
|
||||||
w3.__updateProps(props3, extra.fiber, undefined);
|
|
||||||
let pvnode = w3.__owl__.pvnode;
|
|
||||||
c1.push(pvnode);
|
|
||||||
} else {
|
|
||||||
let componentKey3 = \`ChildWidget\`;
|
|
||||||
let W3 = context.constructor.components[componentKey3] || QWeb.components[componentKey3]|| scope['ChildWidget'];
|
|
||||||
if (!W3) {throw new Error('Cannot find the definition of component \\"' + componentKey3 + '\\"')}
|
|
||||||
w3 = new W3(parent, props3);
|
|
||||||
parent.__owl__.cmap['__4__'] = w3.__owl__.id;
|
|
||||||
let fiber = w3.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; });
|
|
||||||
let pvnode = h('dummy', {key: '__4__', hook: {remove() {},destroy(vn) {w3.destroy();}}});
|
|
||||||
c1.push(pvnode);
|
|
||||||
w3.__owl__.pvnode = pvnode;
|
|
||||||
}
|
|
||||||
w3.__owl__.parentLastFiberId = extra.fiber.id;
|
|
||||||
let c5 = [], p5 = {key:5};
|
|
||||||
let vn5 = h('p', p5, c5);
|
|
||||||
c1.push(vn5);
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c5.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`other directives with t-component t-set outside modified in t-foreach 1`] = `
|
|
||||||
"function anonymous(context, extra
|
|
||||||
) {
|
|
||||||
// Template name: \\"__template__1\\"
|
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
|
||||||
let h = this.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
let vn1 = h('div', p1, c1);
|
|
||||||
scope.iter = 0;
|
|
||||||
let _2 = scope['state'].values;
|
|
||||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
|
||||||
let _3 = _4 = _2;
|
|
||||||
if (!(_2 instanceof Array)) {
|
|
||||||
_3 = Object.keys(_2);
|
|
||||||
_4 = Object.values(_2);
|
|
||||||
}
|
|
||||||
let _length3 = _3.length;
|
|
||||||
let _origScope5 = scope;
|
|
||||||
scope = Object.create(scope);
|
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
|
||||||
scope.val_first = i1 === 0
|
|
||||||
scope.val_last = i1 === _length3 - 1
|
|
||||||
scope.val_index = i1
|
|
||||||
scope.val = _3[i1]
|
|
||||||
scope.val_value = _4[i1]
|
|
||||||
let key1 = scope['val'];
|
|
||||||
let c6 = [], p6 = {key:\`\${key1}_6\`};
|
|
||||||
let vn6 = h('p', p6, c6);
|
|
||||||
c1.push(vn6);
|
|
||||||
c6.push({text: \`InLoop: \`});
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c6.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
utils.getScope(scope, 'iter').iter = scope.iter+1;
|
|
||||||
}
|
|
||||||
scope = _origScope5;
|
|
||||||
let c7 = [], p7 = {key:7};
|
|
||||||
let vn7 = h('p', p7, c7);
|
|
||||||
c1.push(vn7);
|
|
||||||
c7.push({text: \`EndLoop: \`});
|
|
||||||
if (scope.iter != null) {
|
|
||||||
c7.push({text: scope.iter});
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`random stuff/miscellaneous can inject values in tagged templates 1`] = `
|
exports[`random stuff/miscellaneous can inject values in tagged templates 1`] = `
|
||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
@@ -1466,7 +1026,7 @@ exports[`random stuff/miscellaneous can inject values in tagged templates 1`] =
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
this.subTemplates['__template__1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['__template__1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1533,7 +1093,7 @@ exports[`random stuff/miscellaneous t-on with handler bound to dynamic argument
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -1782,7 +1342,7 @@ exports[`t-model directive in a t-foreach 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.thing_first = i1 === 0
|
scope.thing_first = i1 === 0
|
||||||
scope.thing_last = i1 === _length3 - 1
|
scope.thing_last = i1 === _length3 - 1
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 2`] = `
|
|||||||
}
|
}
|
||||||
let _length4 = _4.length;
|
let _length4 = _4.length;
|
||||||
let _origScope6 = scope;
|
let _origScope6 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length4; i1++) {
|
for (let i1 = 0; i1 < _length4; i1++) {
|
||||||
scope.user_first = i1 === 0
|
scope.user_first = i1 === 0
|
||||||
scope.user_last = i1 === _length4 - 1
|
scope.user_last = i1 === _length4 - 1
|
||||||
@@ -360,7 +360,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
|
|||||||
}
|
}
|
||||||
let _length4 = _4.length;
|
let _length4 = _4.length;
|
||||||
let _origScope6 = scope;
|
let _origScope6 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length4; i1++) {
|
for (let i1 = 0; i1 < _length4; i1++) {
|
||||||
scope.user_first = i1 === 0
|
scope.user_first = i1 === 0
|
||||||
scope.user_last = i1 === _length4 - 1
|
scope.user_last = i1 === _length4 - 1
|
||||||
@@ -371,7 +371,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 2`] = `
|
|||||||
let c7 = [], p7 = {key:\`\${key1}_7\`};
|
let c7 = [], p7 = {key:\`\${key1}_7\`};
|
||||||
let vn7 = h('li', p7, c7);
|
let vn7 = h('li', p7, c7);
|
||||||
c2.push(vn7);
|
c2.push(vn7);
|
||||||
utils.getScope(scope, 'userdescr').userdescr = 'User '+scope['user'].name;
|
scope.userdescr = 'User '+scope['user'].name;
|
||||||
// Component 'Link'
|
// Component 'Link'
|
||||||
let k9 = \`__9__\${key1}__\`;
|
let k9 = \`__9__\${key1}__\`;
|
||||||
let w8 = k9 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[k9]] : false;
|
let w8 = k9 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[k9]] : false;
|
||||||
|
|||||||
@@ -2671,7 +2671,7 @@ describe("other directives with t-component", () => {
|
|||||||
expect(fixture.innerHTML).toBe("<div><span>B0</span><span>B1</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>B0</span><span>B1</span></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-set outside modified in t-foreach", async () => {
|
test.only("t-set outside modified in t-foreach", async () => {
|
||||||
class SomeWidget extends Component<any, any> {
|
class SomeWidget extends Component<any, any> {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -2683,195 +2683,15 @@ describe("other directives with t-component", () => {
|
|||||||
<p>EndLoop: <t t-esc="iter"/></p>
|
<p>EndLoop: <t t-esc="iter"/></p>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
state = useState({values: ['a', 'b']});
|
||||||
}
|
}
|
||||||
const widget = new SomeWidget();
|
const widget = new SomeWidget();
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>InLoop: 0</p><p>InLoop: 1</p><p>EndLoop: 2</p></div>");
|
expect(fixture.innerHTML).toBe("<div><p>Inloop: 0</p><p>Inloop: 1</p><p>EndLoop: 2<p></div>");
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("t-set outside modified in t-if", async () => {
|
test.only("t-set outside modified in t-foreach increment operator", async () => {
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="0"/>
|
|
||||||
<t t-set="flag" t-value="state.flag" />
|
|
||||||
<t t-if="flag === 'if'">
|
|
||||||
<t t-set="iter" t-value="2"/>
|
|
||||||
</t>
|
|
||||||
<t t-elif="flag === 'elif'">
|
|
||||||
<t t-set="iter" t-value="3"/>
|
|
||||||
</t>
|
|
||||||
<t t-else="">
|
|
||||||
<t t-set="iter" t-value="4"/>
|
|
||||||
</t>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = { flag: "if" };
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>2</p></div>");
|
|
||||||
widget.state.flag = "elif";
|
|
||||||
await widget.render();
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>3</p></div>");
|
|
||||||
widget.state.flag = "false";
|
|
||||||
await widget.render();
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>4</p></div>");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set in t-if", async () => {
|
|
||||||
// Weird that code block within 'if' leaks outside of it
|
|
||||||
// Python does the same
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="flag" t-value="state.flag" />
|
|
||||||
<t t-if="flag === 'if'">
|
|
||||||
<t t-set="iter" t-value="2"/>
|
|
||||||
</t>
|
|
||||||
<t t-elif="flag === 'elif'">
|
|
||||||
<t t-set="iter" t-value="3"/>
|
|
||||||
</t>
|
|
||||||
<t t-else="">
|
|
||||||
<t t-set="iter" t-value="4"/>
|
|
||||||
</t>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = { flag: "if" };
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>2</p></div>");
|
|
||||||
widget.state.flag = "elif";
|
|
||||||
await widget.render();
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>3</p></div>");
|
|
||||||
widget.state.flag = "false";
|
|
||||||
await widget.render();
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>4</p></div>");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set can't alter component", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
<t t-set="iter" t-value="5"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
iter = 1;
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>1</p><p>5</p></div>");
|
|
||||||
expect(widget.iter).toBe(1);
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set can't alter from within callee", async () => {
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"ChildWidget",
|
|
||||||
`<div><t t-esc="iter"/><t t-set="iter" t-value="'called'"/><t t-esc="iter"/></div>`
|
|
||||||
);
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="'source'"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
<t t-call="ChildWidget"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>source</p><div>sourcecalled</div><p>source</p></div>");
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set can't alter in t-call body", async () => {
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"ChildWidget",
|
|
||||||
`<div><t t-esc="iter"/><t t-set="iter" t-value="'called'"/><t t-esc="iter"/></div>`
|
|
||||||
);
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="'source'"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
<t t-call="ChildWidget">
|
|
||||||
<t t-set="iter" t-value="'inCall'"/>
|
|
||||||
</t>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>source</p><div>inCallcalled</div><p>source</p></div>");
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("slot setted value (with t-set) not accessible with t-esc", async () => {
|
|
||||||
class ChildWidget extends Component<any, any> {
|
|
||||||
static template = xml`<div><t t-esc="iter"/><t t-set="iter" t-value="'called'"/><t t-esc="iter"/></div>`;
|
|
||||||
}
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static components = { ChildWidget };
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="'source'"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
<ChildWidget>
|
|
||||||
<t t-set="iter" t-value="'inCall'"/>
|
|
||||||
</ChildWidget>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>source</p><div>called</div><p>source</p></div>");
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set not altered by child widget", async () => {
|
|
||||||
let child;
|
|
||||||
class ChildWidget extends Component<any, any> {
|
|
||||||
static template = xml`<div><t t-esc="iter"/><t t-set="iter" t-value="'called'"/><t t-esc="iter"/></div>`;
|
|
||||||
iter = "child";
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
child = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static components = { ChildWidget };
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="'source'"/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
<ChildWidget/>
|
|
||||||
<p><t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>source</p><div>childcalled</div><p>source</p></div>");
|
|
||||||
expect(child.iter).toBe("child");
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set outside modified in t-foreach increment-after operator", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
class SomeWidget extends Component<any, any> {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -2883,145 +2703,12 @@ describe("other directives with t-component", () => {
|
|||||||
<p>EndLoop: <t t-esc="iter"/></p>
|
<p>EndLoop: <t t-esc="iter"/></p>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
state = useState({values: ['a', 'b']});
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>InLoop: 0</p><p>InLoop: 1</p><p>EndLoop: 0</p></div>");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-set outside modified in t-foreach increment-before operator", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="0"/>
|
|
||||||
<t t-foreach="state.values" t-as="val" t-key="val">
|
|
||||||
<p>InLoop: <t t-esc="iter"/></p>
|
|
||||||
<t t-set="iter" t-value="++iter"/>
|
|
||||||
</t>
|
|
||||||
<p>EndLoop: <t t-esc="iter"/></p>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p>InLoop: 0</p><p>InLoop: 1</p><p>EndLoop: 1</p></div>");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-on expression in t-foreach", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
|
||||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
|
||||||
<button t-on-click="otherState.vals.push(val)">Expr</button>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
|
||||||
otherState = { vals: [] };
|
|
||||||
}
|
}
|
||||||
const widget = new SomeWidget();
|
const widget = new SomeWidget();
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe(
|
expect(fixture.innerHTML).toBe("<div><p>Inloop: 0</p><p>Inloop: 1</p><p>EndLoop: 2<p></div>");
|
||||||
"<div><div>0: a<button>Expr</button></div><div>1: b<button>Expr</button></div></div>"
|
|
||||||
);
|
|
||||||
expect(widget.otherState.vals).toStrictEqual([]);
|
|
||||||
const buttons = fixture.querySelectorAll("button");
|
|
||||||
buttons[0].click();
|
|
||||||
buttons[1].click();
|
|
||||||
expect(widget.otherState.vals).toStrictEqual(["a", "b"]);
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-on expression in t-foreach with t-set", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="bossa" t-value="'nova'"/>
|
|
||||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
|
||||||
<t t-set="bossa" t-value="bossa + '_' + val_index" />
|
|
||||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
|
||||||
<button t-on-click="otherState.vals.push(val + '_' + bossa)">Expr</button>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
|
||||||
otherState = { vals: [] };
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
"<div><div>0: a<button>Expr</button></div><div>1: b<button>Expr</button></div></div>"
|
|
||||||
);
|
|
||||||
expect(widget.otherState.vals).toStrictEqual([]);
|
|
||||||
const buttons = fixture.querySelectorAll("button");
|
|
||||||
buttons[0].click();
|
|
||||||
buttons[1].click();
|
|
||||||
expect(widget.otherState.vals).toStrictEqual(["a_nova_0", "b_nova_0_1"]);
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-on method call in t-foreach", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<div t-foreach="state.values" t-as="val" t-key="val">
|
|
||||||
<t t-esc="val_index"/>: <t t-esc="val + ''"/>
|
|
||||||
<button t-on-click="addVal(val)">meth call</button>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
state = useState({ values: ["a", "b"] });
|
|
||||||
otherState = { vals: new Array<string>() };
|
|
||||||
|
|
||||||
addVal(val: string) {
|
|
||||||
this.otherState.vals.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
"<div><div>0: a<button>meth call</button></div><div>1: b<button>meth call</button></div></div>"
|
|
||||||
);
|
|
||||||
expect(widget.otherState.vals).toStrictEqual([]);
|
|
||||||
const buttons = fixture.querySelectorAll("button");
|
|
||||||
buttons[0].click();
|
|
||||||
buttons[1].click();
|
|
||||||
expect(widget.otherState.vals).toStrictEqual(["a", "b"]);
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-on expression captured in t-foreach", async () => {
|
|
||||||
class SomeWidget extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-set="iter" t-value="0" />
|
|
||||||
<div t-foreach="arr" t-as="val" t-key="val">
|
|
||||||
<button t-on-click="otherState.vals.push(iter + '_' + iter)">expr</button>
|
|
||||||
<t t-set="iter" t-value="iter + 1" />
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
arr = ["a", "b"];
|
|
||||||
otherState = { vals: new Array<string>() };
|
|
||||||
}
|
|
||||||
const widget = new SomeWidget();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
"<div><div><button>expr</button></div><div><button>expr</button></div></div>"
|
|
||||||
);
|
|
||||||
expect(widget.otherState.vals).toStrictEqual([]);
|
|
||||||
const buttons = fixture.querySelectorAll("button");
|
|
||||||
buttons[0].click();
|
|
||||||
buttons[1].click();
|
|
||||||
expect(widget.otherState.vals).toStrictEqual(["0_0", "1_1"]);
|
|
||||||
expect(QWeb.TEMPLATES[SomeWidget.template].fn.toString()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -6079,29 +5766,4 @@ describe("t-call", () => {
|
|||||||
|
|
||||||
fixture.querySelector("p")!.click();
|
fixture.querySelector("p")!.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sub components in two t-calls", async () => {
|
|
||||||
class Child extends Component<any, any> {
|
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
env.qweb.addTemplate("sub", `<Child val="state.val"/>`);
|
|
||||||
class Parent extends Component<any, any> {
|
|
||||||
static template = xml`
|
|
||||||
<div>
|
|
||||||
<t t-if="state.val===1">
|
|
||||||
<t t-call="sub"/>
|
|
||||||
</t>
|
|
||||||
<div t-else=""><t t-call="sub"/></div>
|
|
||||||
</div>`;
|
|
||||||
static components = { Child };
|
|
||||||
state = useState({ val: 1 });
|
|
||||||
}
|
|
||||||
const parent = new Parent();
|
|
||||||
await parent.mount(fixture);
|
|
||||||
expect(fixture.innerHTML).toBe("<div><span>1</span></div>");
|
|
||||||
parent.state.val = 2;
|
|
||||||
await nextTick();
|
|
||||||
expect(fixture.innerHTML).toBe("<div><div><span>2</span></div></div>");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -138,32 +138,7 @@ describe("styles and component", () => {
|
|||||||
}
|
}
|
||||||
}`);
|
}`);
|
||||||
|
|
||||||
expect(sheet)
|
expect(sheet).toBe(`.parent-a .child-a, .parent-a .child-b, .parent-b .child-a, .parent-b .child-b {
|
||||||
.toBe(`.parent-a .child-a, .parent-a .child-b, .parent-b .child-a, .parent-b .child-b {
|
|
||||||
color: red;
|
|
||||||
}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("handle & selector", async () => {
|
|
||||||
let sheet = processSheet(`.btn {
|
|
||||||
&.danger {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}`);
|
|
||||||
|
|
||||||
expect(sheet).toBe(`.btn.danger {
|
|
||||||
color: red;
|
|
||||||
}`);
|
|
||||||
|
|
||||||
sheet = processSheet(`.some-class {
|
|
||||||
&.btn {
|
|
||||||
.other-class ~ & {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`);
|
|
||||||
|
|
||||||
expect(sheet).toBe(`.other-class ~ .some-class.btn {
|
|
||||||
color: red;
|
color: red;
|
||||||
}`);
|
}`);
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-37
@@ -9,8 +9,7 @@ import {
|
|||||||
onWillPatch,
|
onWillPatch,
|
||||||
onWillStart,
|
onWillStart,
|
||||||
onWillUpdateProps,
|
onWillUpdateProps,
|
||||||
useSubEnv,
|
useSubEnv
|
||||||
useExternalListener
|
|
||||||
} from "../src/hooks";
|
} from "../src/hooks";
|
||||||
import { xml } from "../src/tags";
|
import { xml } from "../src/tags";
|
||||||
|
|
||||||
@@ -593,39 +592,4 @@ describe("hooks", () => {
|
|||||||
expect(fixture.innerHTML).toBe("<div><span>2</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>2</span></div>");
|
||||||
expect(steps).toEqual(["onWillStart", "onWillUpdateProps"]);
|
expect(steps).toEqual(["onWillStart", "onWillUpdateProps"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("useExternalListener", async () => {
|
|
||||||
let n = 0;
|
|
||||||
|
|
||||||
class MyComponent extends Component<any, any> {
|
|
||||||
static template = xml`<span><t t-esc="props.value"/></span>`;
|
|
||||||
constructor(parent, props) {
|
|
||||||
super(parent, props);
|
|
||||||
useExternalListener(window as any, "click", this.increment);
|
|
||||||
}
|
|
||||||
increment() {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class App extends Component<any, any> {
|
|
||||||
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
|
||||||
static components = { MyComponent };
|
|
||||||
state = useState({ flag: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = new App();
|
|
||||||
await app.mount(fixture);
|
|
||||||
|
|
||||||
expect(n).toBe(0);
|
|
||||||
window.dispatchEvent(new Event("click"));
|
|
||||||
expect(n).toBe(0);
|
|
||||||
app.state.flag = true;
|
|
||||||
await nextTick();
|
|
||||||
window.dispatchEvent(new Event("click"));
|
|
||||||
expect(n).toBe(1);
|
|
||||||
app.state.flag = false;
|
|
||||||
await nextTick();
|
|
||||||
window.dispatchEvent(new Event("click"));
|
|
||||||
expect(n).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ exports[`foreach does not pollute the rendering context 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -456,7 +456,7 @@ exports[`foreach iterate on items (on a element node) 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -494,7 +494,7 @@ exports[`foreach iterate on items 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -541,7 +541,7 @@ exports[`foreach iterate, dict param 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -588,7 +588,7 @@ exports[`foreach iterate, position 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.elem_first = i1 === 0
|
scope.elem_first = i1 === 0
|
||||||
scope.elem_last = i1 === _length3 - 1
|
scope.elem_last = i1 === _length3 - 1
|
||||||
@@ -632,7 +632,7 @@ exports[`foreach t-foreach in t-forach 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.number_first = i1 === 0
|
scope.number_first = i1 === 0
|
||||||
scope.number_last = i1 === _length3 - 1
|
scope.number_last = i1 === _length3 - 1
|
||||||
@@ -649,7 +649,7 @@ exports[`foreach t-foreach in t-forach 1`] = `
|
|||||||
}
|
}
|
||||||
let _length7 = _7.length;
|
let _length7 = _7.length;
|
||||||
let _origScope9 = scope;
|
let _origScope9 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i2 = 0; i2 < _length7; i2++) {
|
for (let i2 = 0; i2 < _length7; i2++) {
|
||||||
scope.letter_first = i2 === 0
|
scope.letter_first = i2 === 0
|
||||||
scope.letter_last = i2 === _length7 - 1
|
scope.letter_last = i2 === _length7 - 1
|
||||||
@@ -692,7 +692,7 @@ exports[`foreach warn if no key in some case 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -734,7 +734,7 @@ exports[`loading templates can load a few templates from a xml string 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('ul', p1, c1);
|
let vn1 = h('ul', p1, c1);
|
||||||
this.subTemplates['items'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['items'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -757,7 +757,7 @@ exports[`misc global 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.value_first = i1 === 0
|
scope.value_first = i1 === 0
|
||||||
scope.value_last = i1 === _length3 - 1
|
scope.value_last = i1 === _length3 - 1
|
||||||
@@ -782,7 +782,7 @@ exports[`misc global 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'foo').foo = 'aaa';
|
scope.foo = 'aaa';
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
let k14 = \`__14__\${key1}__\`;
|
let k14 = \`__14__\${key1}__\`;
|
||||||
@@ -791,7 +791,7 @@ exports[`misc global 1`] = `
|
|||||||
}
|
}
|
||||||
let k15 = \`__15__\${key1}__\`;
|
let k15 = \`__15__\${key1}__\`;
|
||||||
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k15}));
|
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k15}));
|
||||||
utils.getScope(scope, 'foo').foo = 'bbb';
|
scope.foo = 'bbb';
|
||||||
let k16 = \`__16__\${key1}__\`;
|
let k16 = \`__16__\${key1}__\`;
|
||||||
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k16}));
|
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c__0, parent: utils.getComponent(context), key: k16}));
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
@@ -802,7 +802,7 @@ exports[`misc global 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope = _origScope5;
|
scope = _origScope5;
|
||||||
this.subTemplates['_callee-asc-toto'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__20__'}));
|
this.subTemplates['_callee-asc-toto'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1041,7 +1041,7 @@ exports[`t-call (template calling basic caller 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1069,7 +1069,7 @@ exports[`t-call (template calling basic caller, no parent node 1`] = `
|
|||||||
let result;
|
let result;
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
result = []
|
result = []
|
||||||
this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['_basic-callee'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context)}));
|
||||||
result = result[0]
|
result = result[0]
|
||||||
return result;
|
return result;
|
||||||
}"
|
}"
|
||||||
@@ -1114,7 +1114,7 @@ exports[`t-call (template calling call with several sub nodes on same line 1`] =
|
|||||||
c5.push({text: \`yay\`});
|
c5.push({text: \`yay\`});
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
|
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1162,7 +1162,7 @@ exports[`t-call (template calling cascading t-call t-raw='0' 1`] = `
|
|||||||
c14.push({text: \`yay\`});
|
c14.push({text: \`yay\`});
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__15__'}));
|
this.subTemplates['SubTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope12;
|
scope = _origScope12;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1179,7 +1179,7 @@ exports[`t-call (template calling inherit context 1`] = `
|
|||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
scope.foo = 1;
|
scope.foo = 1;
|
||||||
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__2__'}));
|
this.subTemplates['_callee-uses-foo'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1198,7 +1198,7 @@ exports[`t-call (template calling recursive template, part 1 1`] = `
|
|||||||
c1.push(vn2);
|
c1.push(vn2);
|
||||||
c2.push({text: \`hey\`});
|
c2.push({text: \`hey\`});
|
||||||
if (false) {
|
if (false) {
|
||||||
this.subTemplates['recursive'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'}));
|
this.subTemplates['recursive'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1241,10 +1241,10 @@ exports[`t-call (template calling recursive template, part 2 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'node').node = scope['root'];
|
scope.node = scope['root'];
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
|
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope11;
|
scope = _origScope11;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1279,7 +1279,7 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
|
|||||||
}
|
}
|
||||||
let _length6 = _6.length;
|
let _length6 = _6.length;
|
||||||
let _origScope8 = scope;
|
let _origScope8 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length6; i1++) {
|
for (let i1 = 0; i1 < _length6; i1++) {
|
||||||
scope.subtree_first = i1 === 0
|
scope.subtree_first = i1 === 0
|
||||||
scope.subtree_last = i1 === _length6 - 1
|
scope.subtree_last = i1 === _length6 - 1
|
||||||
@@ -1292,7 +1292,7 @@ exports[`t-call (template calling recursive template, part 2 2`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'node').node = scope['subtree'];
|
scope.node = scope['subtree'];
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
let k10 = \`__10__\${key0}__\${key1}__\`;
|
let k10 = \`__10__\${key0}__\${key1}__\`;
|
||||||
@@ -1318,10 +1318,10 @@ exports[`t-call (template calling recursive template, part 3 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'node').node = scope['root'];
|
scope.node = scope['root'];
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__12__'}));
|
this.subTemplates['nodeTemplate'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope11;
|
scope = _origScope11;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1356,7 +1356,7 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
|
|||||||
}
|
}
|
||||||
let _length6 = _6.length;
|
let _length6 = _6.length;
|
||||||
let _origScope8 = scope;
|
let _origScope8 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length6; i1++) {
|
for (let i1 = 0; i1 < _length6; i1++) {
|
||||||
scope.subtree_first = i1 === 0
|
scope.subtree_first = i1 === 0
|
||||||
scope.subtree_last = i1 === _length6 - 1
|
scope.subtree_last = i1 === _length6 - 1
|
||||||
@@ -1369,7 +1369,7 @@ exports[`t-call (template calling recursive template, part 3 2`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'node').node = scope['subtree'];
|
scope.node = scope['subtree'];
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
let k10 = \`__10__\${key0}__\${key1}__\`;
|
let k10 = \`__10__\${key0}__\${key1}__\`;
|
||||||
@@ -1395,10 +1395,10 @@ exports[`t-call (template calling scoped parameters 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'foo').foo = 42;
|
scope.foo = 42;
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope2;
|
scope = _origScope2;
|
||||||
}
|
}
|
||||||
if (scope.foo != null) {
|
if (scope.foo != null) {
|
||||||
@@ -1418,7 +1418,7 @@ exports[`t-call (template calling t-call with t-if 1`] = `
|
|||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
if (scope['flag']) {
|
if (scope['flag']) {
|
||||||
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -1456,7 +1456,7 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.v_first = i1 === 0
|
scope.v_first = i1 === 0
|
||||||
scope.v_last = i1 === _length3 - 1
|
scope.v_last = i1 === _length3 - 1
|
||||||
@@ -1464,13 +1464,13 @@ exports[`t-call (template calling t-call with t-set inside and outside 1`] = `
|
|||||||
scope.v = _3[i1]
|
scope.v = _3[i1]
|
||||||
scope.v_value = _4[i1]
|
scope.v_value = _4[i1]
|
||||||
let key1 = i1;
|
let key1 = i1;
|
||||||
utils.getScope(scope, 'val').val = scope['v'].val;
|
scope.val = scope['v'].val;
|
||||||
{
|
{
|
||||||
let _origScope8 = scope;
|
let _origScope8 = scope;
|
||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'val3').val3 = scope.val*3;
|
scope.val3 = scope.val*3;
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
let k9 = \`__9__\${key1}__\`;
|
let k9 = \`__9__\${key1}__\`;
|
||||||
@@ -1493,7 +1493,7 @@ exports[`t-call (template calling t-call with t-set inside and outside. 2 1`] =
|
|||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('p', p1, c1);
|
let vn1 = h('p', p1, c1);
|
||||||
scope.w = 'fromwrapper';
|
scope.w = 'fromwrapper';
|
||||||
this.subTemplates['main'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__11__'}));
|
this.subTemplates['main'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1509,19 +1509,19 @@ exports[`t-call (template calling t-call, conditional and t-set in t-call body 1
|
|||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
scope.v1 = 'elif';
|
scope.v1 = 'elif';
|
||||||
if (scope.v1==='if') {
|
if (scope.v1==='if') {
|
||||||
this.subTemplates['callee1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['callee1'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
}
|
}
|
||||||
else if (scope.v1==='elif') {
|
else if (scope.v1==='elif') {
|
||||||
{
|
{
|
||||||
let _origScope6 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'v').v = 'success';
|
scope.v = 'success';
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['callee2'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__7__'}));
|
this.subTemplates['callee2'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope6;
|
scope = _origScope5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1537,7 +1537,7 @@ exports[`t-call (template calling t-call, global templates 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
this.subTemplates['john'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__3__'}));
|
this.subTemplates['john'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -1559,7 +1559,7 @@ exports[`t-call (template calling with unused body 1`] = `
|
|||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
result = []
|
result = []
|
||||||
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context)}));
|
||||||
result = result[0]
|
result = result[0]
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
@@ -1580,11 +1580,11 @@ exports[`t-call (template calling with unused setbody 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'qux').qux = 3;
|
scope.qux = 3;
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
result = []
|
result = []
|
||||||
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['_basic-callee'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context)}));
|
||||||
result = result[0]
|
result = result[0]
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
@@ -1609,7 +1609,7 @@ exports[`t-call (template calling with used body 1`] = `
|
|||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
result = []
|
result = []
|
||||||
this.subTemplates['_callee-printsbody'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['_callee-printsbody'].call(this, scope, Object.assign({}, extra, {parentNode: result, parent: utils.getComponent(context)}));
|
||||||
result = result[0]
|
result = result[0]
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
@@ -1631,10 +1631,10 @@ exports[`t-call (template calling with used set body 1`] = `
|
|||||||
scope = Object.assign(Object.create(context), scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
{
|
{
|
||||||
let c__0 = [];
|
let c__0 = [];
|
||||||
utils.getScope(scope, 'foo').foo = 'ok';
|
scope.foo = 'ok';
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['_callee-uses-foo'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -1834,7 +1834,7 @@ exports[`t-esc t-esc=0 is escaped 1`] = `
|
|||||||
c4.push({text: \`escaped\`});
|
c4.push({text: \`escaped\`});
|
||||||
scope[utils.zero] = c__0;
|
scope[utils.zero] = c__0;
|
||||||
}
|
}
|
||||||
this.subTemplates['test'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__5__'}));
|
this.subTemplates['test'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
scope = _origScope3;
|
scope = _origScope3;
|
||||||
}
|
}
|
||||||
return vn1;
|
return vn1;
|
||||||
@@ -2156,7 +2156,7 @@ exports[`t-key t-key directive in a list 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.beer_first = i1 === 0
|
scope.beer_first = i1 === 0
|
||||||
scope.beer_last = i1 === _length3 - 1
|
scope.beer_last = i1 === _length3 - 1
|
||||||
@@ -2260,7 +2260,7 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.action_first = i1 === 0
|
scope.action_first = i1 === 0
|
||||||
scope.action_last = i1 === _length3 - 1
|
scope.action_last = i1 === _length3 - 1
|
||||||
@@ -2400,8 +2400,7 @@ exports[`t-on t-on with inline statement (function call) 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
const state_2 = scope['state'];
|
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}scope['state'].incrementCounter(2)};
|
||||||
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}state_2.incrementCounter(2)};
|
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -2415,8 +2414,7 @@ exports[`t-on t-on with inline statement 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
const state_2 = scope['state'];
|
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}scope['state'].counter++};
|
||||||
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}state_2.counter++};
|
|
||||||
c1.push({text: \`Click\`});
|
c1.push({text: \`Click\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -2430,8 +2428,7 @@ exports[`t-on t-on with inline statement, part 2 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
const state_2 = scope['state'];
|
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}scope['state'].flag=!scope['state'].flag};
|
||||||
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}state_2.flag=!state_2.flag};
|
|
||||||
c1.push({text: \`Toggle\`});
|
c1.push({text: \`Toggle\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -2445,9 +2442,7 @@ exports[`t-on t-on with inline statement, part 3 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1,on:{}};
|
let c1 = [], p1 = {key:1,on:{}};
|
||||||
let vn1 = h('button', p1, c1);
|
let vn1 = h('button', p1, c1);
|
||||||
const state_2 = scope['state'];
|
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}scope['state'].n=scope['someFunction'](3)};
|
||||||
const someFunction_2 = scope['someFunction'];
|
|
||||||
p1.on['click'] = function (e) {if (!context.__owl__.isMounted){return}state_2.n=someFunction_2(3)};
|
|
||||||
c1.push({text: \`Toggle\`});
|
c1.push({text: \`Toggle\`});
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
@@ -2522,7 +2517,7 @@ exports[`t-on t-on with prevent modifier in t-foreach 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.project_first = i1 === 0
|
scope.project_first = i1 === 0
|
||||||
scope.project_last = i1 === _length3 - 1
|
scope.project_last = i1 === _length3 - 1
|
||||||
@@ -2610,7 +2605,7 @@ exports[`t-on t-on with t-call 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -2624,7 +2619,7 @@ exports[`t-on t-on, with arguments and t-call 1`] = `
|
|||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
let vn1 = h('div', p1, c1);
|
let vn1 = h('div', p1, c1);
|
||||||
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__4__'}));
|
this.subTemplates['sub'].call(this, Object.assign(Object.create(context), scope), Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context)}));
|
||||||
return vn1;
|
return vn1;
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
@@ -2768,7 +2763,7 @@ exports[`t-ref refs in a loop 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.item_first = i1 === 0
|
scope.item_first = i1 === 0
|
||||||
scope.item_last = i1 === _length3 - 1
|
scope.item_last = i1 === _length3 - 1
|
||||||
@@ -2995,7 +2990,6 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
|
|||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
// Template name: \\"test\\"
|
// Template name: \\"test\\"
|
||||||
let utils = this.constructor.utils;
|
|
||||||
let scope = Object.create(context);
|
let scope = Object.create(context);
|
||||||
let h = this.h;
|
let h = this.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
@@ -3010,7 +3004,7 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
|
|||||||
}
|
}
|
||||||
let _length3 = _3.length;
|
let _length3 = _3.length;
|
||||||
let _origScope5 = scope;
|
let _origScope5 = scope;
|
||||||
scope = Object.create(scope);
|
scope = Object.assign(Object.create(context), scope);
|
||||||
for (let i1 = 0; i1 < _length3; i1++) {
|
for (let i1 = 0; i1 < _length3; i1++) {
|
||||||
scope.elem_first = i1 === 0
|
scope.elem_first = i1 === 0
|
||||||
scope.elem_last = i1 === _length3 - 1
|
scope.elem_last = i1 === _length3 - 1
|
||||||
@@ -3028,7 +3022,7 @@ exports[`t-set t-set should reuse variable if possible 1`] = `
|
|||||||
if (scope.v != null) {
|
if (scope.v != null) {
|
||||||
c7.push({text: scope.v});
|
c7.push({text: scope.v});
|
||||||
}
|
}
|
||||||
utils.getScope(scope, 'v').v = scope['elem'];
|
scope.v = scope['elem'];
|
||||||
}
|
}
|
||||||
scope = _origScope5;
|
scope = _origScope5;
|
||||||
return vn1;
|
return vn1;
|
||||||
|
|||||||
@@ -56,12 +56,6 @@ describe("tokenizer", () => {
|
|||||||
{ type: "OPERATOR", value: "..." },
|
{ type: "OPERATOR", value: "..." },
|
||||||
{ type: "VALUE", value: "1" }
|
{ type: "VALUE", value: "1" }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(tokenize("a in b")).toEqual([
|
|
||||||
{ type: "SYMBOL", value: "a" },
|
|
||||||
{ type: "OPERATOR", value: "in " },
|
|
||||||
{ type: "SYMBOL", value: "b" }
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("strings", () => {
|
test("strings", () => {
|
||||||
@@ -140,7 +134,6 @@ describe("expression evaluation", () => {
|
|||||||
expect(compileExpr("color === 'black'", {})).toBe("scope['color']==='black'");
|
expect(compileExpr("color === 'black'", {})).toBe("scope['color']==='black'");
|
||||||
expect(compileExpr("'li_'+item", {})).toBe("'li_'+scope['item']");
|
expect(compileExpr("'li_'+item", {})).toBe("'li_'+scope['item']");
|
||||||
expect(compileExpr("state.val > 1", {})).toBe("scope['state'].val>1");
|
expect(compileExpr("state.val > 1", {})).toBe("scope['state'].val>1");
|
||||||
expect(compileExpr("a in b", {})).toBe("scope['a']in scope['b']");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("boolean operations", () => {
|
test("boolean operations", () => {
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* We can only make one test per file, since the debug tool modify in place
|
|
||||||
* the owl object in a way that is difficult to undo.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { debugOwl } from "../../tools/debug";
|
|
||||||
import * as owl from "../../src/index";
|
|
||||||
|
|
||||||
import { Component, Env } from "../../src/component/component";
|
|
||||||
import { xml } from "../../src/tags";
|
|
||||||
import { makeTestFixture, makeTestEnv } from "../helpers";
|
|
||||||
|
|
||||||
let fixture: HTMLElement = makeTestFixture();
|
|
||||||
let env: Env = makeTestEnv();
|
|
||||||
Component.env = env;
|
|
||||||
|
|
||||||
debugOwl(owl, { logScheduler: true });
|
|
||||||
|
|
||||||
test("log a sub component with non stringifiable props", async () => {
|
|
||||||
const steps: string[] = [];
|
|
||||||
const log = console.log;
|
|
||||||
console.log = arg => steps.push(arg);
|
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
|
||||||
static template = xml`<span><t t-esc="props.obj.val"/></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const circularObject: any = { val: 1 };
|
|
||||||
circularObject.circularObject = circularObject;
|
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
|
||||||
static template = xml`<div><Child obj="obj"/></div>`;
|
|
||||||
static components = { Child };
|
|
||||||
obj = circularObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = new Parent(null, {});
|
|
||||||
await parent.mount(fixture);
|
|
||||||
parent.unmount();
|
|
||||||
|
|
||||||
expect(steps).toEqual([
|
|
||||||
"[OWL_DEBUG] Parent<id=1> constructor, props={}",
|
|
||||||
"[OWL_DEBUG] Parent<id=1> mount",
|
|
||||||
"[OWL_DEBUG] Parent<id=1> willStart",
|
|
||||||
"[OWL_DEBUG] scheduler: start running tasks queue",
|
|
||||||
"[OWL_DEBUG] Parent<id=1> rendering template",
|
|
||||||
"[OWL_DEBUG] Child<id=2> constructor, props=<JSON error>",
|
|
||||||
"[OWL_DEBUG] Child<id=2> willStart",
|
|
||||||
"[OWL_DEBUG] Child<id=2> rendering template",
|
|
||||||
"[OWL_DEBUG] Child<id=2> mounted",
|
|
||||||
"[OWL_DEBUG] Parent<id=1> mounted",
|
|
||||||
"[OWL_DEBUG] scheduler: stop running tasks queue",
|
|
||||||
"[OWL_DEBUG] Parent<id=1> willUnmount",
|
|
||||||
"[OWL_DEBUG] Child<id=2> willUnmount"
|
|
||||||
]);
|
|
||||||
console.log = log;
|
|
||||||
});
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
import { buildData, startMeasure, stopMeasure, formatNumber } from "../shared/utils.js";
|
|
||||||
|
|
||||||
const { useState, useRef } = owl.hooks;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Likes Counter Widget
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
class Counter extends owl.Component {
|
|
||||||
state = useState({ counter: 0 });
|
|
||||||
|
|
||||||
increment() {
|
|
||||||
this.state.counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Message Widget
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
class Message extends owl.Component {
|
|
||||||
shouldUpdate(nextProps) {
|
|
||||||
return nextProps.message !== this.props.message;
|
|
||||||
}
|
|
||||||
removeMessage() {
|
|
||||||
this.trigger("remove-message", {
|
|
||||||
id: this.props.message.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message.components = { Counter };
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Root Widget
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
class App extends owl.Component {
|
|
||||||
state = useState({ messages: [], multipleFlag: false, clearAfterFlag: false });
|
|
||||||
logRef = useRef("log");
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.log(`Benchmarking Owl v${owl.__info__.version} (build date: ${owl.__info__.date})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
benchmark(message, fn, callback) {
|
|
||||||
if (this.state.multipleFlag) {
|
|
||||||
const N = 20;
|
|
||||||
let n = N;
|
|
||||||
let total = 0;
|
|
||||||
let cb = info => {
|
|
||||||
let finalize = () => {
|
|
||||||
n--;
|
|
||||||
total += info.delta;
|
|
||||||
if (n === 0) {
|
|
||||||
const avg = total / N;
|
|
||||||
this.log(`Average: ${formatNumber(avg)}ms`, true);
|
|
||||||
if (callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._benchmark(message, fn, cb);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.state.clearAfterFlag) {
|
|
||||||
this._benchmark(
|
|
||||||
"clear",
|
|
||||||
() => {
|
|
||||||
this.state.messages = [];
|
|
||||||
},
|
|
||||||
finalize,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
finalize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this._benchmark(message, fn, cb);
|
|
||||||
} else {
|
|
||||||
this._benchmark(message, fn, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_benchmark(message, fn, cb, log = true) {
|
|
||||||
setTimeout(() => {
|
|
||||||
startMeasure(message);
|
|
||||||
fn();
|
|
||||||
stopMeasure(info => {
|
|
||||||
if (log) {
|
|
||||||
this.log(info.msg);
|
|
||||||
}
|
|
||||||
if (cb) {
|
|
||||||
cb(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
addMessages(n) {
|
|
||||||
this.benchmark("add " + n, () => {
|
|
||||||
const newMessages = buildData(n);
|
|
||||||
this.state.messages.push.apply(this.state.messages, newMessages);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this._benchmark("clear", () => {
|
|
||||||
this.state.messages = [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSomeMessages() {
|
|
||||||
this.benchmark("update every 10th", () => {
|
|
||||||
const messages = this.state.messages;
|
|
||||||
for (let i = 0; i < messages.length; i += 10) {
|
|
||||||
const msg = Object.assign({}, messages[i]);
|
|
||||||
msg.author += "!!!";
|
|
||||||
messages[i] = msg;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
removeMessage(event) {
|
|
||||||
this.benchmark("remove message", () => {
|
|
||||||
const index = this.state.messages.findIndex(m => m.id === event.detail.id);
|
|
||||||
this.state.messages.splice(index, 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
log(str, isBold) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
if (isBold) {
|
|
||||||
div.classList.add("bold");
|
|
||||||
}
|
|
||||||
div.textContent = `> ${str}`;
|
|
||||||
this.logRef.el.appendChild(div);
|
|
||||||
this.logRef.el.scrollTop = this.logRef.el.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearLog() {
|
|
||||||
this.logRef.el.innerHTML = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
App.components = { Message };
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Application initialization
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
async function start() {
|
|
||||||
const templates = await owl.utils.loadFile("templates.xml");
|
|
||||||
App.env = {
|
|
||||||
qweb: new owl.QWeb({ templates })
|
|
||||||
};
|
|
||||||
const app = new App();
|
|
||||||
app.mount(document.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
start();
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>OWL v1.0.0 Benchmark</title>
|
|
||||||
<link href="../shared/main.css" rel="stylesheet"/>
|
|
||||||
<script src='owl.js'></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src='app.js' type="module"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
|||||||
<templates>
|
|
||||||
<div t-name="App" class="main">
|
|
||||||
<div class="left-thing">
|
|
||||||
<div class="title">Actions</div>
|
|
||||||
<div class="panel">
|
|
||||||
<button t-on-click="addMessages(100)">Add 100 messages</button>
|
|
||||||
<button t-on-click="addMessages(1000)">Add 1k messages</button>
|
|
||||||
<button t-on-click="addMessages(10000)">Add 10k messages</button>
|
|
||||||
<button t-on-click="addMessages(30000)">Add 30k messages</button>
|
|
||||||
<button t-on-click="updateSomeMessages">Update every 10th messages</button>
|
|
||||||
<button t-on-click="clear">Clear</button>
|
|
||||||
</div>
|
|
||||||
<div class="flags">
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" id="multipleflag" t-model="state.multipleFlag"/>
|
|
||||||
<label for="multipleflag">Do it 20x</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" id="clearFlag" t-model="state.clearAfterFlag" />
|
|
||||||
<label for="clearFlag">Clear after</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="info">Number of messages: <t t-esc="state.messages.length"/></div>
|
|
||||||
<hr/>
|
|
||||||
<div class="title">Log <span class="clear-log" t-on-click="clearLog">(clear)</span></div>
|
|
||||||
<div class="log">
|
|
||||||
<div class="log-content" t-ref="log"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="right-thing">
|
|
||||||
<div class="content" t-on-remove-message="removeMessage">
|
|
||||||
<t t-foreach="state.messages" t-as="message">
|
|
||||||
<Message t-key="message.id" message="message"/>
|
|
||||||
</t>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div t-name="Message" class="message">
|
|
||||||
<span class="author"><t t-esc="props.message.author"/></span>
|
|
||||||
<span class="msg"><t t-esc="props.message.msg"/></span>
|
|
||||||
<button class="remove" t-on-click="removeMessage">Remove</button>
|
|
||||||
<Counter/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div t-name="Counter">
|
|
||||||
<button t-on-click="increment">Value: <t t-esc="state.counter"/></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</templates>
|
|
||||||
+1
-6
@@ -35,12 +35,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function toStr(obj) {
|
function toStr(obj) {
|
||||||
let str;
|
let str = JSON.stringify(obj || {});
|
||||||
try {
|
|
||||||
str = JSON.stringify(obj || {});
|
|
||||||
} catch (e) {
|
|
||||||
str = "<JSON error>";
|
|
||||||
}
|
|
||||||
if (str.length > 200) {
|
if (str.length > 200) {
|
||||||
str = str.slice(0, 200) + "...";
|
str = str.slice(0, 200) + "...";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
<li><a href="benchmarks/owl-0.21.0">OWL 0.21.0</a></li>
|
<li><a href="benchmarks/owl-0.21.0">OWL 0.21.0</a></li>
|
||||||
<li><a href="benchmarks/owl-0.24.0">OWL 0.24.0</a></li>
|
<li><a href="benchmarks/owl-0.24.0">OWL 0.24.0</a></li>
|
||||||
<li><a href="benchmarks/owl-1.0.0-beta1">OWL 1.0.0-beta1</a></li>
|
<li><a href="benchmarks/owl-1.0.0-beta1">OWL 1.0.0-beta1</a></li>
|
||||||
<li><a href="benchmarks/owl-1.0.0">OWL 1.0.0</a></li>
|
|
||||||
<li><a href="benchmarks/owl-master">OWL Master</a></li>
|
<li><a href="benchmarks/owl-master">OWL Master</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ const actions = {
|
|||||||
todo.completed = !todo.completed;
|
todo.completed = !todo.completed;
|
||||||
},
|
},
|
||||||
clearCompleted({ state, dispatch }) {
|
clearCompleted({ state, dispatch }) {
|
||||||
for (let todo of state.todos.slice()) {
|
for (let todo of state.todos) {
|
||||||
if (todo.completed) {
|
if (todo.completed) {
|
||||||
dispatch("removeTodo", todo.id);
|
dispatch("removeTodo", todo.id);
|
||||||
}
|
}
|
||||||
@@ -1089,20 +1089,20 @@ const RESPONSIVE_XML = `<templates>
|
|||||||
<button>Button!</button>
|
<button>Button!</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<t t-name="maincontent">
|
|
||||||
<FormView />
|
|
||||||
<Chatter />
|
|
||||||
</t>
|
|
||||||
<div t-name="App" class="app" t-att-class="{mobile: env.isMobile, desktop: !env.isMobile}">
|
<div t-name="App" class="app" t-att-class="{mobile: env.isMobile, desktop: !env.isMobile}">
|
||||||
|
<t t-set="maincontent">
|
||||||
|
<FormView />
|
||||||
|
<Chatter />
|
||||||
|
</t>
|
||||||
<Navbar/>
|
<Navbar/>
|
||||||
<ControlPanel/>
|
<ControlPanel/>
|
||||||
<div class="content-wrapper" t-if="!env.isMobile">
|
<div class="content-wrapper" t-if="!env.isMobile">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<t t-call="maincontent"/>
|
<t t-raw="maincontent"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<t t-else="">
|
<t t-else="">
|
||||||
<t t-call="maincontent"/>
|
<t t-raw="maincontent"/>
|
||||||
</t>
|
</t>
|
||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
|
|||||||
+1
-2
@@ -13,8 +13,7 @@
|
|||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"strictPropertyInitialization": true,
|
"strictPropertyInitialization": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true
|
||||||
"declarationDir": "dist/types"
|
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts","src/*.ts"]
|
"include": ["src/**/*.ts","src/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user