move internal stuff in _, add unique id for each widget

This commit is contained in:
Géry Debongnie
2019-01-25 14:27:16 +01:00
parent c1dd38bf03
commit 9fc7cf0c68
5 changed files with 60 additions and 21 deletions
+38 -17
View File
@@ -8,17 +8,28 @@ const patch = init([sdListeners, sdAttrs]);
export interface WEnv {
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> {
_: Meta<WEnv>;
name: string = "widget";
template: string = "<div></div>";
vnode: VNode | null = null;
isStarted: boolean = false;
isMounted: boolean = false;
parent: Widget<T> | null = null;
children: Widget<T>[] = [];
env: T;
el: HTMLElement | null = null;
state: Object = {};
@@ -29,13 +40,23 @@ export class Widget<T extends WEnv> {
//--------------------------------------------------------------------------
constructor(parent: Widget<T> | T, props?: any) {
wl.push(this);
let p: Widget<T> | null = null;
if (parent instanceof Widget) {
this.parent = parent;
parent.children.push(this);
p = parent;
parent._.children.push(this);
this.env = Object.create(parent.env);
} else {
this.env = parent;
}
this._ = {
id: this.env.getID(),
vnode: null,
isStarted: false,
isMounted: false,
parent: p,
children: []
};
}
async willStart() {}
@@ -56,8 +77,8 @@ export class Widget<T extends WEnv> {
if (document.body.contains(target)) {
this.visitSubTree(w => {
if (!w.isMounted && this.el!.contains(w.el)) {
w.isMounted = true;
if (!w._.isMounted && this.el!.contains(w.el)) {
w._.isMounted = true;
w.mounted();
}
});
@@ -78,7 +99,7 @@ export class Widget<T extends WEnv> {
*/
async updateState(newState: Object) {
Object.assign(this.state, newState);
if (this.isStarted) {
if (this._.isStarted) {
await this.render();
}
}
@@ -92,14 +113,14 @@ export class Widget<T extends WEnv> {
if (!this.el) {
this.el = document.createElement(vnode.sel!);
}
patch(this.vnode || this.el, vnode);
this.vnode = vnode;
patch(this._.vnode || this.el, vnode);
this._.vnode = vnode;
return vnode;
}
private async _start(): Promise<void> {
await this.willStart();
this.isStarted = true;
this._.isStarted = true;
}
private async _render(): Promise<VNode> {
@@ -114,9 +135,9 @@ export class Widget<T extends WEnv> {
_mount(el: HTMLElement) {
this.el = el;
if (this.parent) {
if (this.parent.isMounted) {
this.isMounted = true;
if (this._.parent) {
if (this._.parent._.isMounted) {
this._.isMounted = true;
this.mounted();
}
}
@@ -124,7 +145,7 @@ export class Widget<T extends WEnv> {
private visitSubTree(callback: (w: Widget<T>) => void) {
callback(this);
for (let child of this.children) {
for (let child of this._.children) {
child.visitSubTree(callback);
}
}
+5
View File
@@ -26,3 +26,8 @@ export function htmlTrim(s: string): string {
}
return result;
}
export function idGenerator(): (() => number) {
let nextID = 1;
return () => nextID++;
}
+3 -1
View File
@@ -1,4 +1,5 @@
import { QWeb } from "./core/qweb_vdom";
import { idGenerator } from "./core/utils";
import { WEnv } from "./core/widget";
import { ActionManager } from "./services/action_manager";
import { Ajax } from "./services/ajax";
@@ -31,6 +32,7 @@ export function makeEnvironment(): Env {
ajax,
router,
actionManager,
menus
menus,
getID: idGenerator()
};
}
+10 -1
View File
@@ -1,4 +1,4 @@
import { escape, htmlTrim } from "../src/ts/core/utils";
import { escape, htmlTrim, idGenerator } from "../src/ts/core/utils";
describe("escape", () => {
test("normal strings", () => {
@@ -25,3 +25,12 @@ describe("htmlTrim", () => {
expect(htmlTrim("")).toBe("");
});
});
describe("idGenerator", () => {
test("basic use", () => {
let gen = idGenerator();
expect(gen()).toBe(1);
expect(gen()).toBe(2);
expect(gen()).toBe(3);
});
});
+4 -2
View File
@@ -1,4 +1,5 @@
import { Widget, WEnv } from "../src/ts/core/widget";
import { idGenerator } from "../src/ts/core/utils";
import { QWeb } from "../src/ts/core/qweb_vdom";
interface Type<T> extends Function {
@@ -9,8 +10,9 @@ type TestEnv = WEnv;
type TestWidget = Widget<TestEnv>;
function makeWidget(W: Type<TestWidget>): TestWidget {
const env = {
qweb: new QWeb()
const env: WEnv = {
qweb: new QWeb(),
getID: idGenerator()
};
const w = new W(env);
return w;