mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
move internal stuff in _, add unique id for each widget
This commit is contained in:
@@ -8,17 +8,28 @@ const patch = init([sdListeners, sdAttrs]);
|
|||||||
|
|
||||||
export interface WEnv {
|
export interface WEnv {
|
||||||
qweb: QWeb;
|
qweb: QWeb;
|
||||||
|
getID(): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wl: any[] = [];
|
||||||
|
(<any>window).wl = wl;
|
||||||
|
|
||||||
|
interface Meta<T extends WEnv> {
|
||||||
|
id: number;
|
||||||
|
// name: string;
|
||||||
|
// template: string;
|
||||||
|
vnode: VNode | null;
|
||||||
|
isStarted: boolean;
|
||||||
|
isMounted: boolean;
|
||||||
|
parent: Widget<T> | null;
|
||||||
|
children: Widget<T>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Widget<T extends WEnv> {
|
export class Widget<T extends WEnv> {
|
||||||
|
_: Meta<WEnv>;
|
||||||
name: string = "widget";
|
name: string = "widget";
|
||||||
template: string = "<div></div>";
|
template: string = "<div></div>";
|
||||||
vnode: VNode | null = null;
|
|
||||||
|
|
||||||
isStarted: boolean = false;
|
|
||||||
isMounted: boolean = false;
|
|
||||||
parent: Widget<T> | null = null;
|
|
||||||
children: Widget<T>[] = [];
|
|
||||||
env: T;
|
env: T;
|
||||||
el: HTMLElement | null = null;
|
el: HTMLElement | null = null;
|
||||||
state: Object = {};
|
state: Object = {};
|
||||||
@@ -29,13 +40,23 @@ export class Widget<T extends WEnv> {
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
constructor(parent: Widget<T> | T, props?: any) {
|
constructor(parent: Widget<T> | T, props?: any) {
|
||||||
|
wl.push(this);
|
||||||
|
let p: Widget<T> | null = null;
|
||||||
if (parent instanceof Widget) {
|
if (parent instanceof Widget) {
|
||||||
this.parent = parent;
|
p = parent;
|
||||||
parent.children.push(this);
|
parent._.children.push(this);
|
||||||
this.env = Object.create(parent.env);
|
this.env = Object.create(parent.env);
|
||||||
} else {
|
} else {
|
||||||
this.env = parent;
|
this.env = parent;
|
||||||
}
|
}
|
||||||
|
this._ = {
|
||||||
|
id: this.env.getID(),
|
||||||
|
vnode: null,
|
||||||
|
isStarted: false,
|
||||||
|
isMounted: false,
|
||||||
|
parent: p,
|
||||||
|
children: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async willStart() {}
|
async willStart() {}
|
||||||
@@ -56,8 +77,8 @@ export class Widget<T extends WEnv> {
|
|||||||
|
|
||||||
if (document.body.contains(target)) {
|
if (document.body.contains(target)) {
|
||||||
this.visitSubTree(w => {
|
this.visitSubTree(w => {
|
||||||
if (!w.isMounted && this.el!.contains(w.el)) {
|
if (!w._.isMounted && this.el!.contains(w.el)) {
|
||||||
w.isMounted = true;
|
w._.isMounted = true;
|
||||||
w.mounted();
|
w.mounted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -78,7 +99,7 @@ export class Widget<T extends WEnv> {
|
|||||||
*/
|
*/
|
||||||
async updateState(newState: Object) {
|
async updateState(newState: Object) {
|
||||||
Object.assign(this.state, newState);
|
Object.assign(this.state, newState);
|
||||||
if (this.isStarted) {
|
if (this._.isStarted) {
|
||||||
await this.render();
|
await this.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,14 +113,14 @@ export class Widget<T extends WEnv> {
|
|||||||
if (!this.el) {
|
if (!this.el) {
|
||||||
this.el = document.createElement(vnode.sel!);
|
this.el = document.createElement(vnode.sel!);
|
||||||
}
|
}
|
||||||
patch(this.vnode || this.el, vnode);
|
patch(this._.vnode || this.el, vnode);
|
||||||
this.vnode = vnode;
|
this._.vnode = vnode;
|
||||||
return vnode;
|
return vnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _start(): Promise<void> {
|
private async _start(): Promise<void> {
|
||||||
await this.willStart();
|
await this.willStart();
|
||||||
this.isStarted = true;
|
this._.isStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _render(): Promise<VNode> {
|
private async _render(): Promise<VNode> {
|
||||||
@@ -114,9 +135,9 @@ export class Widget<T extends WEnv> {
|
|||||||
|
|
||||||
_mount(el: HTMLElement) {
|
_mount(el: HTMLElement) {
|
||||||
this.el = el;
|
this.el = el;
|
||||||
if (this.parent) {
|
if (this._.parent) {
|
||||||
if (this.parent.isMounted) {
|
if (this._.parent._.isMounted) {
|
||||||
this.isMounted = true;
|
this._.isMounted = true;
|
||||||
this.mounted();
|
this.mounted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +145,7 @@ export class Widget<T extends WEnv> {
|
|||||||
|
|
||||||
private visitSubTree(callback: (w: Widget<T>) => void) {
|
private visitSubTree(callback: (w: Widget<T>) => void) {
|
||||||
callback(this);
|
callback(this);
|
||||||
for (let child of this.children) {
|
for (let child of this._.children) {
|
||||||
child.visitSubTree(callback);
|
child.visitSubTree(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,8 @@ export function htmlTrim(s: string): string {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function idGenerator(): (() => number) {
|
||||||
|
let nextID = 1;
|
||||||
|
return () => nextID++;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { QWeb } from "./core/qweb_vdom";
|
import { QWeb } from "./core/qweb_vdom";
|
||||||
|
import { idGenerator } from "./core/utils";
|
||||||
import { WEnv } from "./core/widget";
|
import { WEnv } from "./core/widget";
|
||||||
import { ActionManager } from "./services/action_manager";
|
import { ActionManager } from "./services/action_manager";
|
||||||
import { Ajax } from "./services/ajax";
|
import { Ajax } from "./services/ajax";
|
||||||
@@ -31,6 +32,7 @@ export function makeEnvironment(): Env {
|
|||||||
ajax,
|
ajax,
|
||||||
router,
|
router,
|
||||||
actionManager,
|
actionManager,
|
||||||
menus
|
menus,
|
||||||
|
getID: idGenerator()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { escape, htmlTrim } from "../src/ts/core/utils";
|
import { escape, htmlTrim, idGenerator } from "../src/ts/core/utils";
|
||||||
|
|
||||||
describe("escape", () => {
|
describe("escape", () => {
|
||||||
test("normal strings", () => {
|
test("normal strings", () => {
|
||||||
@@ -25,3 +25,12 @@ describe("htmlTrim", () => {
|
|||||||
expect(htmlTrim("")).toBe("");
|
expect(htmlTrim("")).toBe("");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("idGenerator", () => {
|
||||||
|
test("basic use", () => {
|
||||||
|
let gen = idGenerator();
|
||||||
|
expect(gen()).toBe(1);
|
||||||
|
expect(gen()).toBe(2);
|
||||||
|
expect(gen()).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Widget, WEnv } from "../src/ts/core/widget";
|
import { Widget, WEnv } from "../src/ts/core/widget";
|
||||||
|
import { idGenerator } from "../src/ts/core/utils";
|
||||||
import { QWeb } from "../src/ts/core/qweb_vdom";
|
import { QWeb } from "../src/ts/core/qweb_vdom";
|
||||||
|
|
||||||
interface Type<T> extends Function {
|
interface Type<T> extends Function {
|
||||||
@@ -9,8 +10,9 @@ type TestEnv = WEnv;
|
|||||||
type TestWidget = Widget<TestEnv>;
|
type TestWidget = Widget<TestEnv>;
|
||||||
|
|
||||||
function makeWidget(W: Type<TestWidget>): TestWidget {
|
function makeWidget(W: Type<TestWidget>): TestWidget {
|
||||||
const env = {
|
const env: WEnv = {
|
||||||
qweb: new QWeb()
|
qweb: new QWeb(),
|
||||||
|
getID: idGenerator()
|
||||||
};
|
};
|
||||||
const w = new W(env);
|
const w = new W(env);
|
||||||
return w;
|
return w;
|
||||||
|
|||||||
Reference in New Issue
Block a user