Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 2x 2x 88x 88x 88x 88x 1x 1x 88x 26x 26x 26x 26x 88x 77x 77x 88x 88x 2x 2x 497x 497x 497x 2x 731x 2x 2x 729x 731x 537x 537x 192x 731x 731x 169x 169x 71x 71x 71x 1x 1x 71x 169x 169x 169x 69x 69x 169x 169x 169x 97x 97x 169x 191x 191x 731x 2x 735x 735x 735x 735x 3x 3x 732x 732x 732x 197x 196x 735x 195x 195x 565x 2x 2x 565x 1x 1x 534x 735x 2x 403x 403x 403x 403x 403x 403x 403x 2x | import type { Router } from './router';
import type { RouterMicroAppCallback, RouterMicroAppOptions } from './types';
import { isBrowser, isPlainObject } from './util';
/**
* Resolves the root container element.
* Supports a DOM selector string or a direct HTMLElement.
*
* @param rootConfig - The root container configuration, can be a selector string or an HTMLElement.
* @returns The resolved HTMLElement.
*/
export function resolveRootElement(
rootConfig?: string | HTMLElement
): HTMLElement {
let el: HTMLElement | null = null;
// Direct HTMLElement provided
if (rootConfig instanceof HTMLElement) {
el = rootConfig;
}
if (typeof rootConfig === 'string' && rootConfig) {
try {
el = document.querySelector(rootConfig);
} catch (error) {
console.warn(`Failed to resolve root element: ${rootConfig}`);
}
}
if (el === null) {
el = document.createElement('div');
}
return el;
}
export class MicroApp {
public app: RouterMicroAppOptions | null = null;
public root: HTMLElement | null = null;
private _factory: RouterMicroAppCallback | null = null;
private destroyed = false;
public _update(router: Router, force = false) {
if (this.destroyed) {
throw new Error('MicroApp has been destroyed');
}
const factory = this._getNextFactory(router);
if (!force && factory === this._factory) {
return;
}
const oldApp = this.app;
// Create the new application
const app = factory ? factory(router) : null;
if (isBrowser && app) {
let root: HTMLElement | null = this.root;
if (root === null) {
root = resolveRootElement(router.root);
const { rootStyle } = router.parsedOptions;
if (root && isPlainObject(rootStyle)) {
Object.assign(root.style, router.parsedOptions.rootStyle);
}
}
if (root) {
app.mount(root);
if (root.parentNode === null) {
document.body.appendChild(root);
}
this.root = root;
}
if (oldApp) {
oldApp.unmount();
}
}
this.app = app;
this._factory = factory;
}
private _getNextFactory({
route,
options
}: Router): RouterMicroAppCallback | null {
if (!route.matched || route.matched.length === 0) {
return null;
}
const name = route.matched[0].app;
if (
typeof name === 'string' &&
options.apps &&
typeof options.apps === 'object'
) {
return options.apps[name] || null;
}
if (typeof name === 'function') {
return name;
}
if (typeof options.apps === 'function') {
return options.apps;
}
return null;
}
public destroy() {
this.app?.unmount();
this.app = null;
this.root?.remove();
this.root = null;
this._factory = null;
this.destroyed = true;
}
}
|