[IMP] app: improve API, small refactoring

This commit is contained in:
Géry Debongnie
2021-12-20 17:32:32 +01:00
committed by Aaron Bohy
parent 772c275bd4
commit aad6b806ba
13 changed files with 112 additions and 87 deletions
+17 -28
View File
@@ -2,7 +2,7 @@ import { Component } from "../component/component";
import { ComponentNode } from "../component/component_node";
import { MountOptions } from "../component/fibers";
import { Scheduler } from "../component/scheduler";
import { TemplateSet } from "./template_set";
import { TemplateSet, TemplateSetConfig } from "./template_set";
import { nodeErrorHandlers } from "../component/error_handling";
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
@@ -11,12 +11,9 @@ export interface Env {
[key: string]: any;
}
export interface AppConfig {
dev?: boolean;
export interface AppConfig extends TemplateSetConfig {
env?: Env;
translatableAttributes?: string[];
translateFn?: (s: string) => string;
templates?: string | Document;
props?: any;
}
export const DEV_MSG = `Owl is running in 'dev' mode.
@@ -27,35 +24,19 @@ See https://github.com/odoo/owl/blob/master/doc/reference/config.md#mode for mor
export class App<T extends typeof Component = any> extends TemplateSet {
Root: T;
props: any;
env: Env = Object.freeze({});
env: Env;
scheduler = new Scheduler(window.requestAnimationFrame.bind(window));
root: ComponentNode | null = null;
constructor(Root: T, props?: any) {
super();
constructor(Root: T, config: AppConfig = {}) {
super(config);
this.Root = Root;
this.props = props;
}
configure(config: AppConfig): App<T> {
if (config.dev) {
this.dev = config.dev;
console.info(DEV_MSG);
}
if (config.env) {
const descrs = Object.getOwnPropertyDescriptors(config.env);
this.env = Object.freeze(Object.defineProperties({}, descrs));
}
if (config.translateFn) {
this.translateFn = config.translateFn;
}
if (config.translatableAttributes) {
this.translatableAttributes = config.translatableAttributes;
}
if (config.templates) {
this.addTemplates(config.templates);
}
return this;
const descrs = Object.getOwnPropertyDescriptors(config.env || {});
this.env = Object.freeze(Object.defineProperties({}, descrs));
this.props = config.props || {};
}
mount(target: HTMLElement, options?: MountOptions): Promise<InstanceType<T>> {
@@ -114,3 +95,11 @@ export class App<T extends typeof Component = any> extends TemplateSet {
}
}
}
export async function mount<T extends typeof Component>(
C: T,
target: HTMLElement,
config: AppConfig & MountOptions = {}
): Promise<InstanceType<T>> {
return new App(C, config).mount(target, config);
}
+20 -8
View File
@@ -37,22 +37,34 @@ function parseXML(xml: string): Document {
return doc;
}
export interface TemplateSetConfig {
dev?: boolean;
translatableAttributes?: string[];
translateFn?: (s: string) => string;
templates?: string | Document;
}
export class TemplateSet {
dev: boolean;
rawTemplates: typeof globalTemplates = Object.create(globalTemplates);
templates: { [name: string]: Template } = {};
translateFn?: (s: string) => string;
translatableAttributes?: string[];
utils: typeof UTILS;
dev?: boolean;
constructor() {
const call = (owner: any, subTemplate: string, ctx: any, parent: any) => {
utils: typeof UTILS = Object.assign({}, UTILS, {
call: (owner: any, subTemplate: string, ctx: any, parent: any) => {
const template = this.getTemplate(subTemplate);
return toggler(subTemplate, template.call(owner, ctx, parent));
};
},
getTemplate: (name: string) => this.getTemplate(name),
});
const getTemplate = (name: string) => this.getTemplate(name);
this.utils = Object.assign({}, UTILS, { getTemplate, call });
constructor(config: TemplateSetConfig = {}) {
this.dev = config.dev || false;
this.translateFn = config.translateFn;
this.translatableAttributes = config.translatableAttributes;
if (config.templates) {
this.addTemplates(config.templates);
}
}
addTemplate(name: string, template: string | Node, options: { allowDuplicate?: boolean } = {}) {
+10 -6
View File
@@ -13,6 +13,16 @@ import { handleError, fibersInError } from "./error_handling";
import { applyDefaultProps } from "./props_validation";
import { STATUS } from "./status";
let currentNode: ComponentNode | null = null;
export function getCurrent(): ComponentNode | null {
return currentNode;
}
export function useComponent(): Component {
return currentNode!.component;
}
export function component(
name: string | typeof Component,
props: any,
@@ -62,12 +72,6 @@ export function component(
// Component VNode
// -----------------------------------------------------------------------------
let currentNode: ComponentNode | null = null;
export function getCurrent(): ComponentNode | null {
return currentNode;
}
type LifecycleHook = Function;
export class ComponentNode<T extends typeof Component = typeof Component>
+3 -22
View File
@@ -32,27 +32,9 @@ export const blockDom = {
comment,
};
import type { AppConfig } from "./app/app";
import { App } from "./app/app";
import { Component } from "./component/component";
import { getCurrent } from "./component/component_node";
export { App, Component };
export async function mount<T extends typeof Component>(
C: T,
target: HTMLElement,
config: AppConfig = {}
): Promise<InstanceType<T>> {
const app = new App(C);
return app.configure(config).mount(target);
}
export function useComponent(): Component {
const current = getCurrent();
return current!.component;
}
export { App, mount } from "./app/app";
export { Component } from "./component/component";
export { useComponent } from "./component/component_node";
export { status } from "./component/status";
export { Portal } from "./portal";
export { Memo } from "./memo";
@@ -60,7 +42,6 @@ export { xml } from "./app/template_set";
export { useState, reactive } from "./reactivity";
export { useEffect, useEnv, useExternalListener, useRef, useSubEnv } from "./hooks";
export { EventBus, whenReady, loadFile, markup } from "./utils";
export {
onWillStart,
onMounted,