import type { View, Template, KeyedTemplate } from '../core/view'; import type { ViewBase } from '../core/view-base'; import type { ViewEntry } from '../frame/frame-interfaces'; import type { Page } from '../page'; import { debug } from '../../utils/debug'; import { isDefined } from '../../utils/types'; import { sanitizeModuleName } from '../../utils/common'; import { setPropertyValue, getComponentModule } from './component-builder'; import type { ComponentModule } from './component-builder'; import { platformNames } from '../../platform/common'; import { resolveModuleName } from '../../module-name-resolver'; import { ScopeError, SourceError, Source } from '../../utils/debug-source'; import * as xml from '../../xml'; import { isString, isObject } from '../../utils/types'; import { Device } from '../../platform/device'; import { profile } from '../../profiling'; // Note: after all circulars are resolve, try importing this from single place or see if globals/index.ts properly handles it if (typeof global.__metadata === 'undefined') { /** * TS decorator metadata helper. * @param metadataKey the metadata key (e.g. "design:type") * @param metadataValue the metadata value (e.g. the constructor function) * @returns a decorator function, or undefined if Reflect.metadata isn’t available */ global.__metadata = (metadataKey, metadataValue) => { if ( typeof Reflect === 'object' && // @ts-expect-error typeof Reflect.metadata === 'function' ) { // Delegate to the reflect-metadata shim // @ts-expect-error return Reflect.metadata(metadataKey, metadataValue); } // no-op if no Reflect.metadata }; } export const ios = platformNames.ios.toLowerCase(); export const android = platformNames.android.toLowerCase(); export const visionos = platformNames.visionos.toLowerCase(); export const apple = platformNames.apple.toLowerCase(); export const defaultNameSpaceMatcher = /tns\.xsd$/i; export interface LoadOptions { path: string; name: string; attributes?: any; exports?: any; page?: Page; } export class Builder { /** * UI plugin developers can add to these to define their own custom types if needed */ static knownTemplates: Set = new Set(['itemTemplate']); static knownMultiTemplates: Set = new Set(['itemTemplates']); static knownCollections: Set = new Set(['items', 'spans', 'actionItems']); /** * Creates view from navigation entry * @param entry NavigationEntry */ static createViewFromEntry(entry: ViewEntry): View { if (entry.create) { const view = entry.create(); if (!view) { throw new Error('Failed to create View with entry.create() function.'); } return view; } else if (entry.moduleName) { const moduleName = sanitizeModuleName(entry.moduleName); console.log('.'); console.log('moduleName:', moduleName); const resolvedCodeModuleName = resolveModuleName(moduleName, ''); //`${moduleName}.xml`; const moduleExports = resolvedCodeModuleName ? global.loadModule(resolvedCodeModuleName) : null; console.log('createViewFromEntry called with entry:', entry, 'moduleName:', entry.moduleName, 'resolvedCodeModuleName:', resolvedCodeModuleName, 'moduleExports:', moduleExports); if (moduleExports && moduleExports.createPage) { // Exports has a createPage() method const view = moduleExports.createPage(); const resolvedCssModuleName = resolveModuleName(moduleName, 'css'); //entry.moduleName + ".css"; if (resolvedCssModuleName) { view.addCssFile(resolvedCssModuleName); } return view; } else { let componentView; if (__UI_USE_XML_PARSER__) { const componentModule = loadInternal(moduleName, moduleExports); componentView = componentModule && componentModule.component; } else { const resolvedXmlModuleName = resolveModuleName(moduleName, 'xml'); const componentModule = resolvedXmlModuleName ? global.loadModule(resolvedXmlModuleName) : null; if (componentModule?.default) { componentView = new componentModule.default(); } else { throw new Error('Failed to load component from module: ' + moduleName); } } return componentView; } } throw new Error('Failed to load page XML file for module: ' + entry.moduleName); } static parse(value: string | Template, context?: any): View { if (typeof value === 'function') { return (