Files
third_party_jsframework/runtime/main/app/bundle.ts
T
yuanlin94 b5380d8519 jsframework add boolean
Signed-off-by: yuanlin94 <linyuan25@h-partners.com>
2026-01-22 17:54:16 +08:00

224 lines
6.8 KiB
TypeScript

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* 2021.01.08 - Add init global data and hook life cycle of App.
* Copyright (c) 2021 Huawei Device Co., Ltd.
*/
import {
isModule,
removePrefix,
isApplication,
removeApplicationPrefix,
Log
} from '../../utils/index';
import {
registerCustomComponent,
requireModule
} from '../page/register';
import { pageMap, appMap } from './map';
import { updateLocale, updateDpi } from './index';
import Page from '../page/index';
import { App } from './App';
const APP_LIFE_CYCLE_TYPES: string[] = ['onCreate', 'onError', 'onDestroy', 'onShow', 'onHide'];
export let CSS_INHERITANCE: string[];
/**
* Parse app page code.
* @param {Page} page
* @param {string} packageName - PackageName of App.
* @param {string} name - Name of page.
* @param {*[]} args
*/
export const defineFn = function(page: Page, packageName: string, name?: string, ...args: any[] | null): void {
Log.debug(`Define a page ${name}.`);
const parseContent: Function = args[1];
let bundleContent: any = null;
// Function to obtain bundle content.
if (parseContent) {
const pageRequire = (name: string) : any => {
if (isModule(name)) {
const appFunction = (): Page => {
return pageMap.getTop(packageName) || page;
};
return requireModule(appFunction, removePrefix(name));
}
};
const moduleContent = { exports: {} };
parseContent(pageRequire, moduleContent.exports, moduleContent);
bundleContent = moduleContent.exports;
let minPlatformVersion: number = 5;
if (bundleContent.manifest) {
minPlatformVersion = bundleContent.manifest.minPlatformVersion;
}
CSS_INHERITANCE = minPlatformVersion > 5 ?
['fontFamily', 'fontWeight', 'fontSize', 'fontStyle', 'textAlign', 'lineHeight', 'letterSpacing', 'color', 'visibility'] :
[];
}
// Apply bundleContent.
if (isApplication(name)) {
const componetName: string = removeApplicationPrefix(name);
registerCustomComponent(page, componetName, bundleContent);
}
};
/**
* Set i18n and dpi data, hook life cycle of App.
* @param {Page} page
* @param {string} packageName - PackageName of App.
* @param {string} name - Name of page.
* @param {*} config
* @param {*} data
* @return {*}
*/
export function bootstrap(page: Page, packageName: string, name: string, config: any, data: any): any {
Log.debug(`Bootstrap for ${name}.`);
Log.debug(`${config} ${data}`);
// Check component name.
let componentName: string;
if (isApplication(name)) {
componentName = removeApplicationPrefix(name);
} else {
return new Error(`Wrong component name: ${name}.`);
}
// Init global data when page first load,
// global.aceapp.$data means config.data in manifest.json, can add new data by this.$app.$data api.
if (page.options && page.options.appCreate) {
const getApp = function() {
return global.aceapp;
};
global.getApp = getApp;
global.aceapp = {};
global.aceapp.$data = page.options.appGlobalData || {};
// Set i18n and dpi data.
if (page.options.i18n) {
updateLocale(page.options.i18n);
}
if (page.options.resourcesConfiguration) {
updateDpi(page.options.resourcesConfiguration);
}
}
if (page.customComponentMap) {
const app: App = appMap[packageName];
if (app) {
const options: object = page.customComponentMap[componentName] || {};
const aceapp: any = global.aceapp || {};
for (const key in options) {
if (!isReserved(key)) {
app[key] = options[key];
aceapp[key] = options[key];
}
}
aceapp.$def = aceapp;
aceapp._def = aceapp.$def;
aceapp._data = aceapp.$data;
// Exit api to $app.
aceapp.exit = function(): void {
};
APP_LIFE_CYCLE_TYPES.forEach((type) => {
app.onEvent(`hook:${type}`, options[type]);
});
// Last fire on Create.
Log.debug(`Page "onCreate" lifecycle in app(${app.packageName}).`);
app.emitEvent('hook:onCreate');
}
}
}
/**
* Check input param is onCreate or onDestroy.
* @param {string} key
* @return {boolean}
*/
function isReserved(key: string): boolean {
if (key === 'onCreate' || key === 'onDestroy') {
return true;
}
return false;
}
/**
* Return timerAPIs.
* @param {Page} page - Page
* @return {Object}
*/
export function genTimerAPI(page: Page): object {
const timerAPIs: object = {};
// Timer APIs polyfill in native
const timer: any = page.requireModule('timer');
const animation = page.requireModule('animation');
const digitalCrown = page.requireModule('digitalCrown');
Object.assign(timerAPIs, {
setTimeout: (...args) => {
const handler = () => {
args[0](...args.slice(2));
};
timer.setTimeout(handler, args[1]);
return page.doc.taskCenter.callbackManager.currCallbackId.toString();
},
setInterval: (...args) => {
const handler = () => {
args[0](...args.slice(2));
};
timer.setInterval(handler, args[1]);
return page.doc.taskCenter.callbackManager.currCallbackId.toString();
},
clearTimeout: (n) => {
timer.clearTimeout(n);
page.doc.taskCenter.callbackManager.remove(n);
},
clearInterval: (n) => {
timer.clearInterval(n);
page.doc.taskCenter.callbackManager.remove(n);
},
requestAnimationFrame: (...args) => {
const handler = function(timestamp) {
args[0](timestamp, ...args.slice(1));
};
animation.requestAnimationFrame(handler);
return page.doc.taskCenter.callbackManager.currCallbackId.toString();
},
cancelAnimationFrame: (n) => {
animation.cancelAnimationFrame(n);
},
setMonitorForCrownEvents: (...args) => {
const handler = function(event): boolean {
return args[0](event, ...args.slice(1));
};
digitalCrown.setMonitorForCrownEvents(handler);
return page.doc.taskCenter.callbackManager.currCallbackId.toString();
},
clearMonitorForCrownEvents: ()=>{
digitalCrown.clearMonitorForCrownEvents();
}
});
return timerAPIs;
}