[IMP] component: get env from constructor

closes #430
This commit is contained in:
Aaron Bohy
2019-10-31 13:31:10 +01:00
committed by Géry Debongnie
parent 8fbf2172c5
commit 05a678c039
14 changed files with 48 additions and 47 deletions
+5 -2
View File
@@ -1,7 +1,6 @@
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";
@@ -88,6 +87,7 @@ export class Component<T extends Env, Props extends {}> {
static components = {}; static components = {};
static props?: any; static props?: any;
static defaultProps?: any; static defaultProps?: any;
static env: any = {};
/** /**
* The `el` is the root element of the component. Note that it could be null: * The `el` is the root element of the component. Note that it could be null:
@@ -131,7 +131,10 @@ export class Component<T extends Env, Props extends {}> {
depth = __powl__.depth + 1; depth = __powl__.depth + 1;
} else { } else {
// we are the root component // we are the root component
this.env = config.env as T; this.env = (this.constructor as any).env;
if (!this.env.qweb) {
this.env.qweb = new QWeb();
}
this.props = undefined as unknown as Props; this.props = undefined as unknown as Props;
this.env.qweb.on("update", this, () => { this.env.qweb.on("update", this, () => {
if (this.__owl__.isMounted) { if (this.__owl__.isMounted) {
-18
View File
@@ -1,5 +1,4 @@
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:
@@ -8,7 +7,6 @@ import { Env } from "./component/component";
*/ */
interface Config { interface Config {
env: Env;
mode: string; mode: string;
} }
@@ -30,19 +28,3 @@ Object.defineProperty(config, "mode", {
} }
}, },
}); });
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 -2
View File
@@ -1,5 +1,4 @@
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 {
@@ -30,7 +29,7 @@ let cssEl: HTMLElement;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = makeTestEnv(); env = makeTestEnv();
config.env = env; Component.env = env;
qweb = new QWeb(); qweb = new QWeb();
}); });
+27 -3
View File
@@ -3,7 +3,6 @@ import { QWeb } from "../../src/qweb/qweb";
import { xml } from "../../src/tags"; import { xml } from "../../src/tags";
import { useState, useRef } from "../../src/hooks"; import { useState, useRef } from "../../src/hooks";
import { EventBus } from "../../src/core/event_bus"; import { EventBus } from "../../src/core/event_bus";
import { config } from "../../src/config";
import { import {
makeDeferred, makeDeferred,
makeTestFixture, makeTestFixture,
@@ -36,7 +35,7 @@ beforeEach(() => {
); );
env.qweb.addTemplate("WidgetA", `<div>Hello<t t-component="b"/></div>`); env.qweb.addTemplate("WidgetA", `<div>Hello<t t-component="b"/></div>`);
env.qweb.addTemplate("WidgetB", `<div>world</div>`); env.qweb.addTemplate("WidgetB", `<div>world</div>`);
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
@@ -3457,7 +3456,7 @@ describe("can deduce template from name", () => {
await abc.mount(fixture); await abc.mount(fixture);
expect(fixture.innerHTML).toBe("<span>Rochefort 8</span>"); expect(fixture.innerHTML).toBe("<span>Rochefort 8</span>");
abc.destroy(); abc.destroy();
config.env = env2; Component.env = env2;
const abc2 = new ABC(); const abc2 = new ABC();
await abc2.mount(fixture); await abc2.mount(fixture);
expect(fixture.innerHTML).toBe("<span>Rochefort 10</span>"); expect(fixture.innerHTML).toBe("<span>Rochefort 10</span>");
@@ -4247,6 +4246,31 @@ describe("environment and plugins", () => {
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div>Blue</div>"); expect(fixture.innerHTML).toBe("<div>Blue</div>");
}); });
test("can define specific env for root components", async () => {
class App1 extends Component<any, any> {
static template = xml`<span></span>`;
}
App1.env = { test: 1 };
class App2 extends Component<any, any> {
static template = xml`<span></span>`;
}
App2.env = { test: 2 };
class App1B extends App1 {}
class App2B extends App2 {}
App2B.env = { test: 3 };
const app1 = new App1();
const app2 = new App2();
const app1B = new App1B();
const app2B = new App2B();
expect(app1.env.qweb).toBeDefined();
expect(app1.env.test).toBe(1);
expect(app2.env.test).toBe(2);
expect(app1B.env.test).toBe(1);
expect(app2B.env.test).toBe(3);
});
}); });
describe("component error handling (catchError)", () => { describe("component error handling (catchError)", () => {
+1 -2
View File
@@ -1,7 +1,6 @@
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";
@@ -16,7 +15,7 @@ let dev: boolean = false;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = makeTestEnv(); env = makeTestEnv();
config.env = env; Component.env = env;
dev = QWeb.dev; dev = QWeb.dev;
QWeb.dev = true; QWeb.dev = true;
}); });
+1 -2
View File
@@ -1,7 +1,6 @@
import { makeDeferred, makeTestEnv, makeTestFixture, nextTick } from "./helpers"; import { makeDeferred, makeTestEnv, makeTestFixture, nextTick } from "./helpers";
import { Component } 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";
@@ -18,7 +17,7 @@ let fixture: HTMLElement;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
config.env = makeTestEnv(); Component.env = makeTestEnv();
}); });
afterEach(() => { afterEach(() => {
+1 -2
View File
@@ -1,6 +1,5 @@
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,
@@ -29,7 +28,7 @@ let env: Env;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = makeTestEnv(); env = makeTestEnv();
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
+1 -2
View File
@@ -1,5 +1,4 @@
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";
@@ -18,7 +17,7 @@ let fixture: HTMLElement;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
config.env = makeTestEnv(); Component.env = makeTestEnv();
}); });
afterEach(() => { afterEach(() => {
+1 -2
View File
@@ -1,5 +1,4 @@
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";
@@ -13,7 +12,7 @@ describe("Link component", () => {
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = <RouterEnv>makeTestEnv(); env = <RouterEnv>makeTestEnv();
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
+1 -2
View File
@@ -1,5 +1,4 @@
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";
@@ -13,7 +12,7 @@ describe("RouteComponent", () => {
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = <RouterEnv>makeTestEnv(); env = <RouterEnv>makeTestEnv();
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
+2 -3
View File
@@ -1,5 +1,4 @@
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";
@@ -13,7 +12,7 @@ describe("connecting a component to store", () => {
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = makeTestEnv(); env = makeTestEnv();
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
@@ -922,7 +921,7 @@ describe("various scenarios", () => {
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = makeTestEnv(); env = makeTestEnv();
config.env = env; Component.env = env;
}); });
afterEach(() => { afterEach(() => {
+1 -1
View File
@@ -144,7 +144,7 @@ App.components = { Message };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
async function start() { async function start() {
const templates = await owl.utils.loadFile("templates.xml"); const templates = await owl.utils.loadFile("templates.xml");
owl.config.env = { App.env = {
qweb: new owl.QWeb({ templates }) qweb: new owl.QWeb({ templates })
}; };
const app = new App(); const app = new App();
+2 -2
View File
@@ -95,7 +95,7 @@ function makeCodeIframe(js, css, xml, errorHandler) {
owl.__info__.mode = 'dev'; owl.__info__.mode = 'dev';
let templates = \`${sanitizedXML}\`; let templates = \`${sanitizedXML}\`;
const qweb = new owl.QWeb({ templates }); const qweb = new owl.QWeb({ templates });
owl.config.env = { qweb }; owl.Component.env = { qweb };
} }
${js}`; ${js}`;
script.innerHTML = content; script.innerHTML = content;
@@ -443,7 +443,7 @@ async function start() {
owl.utils.whenReady() owl.utils.whenReady()
]); ]);
const qweb = new owl.QWeb({ templates }); const qweb = new owl.QWeb({ templates });
owl.config.env = { qweb }; owl.Component.env = { qweb };
const app = new App(); const app = new App();
app.mount(document.body); app.mount(document.body);
} }
+4 -4
View File
@@ -345,7 +345,7 @@ const themeContext = new Context({
foreground: '#fff', foreground: '#fff',
}); });
// Add the themeContext the environment to make it available to all components // Add the themeContext the environment to make it available to all components
owl.config.env.themeContext = themeContext; App.env.themeContext = themeContext;
const app = new App(); const app = new App();
app.mount(document.body); app.mount(document.body);
`; `;
@@ -544,7 +544,7 @@ function makeStore() {
return store; return store;
} }
owl.config.env.store = makeStore(); TodoApp.env.store = makeStore();
const app = new TodoApp(); const app = new TodoApp();
app.mount(document.body); app.mount(document.body);
`; `;
@@ -1032,7 +1032,7 @@ function setupResponsivePlugin(env) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Application Startup // Application Startup
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
setupResponsivePlugin(owl.config.env); setupResponsivePlugin(App.env);
const app = new App(); const app = new App();
app.mount(document.body); app.mount(document.body);
@@ -1543,7 +1543,7 @@ const windows = [
} }
]; ];
owl.config.env.windows = windows; App.env.windows = windows;
const app = new App(); const app = new App();
app.mount(document.body); app.mount(document.body);
`; `;