diff --git a/src/runtime/app.ts b/src/runtime/app.ts
index 9431e6e7..ea6e9fd4 100644
--- a/src/runtime/app.ts
+++ b/src/runtime/app.ts
@@ -53,7 +53,7 @@ declare global {
}
interface Root
{
- node: ComponentNode
;
+ node: ComponentNode
| null;
mount(target: HTMLElement | ShadowRoot, options?: MountOptions): Promise>;
destroy(): void;
}
@@ -74,8 +74,8 @@ export class App<
props: P;
env: E;
scheduler = new Scheduler();
- subRoots: Set = new Set();
- root: ComponentNode | null = null;
+ subRoots: Set> = new Set();
+ root: Root | null = null;
warnIfNoStaticProps: boolean;
constructor(Root: ComponentConstructor
, config: AppConfig
= {}) {
@@ -101,10 +101,8 @@ export class App<
target: HTMLElement | ShadowRoot,
options?: MountOptions
): Promise & InstanceType> {
- const root = this.createRoot(this.Root, { props: this.props });
- this.root = root.node;
- this.subRoots.delete(root.node);
- return root.mount(target, options) as any;
+ this.root = this.createRoot(this.Root, { props: this.props });
+ return this.root.mount(target, options) as any;
}
createRoot(
@@ -112,25 +110,24 @@ export class App<
config: RootConfig = {}
): Root {
const props = config.props || ({} as Props);
- // hack to make sure the sub root get the sub env if necessary. for owl 3,
- // would be nice to rethink the initialization process to make sure that
- // we can create a ComponentNode and give it explicitely the env, instead
- // of looking it up in the app
const env = this.env;
- if (config.env) {
- this.env = config.env as any;
- }
-
- const restore = saveCurrent();
- const node = this.makeNode(Root, props);
- restore();
- if (config.env) {
- this.env = env;
- }
- this.subRoots.add(node);
- return {
- node,
+ const root: Root = {
+ node: null,
mount: (target: HTMLElement | ShadowRoot, options?: MountOptions) => {
+ // hack to make sure the sub root get the sub env if necessary. for owl 3,
+ // would be nice to rethink the initialization process to make sure that
+ // we can create a ComponentNode and give it explicitely the env, instead
+ // of looking it up in the app
+ if (config.env) {
+ this.env = config.env as any;
+ }
+ const restore = saveCurrent();
+ const node = this.makeNode(Root, props);
+ root.node = node;
+ restore();
+ if (config.env) {
+ this.env = env;
+ }
App.validateTarget(target);
if (this.dev) {
validateProps(Root, props, { __owl__: { app: this } });
@@ -139,11 +136,16 @@ export class App<
return prom;
},
destroy: () => {
- this.subRoots.delete(node);
- node.destroy();
- this.scheduler.processTasks();
+ this.subRoots.delete(root);
+ if (root.node) {
+ root.node?.destroy();
+ this.scheduler.processTasks();
+ }
},
};
+
+ this.subRoots.add(root);
+ return root;
}
makeNode(Component: ComponentConstructor, props: any): ComponentNode {
@@ -178,13 +180,17 @@ export class App<
}
destroy() {
- if (this.root) {
- for (let subroot of this.subRoots) {
- subroot.destroy();
- }
- this.root.destroy();
- this.scheduler.processTasks();
+ const roots = [...this.subRoots].reverse();
+ for (let root of roots) {
+ root.destroy();
}
+ // if (this.root) {
+ // for (let subroot of this.subRoots) {
+ // subroot.destroy();
+ // }
+ // this.root.destroy();
+ this.scheduler.processTasks();
+ // }
apps.delete(this);
}
diff --git a/tests/app/__snapshots__/sub_root.test.ts.snap b/tests/app/__snapshots__/sub_root.test.ts.snap
index efc4d563..aa5ece6c 100644
--- a/tests/app/__snapshots__/sub_root.test.ts.snap
+++ b/tests/app/__snapshots__/sub_root.test.ts.snap
@@ -94,17 +94,6 @@ exports[`subroot can create a root in a setup function, then use a hook 1`] = `
}"
`;
-exports[`subroot can create a root in a setup function, then use a hook 2`] = `
-"function anonymous(app, bdom, helpers
-) {
- let { text, createBlock, list, multi, html, toggler, comment } = bdom;
-
- return function template(ctx, node, key = \\"\\") {
- return text(\`c\`);
- }
-}"
-`;
-
exports[`subroot can mount subroot 1`] = `
"function anonymous(app, bdom, helpers
) {
diff --git a/tests/components/props_validation.test.ts b/tests/components/props_validation.test.ts
index b1b8e81b..727535f1 100644
--- a/tests/components/props_validation.test.ts
+++ b/tests/components/props_validation.test.ts
@@ -702,7 +702,7 @@ describe("props validation", () => {
const app = new App(Parent, { test: true });
await app.mount(fixture);
expect(fixture.innerHTML).toBe("12");
- expect(app.root!.subscriptions).toEqual([{ keys: ["otherValue"], target: obj }]);
+ expect(app.root!.node!.subscriptions).toEqual([{ keys: ["otherValue"], target: obj }]);
});
test("props are validated whenever component is updated", async () => {