1e484b35bSopenharmony_ci/* 2e484b35bSopenharmony_ci * Licensed to the Apache Software Foundation (ASF) under one 3e484b35bSopenharmony_ci * or more contributor license agreements. See the NOTICE file 4e484b35bSopenharmony_ci * distributed with this work for additional information 5e484b35bSopenharmony_ci * regarding copyright ownership. The ASF licenses this file 6e484b35bSopenharmony_ci * to you under the Apache License, Version 2.0 (the 7e484b35bSopenharmony_ci * "License"); you may not use this file except in compliance 8e484b35bSopenharmony_ci * with the License. You may obtain a copy of the License at 9e484b35bSopenharmony_ci * 10e484b35bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 11e484b35bSopenharmony_ci * 12e484b35bSopenharmony_ci * Unless required by applicable law or agreed to in writing, 13e484b35bSopenharmony_ci * software distributed under the License is distributed on an 14e484b35bSopenharmony_ci * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15e484b35bSopenharmony_ci * KIND, either express or implied. See the License for the 16e484b35bSopenharmony_ci * specific language governing permissions and limitations 17e484b35bSopenharmony_ci * under the License. 18e484b35bSopenharmony_ci */ 19e484b35bSopenharmony_ci/* 20e484b35bSopenharmony_ci * 2021.01.08 - Add init global data and hook life cycle of App. 21e484b35bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 22e484b35bSopenharmony_ci */ 23e484b35bSopenharmony_ci 24e484b35bSopenharmony_ciimport { 25e484b35bSopenharmony_ci isModule, 26e484b35bSopenharmony_ci removePrefix, 27e484b35bSopenharmony_ci isApplication, 28e484b35bSopenharmony_ci removeApplicationPrefix, 29e484b35bSopenharmony_ci Log 30e484b35bSopenharmony_ci} from '../../utils/index'; 31e484b35bSopenharmony_ciimport { 32e484b35bSopenharmony_ci registerCustomComponent, 33e484b35bSopenharmony_ci requireModule 34e484b35bSopenharmony_ci} from '../page/register'; 35e484b35bSopenharmony_ciimport { pageMap, appMap } from './map'; 36e484b35bSopenharmony_ciimport { updateLocale, updateDpi } from './index'; 37e484b35bSopenharmony_ciimport Page from '../page/index'; 38e484b35bSopenharmony_ciimport { App } from './App'; 39e484b35bSopenharmony_ci 40e484b35bSopenharmony_ciconst APP_LIFE_CYCLE_TYPES: string[] = ['onCreate', 'onError', 'onDestroy', 'onShow', 'onHide']; 41e484b35bSopenharmony_ci 42e484b35bSopenharmony_ciexport let CSS_INHERITANCE: string[]; 43e484b35bSopenharmony_ci 44e484b35bSopenharmony_ci/** 45e484b35bSopenharmony_ci * Parse app page code. 46e484b35bSopenharmony_ci * @param {Page} page 47e484b35bSopenharmony_ci * @param {string} packageName - PackageName of App. 48e484b35bSopenharmony_ci * @param {string} name - Name of page. 49e484b35bSopenharmony_ci * @param {*[]} args 50e484b35bSopenharmony_ci */ 51e484b35bSopenharmony_ciexport const defineFn = function(page: Page, packageName: string, name?: string, ...args: any[] | null): void { 52e484b35bSopenharmony_ci Log.debug(`Define a page ${name}.`); 53e484b35bSopenharmony_ci const parseContent: Function = args[1]; 54e484b35bSopenharmony_ci let bundleContent: any = null; 55e484b35bSopenharmony_ci 56e484b35bSopenharmony_ci // Function to obtain bundle content. 57e484b35bSopenharmony_ci if (parseContent) { 58e484b35bSopenharmony_ci const pageRequire = (name: string) : any => { 59e484b35bSopenharmony_ci if (isModule(name)) { 60e484b35bSopenharmony_ci const appFunction = (): Page => { 61e484b35bSopenharmony_ci return pageMap.getTop(packageName) || page; 62e484b35bSopenharmony_ci }; 63e484b35bSopenharmony_ci return requireModule(appFunction, removePrefix(name)); 64e484b35bSopenharmony_ci } 65e484b35bSopenharmony_ci }; 66e484b35bSopenharmony_ci const moduleContent = { exports: {} }; 67e484b35bSopenharmony_ci parseContent(pageRequire, moduleContent.exports, moduleContent); 68e484b35bSopenharmony_ci bundleContent = moduleContent.exports; 69e484b35bSopenharmony_ci 70e484b35bSopenharmony_ci let minPlatformVersion: number = 5; 71e484b35bSopenharmony_ci if (bundleContent.manifest) { 72e484b35bSopenharmony_ci minPlatformVersion = bundleContent.manifest.minPlatformVersion; 73e484b35bSopenharmony_ci } 74e484b35bSopenharmony_ci CSS_INHERITANCE = minPlatformVersion > 5 ? 75e484b35bSopenharmony_ci ['fontFamily', 'fontWeight', 'fontSize', 'fontStyle', 'textAlign', 'lineHeight', 'letterSpacing', 'color', 'visibility'] : 76e484b35bSopenharmony_ci []; 77e484b35bSopenharmony_ci } 78e484b35bSopenharmony_ci 79e484b35bSopenharmony_ci // Apply bundleContent. 80e484b35bSopenharmony_ci if (isApplication(name)) { 81e484b35bSopenharmony_ci const componetName: string = removeApplicationPrefix(name); 82e484b35bSopenharmony_ci registerCustomComponent(page, componetName, bundleContent); 83e484b35bSopenharmony_ci } 84e484b35bSopenharmony_ci}; 85e484b35bSopenharmony_ci 86e484b35bSopenharmony_ci/** 87e484b35bSopenharmony_ci * Set i18n and dpi data, hook life cycle of App. 88e484b35bSopenharmony_ci * @param {Page} page 89e484b35bSopenharmony_ci * @param {string} packageName - PackageName of App. 90e484b35bSopenharmony_ci * @param {string} name - Name of page. 91e484b35bSopenharmony_ci * @param {*} config 92e484b35bSopenharmony_ci * @param {*} data 93e484b35bSopenharmony_ci * @return {*} 94e484b35bSopenharmony_ci */ 95e484b35bSopenharmony_ciexport function bootstrap(page: Page, packageName: string, name: string, config: any, data: any): any { 96e484b35bSopenharmony_ci Log.debug(`Bootstrap for ${name}.`); 97e484b35bSopenharmony_ci Log.debug(`${config} ${data}`); 98e484b35bSopenharmony_ci 99e484b35bSopenharmony_ci // Check component name. 100e484b35bSopenharmony_ci let componentName: string; 101e484b35bSopenharmony_ci if (isApplication(name)) { 102e484b35bSopenharmony_ci componentName = removeApplicationPrefix(name); 103e484b35bSopenharmony_ci } else { 104e484b35bSopenharmony_ci return new Error(`Wrong component name: ${name}.`); 105e484b35bSopenharmony_ci } 106e484b35bSopenharmony_ci 107e484b35bSopenharmony_ci // Init global data when page first load, 108e484b35bSopenharmony_ci // global.aceapp.$data means config.data in manifest.json, can add new data by this.$app.$data api. 109e484b35bSopenharmony_ci if (page.options && page.options.appCreate) { 110e484b35bSopenharmony_ci const getApp = function() { 111e484b35bSopenharmony_ci return global.aceapp; 112e484b35bSopenharmony_ci }; 113e484b35bSopenharmony_ci global.getApp = getApp; 114e484b35bSopenharmony_ci global.aceapp = {}; 115e484b35bSopenharmony_ci global.aceapp.$data = page.options.appGlobalData || {}; 116e484b35bSopenharmony_ci 117e484b35bSopenharmony_ci // Set i18n and dpi data. 118e484b35bSopenharmony_ci if (page.options.i18n) { 119e484b35bSopenharmony_ci updateLocale(page.options.i18n); 120e484b35bSopenharmony_ci } 121e484b35bSopenharmony_ci if (page.options.resourcesConfiguration) { 122e484b35bSopenharmony_ci updateDpi(page.options.resourcesConfiguration); 123e484b35bSopenharmony_ci } 124e484b35bSopenharmony_ci } 125e484b35bSopenharmony_ci if (page.customComponentMap) { 126e484b35bSopenharmony_ci const app: App = appMap[packageName]; 127e484b35bSopenharmony_ci if (app) { 128e484b35bSopenharmony_ci const options: object = page.customComponentMap[componentName] || {}; 129e484b35bSopenharmony_ci const aceapp: any = global.aceapp || {}; 130e484b35bSopenharmony_ci for (const key in options) { 131e484b35bSopenharmony_ci if (!isReserved(key)) { 132e484b35bSopenharmony_ci app[key] = options[key]; 133e484b35bSopenharmony_ci aceapp[key] = options[key]; 134e484b35bSopenharmony_ci } 135e484b35bSopenharmony_ci } 136e484b35bSopenharmony_ci aceapp.$def = aceapp; 137e484b35bSopenharmony_ci aceapp._def = aceapp.$def; 138e484b35bSopenharmony_ci aceapp._data = aceapp.$data; 139e484b35bSopenharmony_ci 140e484b35bSopenharmony_ci // Exit api to $app. 141e484b35bSopenharmony_ci aceapp.exit = function(): void { 142e484b35bSopenharmony_ci }; 143e484b35bSopenharmony_ci APP_LIFE_CYCLE_TYPES.forEach((type) => { 144e484b35bSopenharmony_ci app.onEvent(`hook:${type}`, options[type]); 145e484b35bSopenharmony_ci }); 146e484b35bSopenharmony_ci 147e484b35bSopenharmony_ci // Last fire on Create. 148e484b35bSopenharmony_ci Log.debug(`Page "onCreate" lifecycle in app(${app.packageName}).`); 149e484b35bSopenharmony_ci app.emitEvent('hook:onCreate'); 150e484b35bSopenharmony_ci } 151e484b35bSopenharmony_ci } 152e484b35bSopenharmony_ci} 153e484b35bSopenharmony_ci 154e484b35bSopenharmony_ci/** 155e484b35bSopenharmony_ci * Check input param is onCreate or onDestroy. 156e484b35bSopenharmony_ci * @param {string} key 157e484b35bSopenharmony_ci * @return {boolean} 158e484b35bSopenharmony_ci */ 159e484b35bSopenharmony_cifunction isReserved(key: string): boolean { 160e484b35bSopenharmony_ci if (key === 'onCreate' || key === 'onDestroy') { 161e484b35bSopenharmony_ci return true; 162e484b35bSopenharmony_ci } 163e484b35bSopenharmony_ci return false; 164e484b35bSopenharmony_ci} 165e484b35bSopenharmony_ci 166e484b35bSopenharmony_ci/** 167e484b35bSopenharmony_ci * Return timerAPIs. 168e484b35bSopenharmony_ci * @param {Page} page - Page 169e484b35bSopenharmony_ci * @return {Object} 170e484b35bSopenharmony_ci */ 171e484b35bSopenharmony_ciexport function genTimerAPI(page: Page): object { 172e484b35bSopenharmony_ci const timerAPIs: object = {}; 173e484b35bSopenharmony_ci 174e484b35bSopenharmony_ci // Timer APIs polyfill in native 175e484b35bSopenharmony_ci const timer: any = page.requireModule('timer'); 176e484b35bSopenharmony_ci const animation = page.requireModule('animation'); 177e484b35bSopenharmony_ci Object.assign(timerAPIs, { 178e484b35bSopenharmony_ci setTimeout: (...args) => { 179e484b35bSopenharmony_ci const handler = () => { 180e484b35bSopenharmony_ci args[0](...args.slice(2)); 181e484b35bSopenharmony_ci }; 182e484b35bSopenharmony_ci timer.setTimeout(handler, args[1]); 183e484b35bSopenharmony_ci return page.doc.taskCenter.callbackManager.currCallbackId.toString(); 184e484b35bSopenharmony_ci }, 185e484b35bSopenharmony_ci setInterval: (...args) => { 186e484b35bSopenharmony_ci const handler = () => { 187e484b35bSopenharmony_ci args[0](...args.slice(2)); 188e484b35bSopenharmony_ci }; 189e484b35bSopenharmony_ci timer.setInterval(handler, args[1]); 190e484b35bSopenharmony_ci return page.doc.taskCenter.callbackManager.currCallbackId.toString(); 191e484b35bSopenharmony_ci }, 192e484b35bSopenharmony_ci clearTimeout: (n) => { 193e484b35bSopenharmony_ci timer.clearTimeout(n); 194e484b35bSopenharmony_ci page.doc.taskCenter.callbackManager.remove(n); 195e484b35bSopenharmony_ci }, 196e484b35bSopenharmony_ci clearInterval: (n) => { 197e484b35bSopenharmony_ci timer.clearInterval(n); 198e484b35bSopenharmony_ci page.doc.taskCenter.callbackManager.remove(n); 199e484b35bSopenharmony_ci }, 200e484b35bSopenharmony_ci requestAnimationFrame: (...args) => { 201e484b35bSopenharmony_ci const handler = function(timestamp) { 202e484b35bSopenharmony_ci args[0](timestamp, ...args.slice(1)); 203e484b35bSopenharmony_ci }; 204e484b35bSopenharmony_ci animation.requestAnimationFrame(handler); 205e484b35bSopenharmony_ci return page.doc.taskCenter.callbackManager.currCallbackId.toString(); 206e484b35bSopenharmony_ci }, 207e484b35bSopenharmony_ci cancelAnimationFrame: (n) => { 208e484b35bSopenharmony_ci animation.cancelAnimationFrame(n); 209e484b35bSopenharmony_ci } 210e484b35bSopenharmony_ci }); 211e484b35bSopenharmony_ci return timerAPIs; 212e484b35bSopenharmony_ci} 213