mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] component: simplify constructor API
It now takes two arguments: parent (optional, only for non-root components) and props (optional). In the case of the root component, the env is taken from the config (config.defaultEnv). If it doesn't exists, the default env is created on the fly. Closes #306
This commit is contained in:
committed by
Géry Debongnie
parent
9f93da4765
commit
9106c19066
+12
-20
@@ -1,6 +1,7 @@
|
|||||||
import { Observer } from "../core/observer";
|
import { Observer } from "../core/observer";
|
||||||
import { CompiledTemplate, QWeb } from "../qweb/index";
|
import { CompiledTemplate, QWeb } from "../qweb/index";
|
||||||
import { h, patch, VNode } from "../vdom/index";
|
import { h, patch, VNode } from "../vdom/index";
|
||||||
|
import { config } from "../config";
|
||||||
import "./directive";
|
import "./directive";
|
||||||
import { Fiber } from "./fiber";
|
import { Fiber } from "./fiber";
|
||||||
import "./props_validation";
|
import "./props_validation";
|
||||||
@@ -106,25 +107,14 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
/**
|
/**
|
||||||
* Creates an instance of Component.
|
* Creates an instance of Component.
|
||||||
*
|
*
|
||||||
* The root component of a component tree needs an environment:
|
|
||||||
*
|
|
||||||
* ```javascript
|
|
||||||
* const root = new RootComponent(env, props);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Every other component simply needs a reference to its parent:
|
|
||||||
*
|
|
||||||
* ```javascript
|
|
||||||
* const child = new SomeComponent(parent, props);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Note that most of the time, only the root component needs to be created by
|
* Note that most of the time, only the root component needs to be created by
|
||||||
* hand. Other components should be created automatically by the framework (with
|
* hand. Other components should be created automatically by the framework (with
|
||||||
* the t-component directive in a template)
|
* the t-component directive in a template)
|
||||||
*/
|
*/
|
||||||
constructor(parent: Component<T, any> | T, props?: Props) {
|
constructor(parent?: Component<T, any>, props?: Props) {
|
||||||
const defaultProps = (<any>this.constructor).defaultProps;
|
|
||||||
Component.current = this;
|
Component.current = this;
|
||||||
|
|
||||||
|
const defaultProps = (<any>this.constructor).defaultProps;
|
||||||
if (defaultProps) {
|
if (defaultProps) {
|
||||||
props = this.__applyDefaultProps(props, defaultProps);
|
props = this.__applyDefaultProps(props, defaultProps);
|
||||||
}
|
}
|
||||||
@@ -136,17 +126,18 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
if (QWeb.dev) {
|
if (QWeb.dev) {
|
||||||
QWeb.utils.validateProps(this.constructor, this.props);
|
QWeb.utils.validateProps(this.constructor, this.props);
|
||||||
}
|
}
|
||||||
let id: number = nextId++;
|
|
||||||
|
const id: number = nextId++;
|
||||||
|
|
||||||
let depth;
|
let depth;
|
||||||
let p: Component<T, any> | null = null;
|
if (parent) {
|
||||||
if (parent instanceof Component) {
|
|
||||||
p = parent;
|
|
||||||
this.env = parent.env;
|
this.env = parent.env;
|
||||||
const __powl__ = parent.__owl__;
|
const __powl__ = parent.__owl__;
|
||||||
__powl__.children[id] = this;
|
__powl__.children[id] = this;
|
||||||
depth = __powl__.depth + 1;
|
depth = __powl__.depth + 1;
|
||||||
} else {
|
} else {
|
||||||
this.env = parent;
|
// we are the root component
|
||||||
|
this.env = config.env as T;
|
||||||
this.env.qweb.on("update", this, () => {
|
this.env.qweb.on("update", this, () => {
|
||||||
if (this.__owl__.isMounted) {
|
if (this.__owl__.isMounted) {
|
||||||
this.render(true);
|
this.render(true);
|
||||||
@@ -162,6 +153,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
});
|
});
|
||||||
depth = 0;
|
depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = this.env.qweb;
|
const qweb = this.env.qweb;
|
||||||
|
|
||||||
this.__owl__ = {
|
this.__owl__ = {
|
||||||
@@ -171,7 +163,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
pvnode: null,
|
pvnode: null,
|
||||||
isMounted: false,
|
isMounted: false,
|
||||||
isDestroyed: false,
|
isDestroyed: false,
|
||||||
parent: p,
|
parent: parent || null,
|
||||||
children: {},
|
children: {},
|
||||||
cmap: {},
|
cmap: {},
|
||||||
currentFiber: null,
|
currentFiber: null,
|
||||||
|
|||||||
+20
-3
@@ -1,17 +1,20 @@
|
|||||||
import { QWeb } from "./qweb/index";
|
import { QWeb } from "./qweb/index";
|
||||||
|
import { Env } from "./component/component";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file creates and exports the OWL 'config' object, with keys:
|
* This file creates and exports the OWL 'config' object, with keys:
|
||||||
* - 'mode': 'prod' or 'dev',
|
* - 'mode': 'prod' or 'dev',
|
||||||
|
* - 'env': the environment to use in root components.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
|
env: Env;
|
||||||
mode: string;
|
mode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _config:Partial<Config> = {};
|
export const config = {} as Config;
|
||||||
|
|
||||||
Object.defineProperty(_config, "mode", {
|
Object.defineProperty(config, "mode", {
|
||||||
get() {
|
get() {
|
||||||
return QWeb.dev ? "dev" : "prod";
|
return QWeb.dev ? "dev" : "prod";
|
||||||
},
|
},
|
||||||
@@ -28,4 +31,18 @@ Object.defineProperty(_config, "mode", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const config:Config = _config as Config;
|
let env:Env;
|
||||||
|
Object.defineProperty(config, "env", {
|
||||||
|
get() {
|
||||||
|
if (!env) {
|
||||||
|
env = {} as Env;
|
||||||
|
}
|
||||||
|
if (!env.qweb) {
|
||||||
|
env.qweb = new QWeb();
|
||||||
|
}
|
||||||
|
return env;
|
||||||
|
},
|
||||||
|
set(newEnv: Env) {
|
||||||
|
env = newEnv;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Component, Env } from "../src/component/component";
|
import { Component, Env } from "../src/component/component";
|
||||||
|
import { config } from "../src/config";
|
||||||
import { QWeb } from "../src/qweb/index";
|
import { QWeb } from "../src/qweb/index";
|
||||||
import { useState, useRef } from "../src/hooks";
|
import { useState, useRef } from "../src/hooks";
|
||||||
import {
|
import {
|
||||||
@@ -29,6 +30,7 @@ let cssEl: HTMLElement;
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
env = makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
qweb = new QWeb();
|
qweb = new QWeb();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ describe("animations", () => {
|
|||||||
class TestWidget extends Widget {
|
class TestWidget extends Widget {
|
||||||
state = useState({ hide: false });
|
state = useState({ hide: false });
|
||||||
}
|
}
|
||||||
const widget = new TestWidget(env);
|
const widget = new TestWidget();
|
||||||
|
|
||||||
// insert widget into the DOM
|
// insert widget into the DOM
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
@@ -151,7 +153,7 @@ describe("animations", () => {
|
|||||||
state = useState({ hide: false });
|
state = useState({ hide: false });
|
||||||
span = useRef("span");
|
span = useRef("span");
|
||||||
}
|
}
|
||||||
const widget = new TestWidget(env);
|
const widget = new TestWidget();
|
||||||
|
|
||||||
// insert widget into the DOM
|
// insert widget into the DOM
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
@@ -180,7 +182,7 @@ describe("animations", () => {
|
|||||||
class Parent extends Widget {
|
class Parent extends Widget {
|
||||||
static components = { Child: Child };
|
static components = { Child: Child };
|
||||||
}
|
}
|
||||||
const widget = new Parent(env);
|
const widget = new Parent();
|
||||||
|
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
var spanNode;
|
var spanNode;
|
||||||
@@ -220,7 +222,7 @@ describe("animations", () => {
|
|||||||
static components = { Child: Child };
|
static components = { Child: Child };
|
||||||
state = useState({ display: true });
|
state = useState({ display: true });
|
||||||
}
|
}
|
||||||
const widget = new Parent(env);
|
const widget = new Parent();
|
||||||
|
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
var spanNode;
|
var spanNode;
|
||||||
@@ -283,7 +285,7 @@ describe("animations", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const widget = new Parent(env);
|
const widget = new Parent();
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
let button = widget.el!.querySelector("button");
|
let button = widget.el!.querySelector("button");
|
||||||
|
|
||||||
@@ -341,7 +343,7 @@ describe("animations", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const widget = new Parent(env);
|
const widget = new Parent();
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
let button = widget.el!.querySelector("button");
|
let button = widget.el!.querySelector("button");
|
||||||
|
|
||||||
|
|||||||
+188
-185
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
import { Component, Env } from "../../src/component/component";
|
import { Component, Env } from "../../src/component/component";
|
||||||
import { makeTestFixture, makeTestEnv, nextTick } from "../helpers";
|
import { makeTestFixture, makeTestEnv, nextTick } from "../helpers";
|
||||||
import { useState } from "../../src/hooks";
|
import { useState } from "../../src/hooks";
|
||||||
|
import { config } from "../../src/config";
|
||||||
import { QWeb } from "../../src/qweb";
|
import { QWeb } from "../../src/qweb";
|
||||||
import { xml } from "../../src/tags";
|
import { xml } from "../../src/tags";
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ let dev: boolean = false;
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
env = makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
dev = QWeb.dev;
|
dev = QWeb.dev;
|
||||||
QWeb.dev = true;
|
QWeb.dev = true;
|
||||||
});
|
});
|
||||||
@@ -38,13 +40,13 @@ describe("props validation", () => {
|
|||||||
|
|
||||||
QWeb.dev = true;
|
QWeb.dev = true;
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env);
|
new TestWidget();
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
|
|
||||||
QWeb.dev = false;
|
QWeb.dev = false;
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env);
|
new TestWidget();
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -55,7 +57,7 @@ describe("props validation", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env);
|
new TestWidget();
|
||||||
}).toThrow("Missing props 'message' (component 'TestWidget')");
|
}).toThrow("Missing props 'message' (component 'TestWidget')");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,15 +78,15 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env);
|
new TestWidget();
|
||||||
}).toThrow("Missing props 'p'");
|
}).toThrow("Missing props 'p'");
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: test.ok });
|
new TestWidget(undefined, { p: test.ok });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: test.ko });
|
new TestWidget(undefined, { p: test.ko });
|
||||||
}).toThrow("Props 'p' of invalid type in component");
|
}).toThrow("Props 'p' of invalid type in component");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -106,15 +108,15 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env);
|
new TestWidget();
|
||||||
}).toThrow("Missing props 'p'");
|
}).toThrow("Missing props 'p'");
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: test.ok });
|
new TestWidget(undefined, { p: test.ok });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: test.ko });
|
new TestWidget(undefined, { p: test.ko });
|
||||||
}).toThrow("Props 'p' of invalid type in component");
|
}).toThrow("Props 'p' of invalid type in component");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -126,12 +128,12 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: "string" });
|
new TestWidget(undefined, { p: "string" });
|
||||||
new TestWidget(env, { p: true });
|
new TestWidget(undefined, { p: true });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: 1 });
|
new TestWidget(undefined, { p: 1 });
|
||||||
}).toThrow("Props 'p' of invalid type in component");
|
}).toThrow("Props 'p' of invalid type in component");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -142,12 +144,12 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: "hey" });
|
new TestWidget(undefined, { p: "hey" });
|
||||||
new TestWidget(env, {});
|
new TestWidget(undefined, {});
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: 1 });
|
new TestWidget(undefined, { p: 1 });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -158,16 +160,16 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: [] });
|
new TestWidget(undefined, { p: [] });
|
||||||
new TestWidget(env, { p: ["string"] });
|
new TestWidget(undefined, { p: ["string"] });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: [1] });
|
new TestWidget(undefined, { p: [1] });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: ["string", 1] });
|
new TestWidget(undefined, { p: ["string", 1] });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -178,13 +180,13 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: [] });
|
new TestWidget(undefined, { p: [] });
|
||||||
new TestWidget(env, { p: ["string"] });
|
new TestWidget(undefined, { p: ["string"] });
|
||||||
new TestWidget(env, { p: [false, true, "string"] });
|
new TestWidget(undefined, { p: [false, true, "string"] });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: [true, 1] });
|
new TestWidget(undefined, { p: [true, 1] });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -197,16 +199,16 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: { id: 1, url: "url" } });
|
new TestWidget(undefined, { p: { id: 1, url: "url" } });
|
||||||
new TestWidget(env, { p: { id: 1, url: "url", extra: true } });
|
new TestWidget(undefined, { p: { id: 1, url: "url", extra: true } });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: { id: "1", url: "url" } });
|
new TestWidget(undefined, { p: { id: "1", url: "url" } });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: { id: 1 } });
|
new TestWidget(undefined, { p: { id: 1 } });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -225,12 +227,12 @@ describe("props validation", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: { id: 1, url: true } });
|
new TestWidget(undefined, { p: { id: 1, url: true } });
|
||||||
new TestWidget(env, { p: { id: 1, url: [12] } });
|
new TestWidget(undefined, { p: { id: 1, url: [12] } });
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
new TestWidget(env, { p: { id: 1, url: [12, true] } });
|
new TestWidget(undefined, { p: { id: 1, url: [12, true] } });
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -249,7 +251,7 @@ describe("props validation", () => {
|
|||||||
class App extends Widget {
|
class App extends Widget {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
||||||
// need to make sure there are 2 call to update props. one at component
|
// need to make sure there are 2 call to update props. one at component
|
||||||
@@ -334,7 +336,7 @@ describe("props validation", () => {
|
|||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new App(env, {});
|
const w = new App(undefined, {});
|
||||||
let error;
|
let error;
|
||||||
try {
|
try {
|
||||||
await w.mount(fixture);
|
await w.mount(fixture);
|
||||||
@@ -365,7 +367,7 @@ describe("props validation", () => {
|
|||||||
state: any = useState({ p: 1 });
|
state: any = useState({ p: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new Parent(env);
|
const w = new Parent();
|
||||||
await w.mount(fixture);
|
await w.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
||||||
|
|
||||||
@@ -387,7 +389,7 @@ describe("props validation", () => {
|
|||||||
state: any = useState({ p: 1 });
|
state: any = useState({ p: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new Parent(env);
|
const w = new Parent();
|
||||||
await w.mount(fixture);
|
await w.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
||||||
|
|
||||||
@@ -404,7 +406,7 @@ describe("default props", () => {
|
|||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new TestWidget(env, {});
|
const w = new TestWidget(undefined, {});
|
||||||
expect(w.props.p).toBe(4);
|
expect(w.props.p).toBe(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -419,7 +421,7 @@ describe("default props", () => {
|
|||||||
state: any = useState({ p: 1 });
|
state: any = useState({ p: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new Parent(env);
|
const w = new Parent();
|
||||||
await w.mount(fixture);
|
await w.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
|
||||||
|
|
||||||
@@ -440,7 +442,7 @@ describe("default props", () => {
|
|||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = new App(env, {});
|
const w = new App(undefined, {});
|
||||||
await w.mount(fixture);
|
await w.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>heyhey</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>heyhey</span></div>");
|
||||||
});
|
});
|
||||||
|
|||||||
+13
-13
@@ -1,6 +1,7 @@
|
|||||||
import { makeDeferred, makeTestEnv, makeTestFixture, nextTick } from "./helpers";
|
import { makeDeferred, makeTestEnv, makeTestFixture, nextTick } from "./helpers";
|
||||||
import { Component, Env } from "../src/component/component";
|
import { Component } from "../src/component/component";
|
||||||
import { Context, useContext } from "../src/context";
|
import { Context, useContext } from "../src/context";
|
||||||
|
import { config } from "../src/config";
|
||||||
import { xml } from "../src/tags";
|
import { xml } from "../src/tags";
|
||||||
import { useState } from "../src/hooks";
|
import { useState } from "../src/hooks";
|
||||||
|
|
||||||
@@ -11,14 +12,13 @@ import { useState } from "../src/hooks";
|
|||||||
// We create before each test:
|
// We create before each test:
|
||||||
// - fixture: a div, appended to the DOM, intended to be the target of dom
|
// - fixture: a div, appended to the DOM, intended to be the target of dom
|
||||||
// manipulations. Note that it is removed after each test.
|
// manipulations. Note that it is removed after each test.
|
||||||
// - env: a WEnv, necessary to create new components
|
// - a test env, necessary to create components, that is set as env
|
||||||
|
|
||||||
let fixture: HTMLElement;
|
let fixture: HTMLElement;
|
||||||
let env: Env;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
config.env = makeTestEnv();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -37,7 +37,7 @@ describe("Context", () => {
|
|||||||
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
}
|
}
|
||||||
const test = new Test(env);
|
const test = new Test();
|
||||||
await test.mount(fixture);
|
await test.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>123</div>");
|
expect(fixture.innerHTML).toBe("<div>123</div>");
|
||||||
});
|
});
|
||||||
@@ -49,7 +49,7 @@ describe("Context", () => {
|
|||||||
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
}
|
}
|
||||||
const test = new Test(env);
|
const test = new Test();
|
||||||
await test.mount(fixture);
|
await test.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>123</div>");
|
expect(fixture.innerHTML).toBe("<div>123</div>");
|
||||||
test.contextObj.value = 321;
|
test.contextObj.value = 321;
|
||||||
@@ -68,7 +68,7 @@ describe("Context", () => {
|
|||||||
static template = xml`<div><Child /><Child /></div>`;
|
static template = xml`<div><Child /><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
|
||||||
testContext.state.value = 321;
|
testContext.state.value = 321;
|
||||||
@@ -95,7 +95,7 @@ describe("Context", () => {
|
|||||||
static template = xml`<div><Child /><Child /></div>`;
|
static template = xml`<div><Child /><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
|
||||||
testContext.state.value = 321;
|
testContext.state.value = 321;
|
||||||
@@ -139,7 +139,7 @@ describe("Context", () => {
|
|||||||
static components = { Child, Parent };
|
static components = { Child, Parent };
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe(
|
expect(fixture.innerHTML).toBe(
|
||||||
"<div><span><p>123</p></span><div><span><p>123</p></span><span><p>123</p></span></div></div>"
|
"<div><span><p>123</p></span><div><span><p>123</p></span><span><p>123</p></span></div></div>"
|
||||||
@@ -175,7 +175,7 @@ describe("Context", () => {
|
|||||||
static template = xml`<div><Child /></div>`;
|
static template = xml`<div><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>12</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>12</span></div>");
|
||||||
expect(steps).toEqual(["child"]);
|
expect(steps).toEqual(["child"]);
|
||||||
@@ -206,7 +206,7 @@ describe("Context", () => {
|
|||||||
return super.__render(fiber);
|
return super.__render(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>123</span>321</div>");
|
expect(fixture.innerHTML).toBe("<div><span>123</span>321</div>");
|
||||||
expect(steps).toEqual(["parent", "child"]);
|
expect(steps).toEqual(["parent", "child"]);
|
||||||
@@ -240,7 +240,7 @@ describe("Context", () => {
|
|||||||
return super.__render(fiber);
|
return super.__render(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>123</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>123</span></div>");
|
||||||
expect(steps).toEqual(["parent", "child"]);
|
expect(steps).toEqual(["parent", "child"]);
|
||||||
@@ -284,7 +284,7 @@ describe("Context", () => {
|
|||||||
context = useContext(testContext);
|
context = useContext(testContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = new ComponentA(env);
|
const component = new ComponentA();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p><span>1a</span></p></div>");
|
expect(fixture.innerHTML).toBe("<div><p><span>1a</span></p></div>");
|
||||||
|
|||||||
+44
-42
@@ -1,5 +1,6 @@
|
|||||||
import { makeTestEnv, makeTestFixture, nextTick } from "./helpers";
|
import { makeTestEnv, makeTestFixture, nextTick } from "./helpers";
|
||||||
import { Component, Env } from "../src/component/component";
|
import { Component, Env } from "../src/component/component";
|
||||||
|
import { config } from "../src/config";
|
||||||
import {
|
import {
|
||||||
useState,
|
useState,
|
||||||
onMounted,
|
onMounted,
|
||||||
@@ -28,6 +29,7 @@ let env: Env;
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
env = makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -44,7 +46,7 @@ describe("hooks", () => {
|
|||||||
static template = xml`<div><t t-esc="counter.value"/></div>`;
|
static template = xml`<div><t t-esc="counter.value"/></div>`;
|
||||||
counter = useState({ value: 42 });
|
counter = useState({ value: 42 });
|
||||||
}
|
}
|
||||||
const counter = new Counter(env);
|
const counter = new Counter();
|
||||||
await counter.mount(fixture);
|
await counter.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>42</div>");
|
expect(fixture.innerHTML).toBe("<div>42</div>");
|
||||||
counter.counter.value = 3;
|
counter.counter.value = 3;
|
||||||
@@ -64,12 +66,12 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(component).not.toHaveProperty("mounted");
|
expect(component).not.toHaveProperty("mounted");
|
||||||
expect(component).not.toHaveProperty("willUnmount");
|
expect(component).not.toHaveProperty("willUnmount");
|
||||||
@@ -92,8 +94,8 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(env) {
|
constructor(parent, props) {
|
||||||
super(env);
|
super(parent, props);
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +105,7 @@ describe("hooks", () => {
|
|||||||
static components = { MyComponent };
|
static components = { MyComponent };
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
}
|
}
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
||||||
expect(steps).toEqual(["mounted"]);
|
expect(steps).toEqual(["mounted"]);
|
||||||
@@ -126,8 +128,8 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -137,7 +139,7 @@ describe("hooks", () => {
|
|||||||
steps.push("comp:willunmount");
|
steps.push("comp:willunmount");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
||||||
component.unmount();
|
component.unmount();
|
||||||
@@ -157,8 +159,8 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(env) {
|
constructor(parent, props) {
|
||||||
super(env);
|
super(parent, props);
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -175,7 +177,7 @@ describe("hooks", () => {
|
|||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
expect(fixture.innerHTML).toBe("<div><div>hey</div></div>");
|
||||||
parent.state.flag = false;
|
parent.state.flag = false;
|
||||||
@@ -197,13 +199,13 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook(1);
|
useMyHook(1);
|
||||||
useMyHook(2);
|
useMyHook(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
||||||
component.unmount();
|
component.unmount();
|
||||||
@@ -226,7 +228,7 @@ describe("hooks", () => {
|
|||||||
(this.button.el as HTMLButtonElement).innerHTML = String(this.value);
|
(this.button.el as HTMLButtonElement).innerHTML = String(this.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const counter = new Counter(env);
|
const counter = new Counter();
|
||||||
await counter.mount(fixture);
|
await counter.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><button>0</button></div>");
|
expect(fixture.innerHTML).toBe("<div><button>0</button></div>");
|
||||||
counter.increment();
|
counter.increment();
|
||||||
@@ -247,7 +249,7 @@ describe("hooks", () => {
|
|||||||
expect(this.spanRef.el).toBeNull();
|
expect(this.spanRef.el).toBeNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new TestRef(env);
|
const component = new TestRef();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>owl</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>owl</span></div>");
|
||||||
component.state.flag = false;
|
component.state.flag = false;
|
||||||
@@ -270,13 +272,13 @@ describe("hooks", () => {
|
|||||||
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
|
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(component).not.toHaveProperty("patched");
|
expect(component).not.toHaveProperty("patched");
|
||||||
expect(component).not.toHaveProperty("willPatch");
|
expect(component).not.toHaveProperty("willPatch");
|
||||||
@@ -304,8 +306,8 @@ describe("hooks", () => {
|
|||||||
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
|
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
willPatch() {
|
willPatch() {
|
||||||
@@ -315,7 +317,7 @@ describe("hooks", () => {
|
|||||||
steps.push("comp:patched");
|
steps.push("comp:patched");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
||||||
component.state.flag = false;
|
component.state.flag = false;
|
||||||
@@ -337,13 +339,13 @@ describe("hooks", () => {
|
|||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component<any, any> {
|
||||||
static template = xml`<div>hey<t t-esc="state.value"/></div>`;
|
static template = xml`<div>hey<t t-esc="state.value"/></div>`;
|
||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useMyHook(1);
|
useMyHook(1);
|
||||||
useMyHook(2);
|
useMyHook(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new MyComponent(env);
|
const component = new MyComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>hey1</div>");
|
expect(fixture.innerHTML).toBe("<div>hey1</div>");
|
||||||
component.state.value++;
|
component.state.value++;
|
||||||
@@ -377,13 +379,13 @@ describe("hooks", () => {
|
|||||||
<input t-ref="input2"/>
|
<input t-ref="input2"/>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useAutofocus("input2");
|
useAutofocus("input2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = new SomeComponent(env);
|
const component = new SomeComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><input><input></div>");
|
expect(fixture.innerHTML).toBe("<div><input><input></div>");
|
||||||
const input2 = fixture.querySelectorAll("input")[1];
|
const input2 = fixture.querySelectorAll("input")[1];
|
||||||
@@ -399,13 +401,13 @@ describe("hooks", () => {
|
|||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
state = useState({ flag: false });
|
state = useState({ flag: false });
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useAutofocus("input2");
|
useAutofocus("input2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = new SomeComponent(env);
|
const component = new SomeComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><input></div>");
|
expect(fixture.innerHTML).toBe("<div><input></div>");
|
||||||
expect(document.activeElement).toBe(document.body);
|
expect(document.activeElement).toBe(document.body);
|
||||||
@@ -420,12 +422,12 @@ describe("hooks", () => {
|
|||||||
test("can use sub env", async () => {
|
test("can use sub env", async () => {
|
||||||
class TestComponent extends Component<any, any> {
|
class TestComponent extends Component<any, any> {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useSubEnv({ val: 3 });
|
useSubEnv({ val: 3 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new TestComponent(env);
|
const component = new TestComponent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>3</div>");
|
expect(fixture.innerHTML).toBe("<div>3</div>");
|
||||||
expect(env).not.toHaveProperty("val");
|
expect(env).not.toHaveProperty("val");
|
||||||
@@ -435,8 +437,8 @@ describe("hooks", () => {
|
|||||||
test("parent and child env", async () => {
|
test("parent and child env", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component<any, any> {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
constructor(env) {
|
constructor(parent, props) {
|
||||||
super(env);
|
super(parent, props);
|
||||||
useSubEnv({ val: 5 });
|
useSubEnv({ val: 5 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,12 +446,12 @@ describe("hooks", () => {
|
|||||||
class Parent extends Component<any, any> {
|
class Parent extends Component<any, any> {
|
||||||
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
constructor(env) {
|
constructor() {
|
||||||
super(env);
|
super();
|
||||||
useSubEnv({ val: 3 });
|
useSubEnv({ val: 3 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = new Parent(env);
|
const component = new Parent();
|
||||||
await component.mount(fixture);
|
await component.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>3<div>5</div></div>");
|
expect(fixture.innerHTML).toBe("<div>3<div>5</div></div>");
|
||||||
});
|
});
|
||||||
@@ -478,7 +480,7 @@ describe("hooks", () => {
|
|||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(app).not.toHaveProperty("willStart");
|
expect(app).not.toHaveProperty("willStart");
|
||||||
expect(app).not.toHaveProperty("willUpdateProps");
|
expect(app).not.toHaveProperty("willUpdateProps");
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { AsyncRoot } from "../../src/misc/async_root";
|
import { AsyncRoot } from "../../src/misc/async_root";
|
||||||
|
import { config } from "../../src/config";
|
||||||
import { useState } from "../../src/hooks";
|
import { useState } from "../../src/hooks";
|
||||||
import { xml } from "../../src/tags";
|
import { xml } from "../../src/tags";
|
||||||
import { makeDeferred, makeTestFixture, makeTestEnv, nextTick } from "../helpers";
|
import { makeDeferred, makeTestFixture, makeTestEnv, nextTick } from "../helpers";
|
||||||
import { Env, Component } from "../../src/component/component";
|
import { Component } from "../../src/component/component";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Setup and helpers
|
// Setup and helpers
|
||||||
@@ -11,14 +12,13 @@ import { Env, Component } from "../../src/component/component";
|
|||||||
// We create before each test:
|
// We create before each test:
|
||||||
// - fixture: a div, appended to the DOM, intended to be the target of dom
|
// - fixture: a div, appended to the DOM, intended to be the target of dom
|
||||||
// manipulations. Note that it is removed after each test.
|
// manipulations. Note that it is removed after each test.
|
||||||
// - env: a WEnv, necessary to create new components
|
// - a test env, necessary to create components, that is set as env
|
||||||
|
|
||||||
let fixture: HTMLElement;
|
let fixture: HTMLElement;
|
||||||
let env: Env;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
config.env = makeTestEnv();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -55,7 +55,7 @@ describe("Asyncroot", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
|
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
|
||||||
@@ -103,7 +103,7 @@ describe("Asyncroot", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
|
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
|
||||||
@@ -158,7 +158,7 @@ describe("Asyncroot", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0/0</span><span>0/0</span>");
|
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0/0</span><span>0/0</span>");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Component } from "../../src/component/component";
|
import { Component } from "../../src/component/component";
|
||||||
|
import { config } from "../../src/config";
|
||||||
import { Link } from "../../src/router/link";
|
import { Link } from "../../src/router/link";
|
||||||
import { RouterEnv } from "../../src/router/router";
|
import { RouterEnv } from "../../src/router/router";
|
||||||
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
||||||
@@ -12,6 +13,7 @@ describe("Link component", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = <RouterEnv>makeTestEnv();
|
env = <RouterEnv>makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -38,7 +40,7 @@ describe("Link component", () => {
|
|||||||
|
|
||||||
router = new TestRouter(env, routes, { mode: "history" });
|
router = new TestRouter(env, routes, { mode: "history" });
|
||||||
router.navigate({ to: "users" });
|
router.navigate({ to: "users" });
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe('<div><a href="/about">About</a></div>');
|
expect(fixture.innerHTML).toBe('<div><a href="/about">About</a></div>');
|
||||||
|
|
||||||
@@ -69,7 +71,7 @@ describe("Link component", () => {
|
|||||||
|
|
||||||
router = new TestRouter(env, routes, { mode: "history" });
|
router = new TestRouter(env, routes, { mode: "history" });
|
||||||
router.navigate({ to: "users" });
|
router.navigate({ to: "users" });
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
|
|
||||||
expect(window.location.pathname).toBe("/users");
|
expect(window.location.pathname).toBe("/users");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Component } from "../../src/component/component";
|
import { Component } from "../../src/component/component";
|
||||||
|
import { config } from "../../src/config";
|
||||||
import { RouterEnv } from "../../src/router/router";
|
import { RouterEnv } from "../../src/router/router";
|
||||||
import { RouteComponent } from "../../src/router/route_component";
|
import { RouteComponent } from "../../src/router/route_component";
|
||||||
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
|
||||||
@@ -12,6 +13,7 @@ describe("RouteComponent", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = <RouterEnv>makeTestEnv();
|
env = <RouterEnv>makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -45,7 +47,7 @@ describe("RouteComponent", () => {
|
|||||||
|
|
||||||
router = new TestRouter(env, routes, { mode: "history" });
|
router = new TestRouter(env, routes, { mode: "history" });
|
||||||
await router.navigate({ to: "about" });
|
await router.navigate({ to: "about" });
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>About</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>About</span></div>");
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ describe("RouteComponent", () => {
|
|||||||
const routes = [{ name: "book", path: "/book/{{title}}", component: Book }];
|
const routes = [{ name: "book", path: "/book/{{title}}", component: Book }];
|
||||||
router = new TestRouter(env, routes, { mode: "history" });
|
router = new TestRouter(env, routes, { mode: "history" });
|
||||||
await router.navigate({ to: "book", params: { title: "1984" } });
|
await router.navigate({ to: "book", params: { title: "1984" } });
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>Book 1984</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>Book 1984</span></div>");
|
||||||
});
|
});
|
||||||
@@ -98,7 +100,7 @@ describe("RouteComponent", () => {
|
|||||||
const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }];
|
const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }];
|
||||||
router = new TestRouter(env, routes, { mode: "history" });
|
router = new TestRouter(env, routes, { mode: "history" });
|
||||||
await router.navigate({ to: "book", params: { title: "1984", val: "123" } });
|
await router.navigate({ to: "book", params: { title: "1984", val: "123" } });
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>Book 1984|124</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>Book 1984|124</span></div>");
|
||||||
});
|
});
|
||||||
|
|||||||
+26
-22
@@ -1,4 +1,5 @@
|
|||||||
import { Component, Env } from "../src/component/component";
|
import { Component, Env } from "../src/component/component";
|
||||||
|
import { config } from "../src/config";
|
||||||
import { Store, useStore, useDispatch, useGetters } from "../src/store";
|
import { Store, useStore, useDispatch, useGetters } from "../src/store";
|
||||||
import { useState } from "../src/hooks";
|
import { useState } from "../src/hooks";
|
||||||
import { xml } from "../src/tags";
|
import { xml } from "../src/tags";
|
||||||
@@ -12,6 +13,7 @@ describe("connecting a component to store", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
env = makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -37,7 +39,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div></div>");
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
@@ -69,7 +71,7 @@ describe("connecting a component to store", () => {
|
|||||||
App.prototype.__render = jest.fn(App.prototype.__render);
|
App.prototype.__render = jest.fn(App.prototype.__render);
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>1</span><span>2</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>1</span><span>2</span></div>");
|
||||||
@@ -101,7 +103,7 @@ describe("connecting a component to store", () => {
|
|||||||
App.prototype.__render = jest.fn(App.prototype.__render);
|
App.prototype.__render = jest.fn(App.prototype.__render);
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div></div>");
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
@@ -134,7 +136,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>0</div>");
|
expect(fixture.innerHTML).toBe("<div>0</div>");
|
||||||
@@ -163,7 +165,7 @@ describe("connecting a component to store", () => {
|
|||||||
App.prototype.__render = jest.fn(App.prototype.__render);
|
App.prototype.__render = jest.fn(App.prototype.__render);
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>0</div>");
|
expect(fixture.innerHTML).toBe("<div>0</div>");
|
||||||
@@ -198,7 +200,7 @@ describe("connecting a component to store", () => {
|
|||||||
todos = useStore(state => state.todos, { store });
|
todos = useStore(state => state.todos, { store });
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div></div>");
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
@@ -228,7 +230,7 @@ describe("connecting a component to store", () => {
|
|||||||
storeState = useStore(state => state);
|
storeState = useStore(state => state);
|
||||||
dispatch = useDispatch();
|
dispatch = useDispatch();
|
||||||
}
|
}
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><button>Inc</button><span>1</span></div>");
|
expect(fixture.innerHTML).toBe("<div><button>Inc</button><span>1</span></div>");
|
||||||
@@ -257,7 +259,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
||||||
@@ -294,7 +296,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new TodoList(env);
|
const app = new TodoList();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
||||||
@@ -347,7 +349,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new TodoList(env);
|
const app = new TodoList();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe(
|
expect(fixture.innerHTML).toBe(
|
||||||
@@ -370,7 +372,7 @@ describe("connecting a component to store", () => {
|
|||||||
const state = { beers: { 1: { name: "jupiler" }, 2: { name: "kwak" } } };
|
const state = { beers: { 1: { name: "jupiler" }, 2: { name: "kwak" } } };
|
||||||
const store = new Store({ state });
|
const store = new Store({ state });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
||||||
@@ -401,7 +403,7 @@ describe("connecting a component to store", () => {
|
|||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
||||||
@@ -446,7 +448,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div><span>taster:aaron</span></div></div>");
|
expect(fixture.innerHTML).toBe("<div><div><span>taster:aaron</span></div></div>");
|
||||||
@@ -513,7 +515,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div><span>taster:aaron</span></div></div>");
|
expect(fixture.innerHTML).toBe("<div><div><span>taster:aaron</span></div></div>");
|
||||||
@@ -588,7 +590,7 @@ describe("connecting a component to store", () => {
|
|||||||
|
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new Parent(env);
|
const app = new Parent();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>a</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>a</span></div>");
|
||||||
@@ -639,7 +641,7 @@ describe("connecting a component to store", () => {
|
|||||||
|
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new Parent(env);
|
const app = new Parent();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><span>abc</span></div>");
|
expect(fixture.innerHTML).toBe("<div><span>abc</span></div>");
|
||||||
@@ -713,7 +715,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new TodoApp(env);
|
const app = new TodoApp();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe(
|
expect(fixture.innerHTML).toBe(
|
||||||
@@ -787,7 +789,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new TodoApp(env);
|
const app = new TodoApp();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe(
|
expect(fixture.innerHTML).toBe(
|
||||||
@@ -833,7 +835,7 @@ describe("connecting a component to store", () => {
|
|||||||
|
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>a</div>");
|
expect(fixture.innerHTML).toBe("<div>a</div>");
|
||||||
@@ -870,7 +872,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
const store = new TestStore({ state: { val: 1 } });
|
const store = new TestStore({ state: { val: 1 } });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const parent = new Parent(env);
|
const parent = new Parent();
|
||||||
|
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(steps).toEqual(["on:update"]);
|
expect(steps).toEqual(["on:update"]);
|
||||||
@@ -901,7 +903,7 @@ describe("connecting a component to store", () => {
|
|||||||
|
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
|
|
||||||
await app.mount(fixture);
|
await app.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>0</div>");
|
expect(fixture.innerHTML).toBe("<div>0</div>");
|
||||||
@@ -920,6 +922,7 @@ describe("various scenarios", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
env = makeTestEnv();
|
env = makeTestEnv();
|
||||||
|
config.env = env;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -978,7 +981,8 @@ describe("various scenarios", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
const message = new Message(env);
|
const message = new Message();
|
||||||
|
|
||||||
await message.mount(fixture);
|
await message.mount(fixture);
|
||||||
|
|
||||||
expect(fixture.innerHTML).toMatchSnapshot();
|
expect(fixture.innerHTML).toMatchSnapshot();
|
||||||
|
|||||||
@@ -145,10 +145,10 @@ class App extends owl.Component {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
async function start() {
|
async function start() {
|
||||||
const templates = await owl.utils.loadFile("templates.xml");
|
const templates = await owl.utils.loadFile("templates.xml");
|
||||||
const env = {
|
owl.config.env = {
|
||||||
qweb: new owl.QWeb({ templates })
|
qweb: new owl.QWeb({ templates })
|
||||||
};
|
};
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -90,7 +90,14 @@ function makeCodeIframe(js, css, xml, errorHandler) {
|
|||||||
owlScript.addEventListener("load", () => {
|
owlScript.addEventListener("load", () => {
|
||||||
const script = doc.createElement("script");
|
const script = doc.createElement("script");
|
||||||
script.type = "text/javascript";
|
script.type = "text/javascript";
|
||||||
const content = `owl.__info__.mode = 'dev';\nwindow.TEMPLATES = \`${sanitizedXML}\`;\n${js}`;
|
const content = `
|
||||||
|
{
|
||||||
|
owl.__info__.mode = 'dev';
|
||||||
|
let templates = \`${sanitizedXML}\`;
|
||||||
|
const qweb = new owl.QWeb({ templates });
|
||||||
|
owl.config.env = { qweb };
|
||||||
|
}
|
||||||
|
${js}`;
|
||||||
script.innerHTML = content;
|
script.innerHTML = content;
|
||||||
iframe.contentWindow.addEventListener("error", errorHandler);
|
iframe.contentWindow.addEventListener("error", errorHandler);
|
||||||
iframe.contentWindow.addEventListener("unhandledrejection", errorHandler);
|
iframe.contentWindow.addEventListener("unhandledrejection", errorHandler);
|
||||||
@@ -436,7 +443,9 @@ async function start() {
|
|||||||
owl.utils.whenReady()
|
owl.utils.whenReady()
|
||||||
]);
|
]);
|
||||||
const qweb = new owl.QWeb({ templates });
|
const qweb = new owl.QWeb({ templates });
|
||||||
const app = new App({ qweb });
|
debugger;
|
||||||
|
owl.config.env = { qweb };
|
||||||
|
const app = new App();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-42
@@ -16,9 +16,7 @@ class App extends Component {
|
|||||||
App.components = { Greeter };
|
App.components = { Greeter };
|
||||||
|
|
||||||
// Application setup
|
// Application setup
|
||||||
// Note that the xml templates are injected into the global TEMPLATES variable.
|
const app = new App();
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
|
||||||
const app = new App({ qweb });
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -70,8 +68,7 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
App.components = { Counter };
|
App.components = { Counter };
|
||||||
|
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const app = new App();
|
||||||
const app = new App({qweb});
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -228,8 +225,7 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
App.components = { DemoComponent };
|
App.components = { DemoComponent };
|
||||||
|
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const app = new App();
|
||||||
const app = new App({ qweb });
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -298,8 +294,7 @@ class App extends owl.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Application setup
|
// Application setup
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const app = new App();
|
||||||
const app = new App({ qweb });
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -349,11 +344,9 @@ const themeContext = new Context({
|
|||||||
background: '#000',
|
background: '#000',
|
||||||
foreground: '#fff',
|
foreground: '#fff',
|
||||||
});
|
});
|
||||||
const env = {
|
// Add the themeContext the environment to make it available to all components
|
||||||
qweb: new owl.QWeb({ templates: TEMPLATES}),
|
owl.config.env.themeContext = themeContext;
|
||||||
themeContext: themeContext,
|
const app = new App();
|
||||||
};
|
|
||||||
const app = new App(env);
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -534,26 +527,25 @@ TodoApp.components = { TodoItem };
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// App Initialization
|
// App Initialization
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function saveState(state) {
|
|
||||||
const str = JSON.stringify(state);
|
|
||||||
window.localStorage.setItem(LOCALSTORAGE_KEY, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadState() {
|
function makeStore() {
|
||||||
const localState = window.localStorage.getItem(LOCALSTORAGE_KEY);
|
function saveState(state) {
|
||||||
return localState ? JSON.parse(localState) : initialState;
|
const str = JSON.stringify(state);
|
||||||
}
|
window.localStorage.setItem(LOCALSTORAGE_KEY, str);
|
||||||
|
}
|
||||||
|
function loadState() {
|
||||||
|
const localState = window.localStorage.getItem(LOCALSTORAGE_KEY);
|
||||||
|
return localState ? JSON.parse(localState) : initialState;
|
||||||
|
}
|
||||||
|
|
||||||
function makeEnv() {
|
|
||||||
const state = loadState();
|
const state = loadState();
|
||||||
const store = new owl.Store({ state, actions });
|
const store = new owl.Store({ state, actions });
|
||||||
store.on("update", null, () => saveState(store.state));
|
store.on("update", null, () => saveState(store.state));
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
return store;
|
||||||
return { qweb, store };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const env = makeEnv();
|
owl.config.env.store = makeStore();
|
||||||
const app = new TodoApp(env);
|
const app = new TodoApp();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -1040,12 +1032,9 @@ function setupResponsivePlugin(env) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Application Startup
|
// Application Startup
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
const env = {
|
setupResponsivePlugin(owl.config.env);
|
||||||
qweb: new owl.QWeb({ templates: TEMPLATES}),
|
|
||||||
};
|
|
||||||
setupResponsivePlugin(env);
|
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -1187,8 +1176,7 @@ class App extends Component {
|
|||||||
App.components = {Card, Counter};
|
App.components = {Card, Counter};
|
||||||
|
|
||||||
// Application setup
|
// Application setup
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const app = new App();
|
||||||
const app = new App({ qweb });
|
|
||||||
app.mount(document.body);`;
|
app.mount(document.body);`;
|
||||||
|
|
||||||
const SLOTS_XML = `<templates>
|
const SLOTS_XML = `<templates>
|
||||||
@@ -1301,10 +1289,9 @@ class App extends Component {
|
|||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
App.components = {SlowComponent, NotificationList};
|
App.components = {SlowComponent, NotificationList, AsyncRoot};
|
||||||
|
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const app = new App();
|
||||||
const app = new App({ qweb });
|
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -1373,8 +1360,7 @@ class Form extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Application setup
|
// Application setup
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
const form = new Form();
|
||||||
const form = new Form({ qweb });
|
|
||||||
form.mount(document.body);
|
form.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -1540,7 +1526,6 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
App.components = { WindowManager };
|
App.components = { WindowManager };
|
||||||
|
|
||||||
const qweb = new owl.QWeb({ templates: TEMPLATES});
|
|
||||||
const windows = [
|
const windows = [
|
||||||
{
|
{
|
||||||
name: "Hello",
|
name: "Hello",
|
||||||
@@ -1558,8 +1543,8 @@ const windows = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const env = { qweb, windows };
|
owl.config.env.windows = windows;
|
||||||
const app = new App(env);
|
const app = new App();
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user