mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
committed by
Géry Debongnie
parent
8fbf2172c5
commit
05a678c039
@@ -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) {
|
||||||
|
|||||||
@@ -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,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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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,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,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
@@ -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,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,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,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(() => {
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user