1e484b35bSopenharmony_ci/*
2e484b35bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3e484b35bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e484b35bSopenharmony_ci * you may not use this file except in compliance with the License.
5e484b35bSopenharmony_ci * You may obtain a copy of the License at
6e484b35bSopenharmony_ci *
7e484b35bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e484b35bSopenharmony_ci *
9e484b35bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e484b35bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e484b35bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e484b35bSopenharmony_ci * See the License for the specific language governing permissions and
13e484b35bSopenharmony_ci * limitations under the License.
14e484b35bSopenharmony_ci */
15e484b35bSopenharmony_ci
16e484b35bSopenharmony_ciimport { Log } from '../../utils/index';
17e484b35bSopenharmony_ciimport {
18e484b35bSopenharmony_ci  defineFn,
19e484b35bSopenharmony_ci  bootstrap,
20e484b35bSopenharmony_ci  genTimerAPI
21e484b35bSopenharmony_ci} from './bundle';
22e484b35bSopenharmony_ciimport { appMap } from './map';
23e484b35bSopenharmony_ciimport { getPageGlobal } from './helper';
24e484b35bSopenharmony_ciimport { App } from './App';
25e484b35bSopenharmony_ciimport { PageLinkedMap } from './map';
26e484b35bSopenharmony_ciimport Page from '../page/index';
27e484b35bSopenharmony_ciimport { destroy } from '../page/api/index';
28e484b35bSopenharmony_ciimport { compileBundle } from '../page/entry/init';
29e484b35bSopenharmony_ciimport { removePrefix } from '../util/index';
30e484b35bSopenharmony_ciimport { requireModule } from '../page/register';
31e484b35bSopenharmony_ci
32e484b35bSopenharmony_ci/**
33e484b35bSopenharmony_ci * Device information for mediaQuery.
34e484b35bSopenharmony_ci */
35e484b35bSopenharmony_ciexport interface MediaQueryInfo {
36e484b35bSopenharmony_ci  'orientation': string;
37e484b35bSopenharmony_ci  'device-type': string;
38e484b35bSopenharmony_ci  'device-width': string;
39e484b35bSopenharmony_ci  'device-height': string;
40e484b35bSopenharmony_ci  'round-screen': boolean;
41e484b35bSopenharmony_ci  'width': string;
42e484b35bSopenharmony_ci  'height': string;
43e484b35bSopenharmony_ci  'isInit': boolean;
44e484b35bSopenharmony_ci  'resolution': string;
45e484b35bSopenharmony_ci  'aspect-ratio': string;
46e484b35bSopenharmony_ci  'dark-mode': string;
47e484b35bSopenharmony_ci}
48e484b35bSopenharmony_ci
49e484b35bSopenharmony_ci/**
50e484b35bSopenharmony_ci * Information of App.
51e484b35bSopenharmony_ci */
52e484b35bSopenharmony_ciexport interface Options extends MediaQueryInfo {
53e484b35bSopenharmony_ci  'appInstanceId': string;
54e484b35bSopenharmony_ci  'packageName': string;
55e484b35bSopenharmony_ci  'appCreate': boolean;
56e484b35bSopenharmony_ci  'appCode': string | Function;
57e484b35bSopenharmony_ci  'pcPreview': string;
58e484b35bSopenharmony_ci  'resourcesConfiguration': object;
59e484b35bSopenharmony_ci  'i18n': object;
60e484b35bSopenharmony_ci  'language': string;
61e484b35bSopenharmony_ci  'appGlobalData'?: object;
62e484b35bSopenharmony_ci  'bundleUrl': string;
63e484b35bSopenharmony_ci}
64e484b35bSopenharmony_ci
65e484b35bSopenharmony_ci/**
66e484b35bSopenharmony_ci * Framework Services.
67e484b35bSopenharmony_ci */
68e484b35bSopenharmony_ciexport interface Services {
69e484b35bSopenharmony_ci  service: object;
70e484b35bSopenharmony_ci  I18n?: Function;
71e484b35bSopenharmony_ci  dpi?: Function;
72e484b35bSopenharmony_ci}
73e484b35bSopenharmony_ci
74e484b35bSopenharmony_ciinterface ParseOptions {
75e484b35bSopenharmony_ci  $app_define$(...args: any[]): void; // eslint-disable-line camelcase
76e484b35bSopenharmony_ci  $app_bootstrap$(name: string, config: any, _data: any): void; // eslint-disable-line camelcase
77e484b35bSopenharmony_ci  $app_require$(name: string): void; // eslint-disable-line camelcase
78e484b35bSopenharmony_ci}
79e484b35bSopenharmony_ci
80e484b35bSopenharmony_ciconst pageMap: PageLinkedMap = App.pageMap;
81e484b35bSopenharmony_ci
82e484b35bSopenharmony_ci/**
83e484b35bSopenharmony_ci * Create app page, run jsbundle code.
84e484b35bSopenharmony_ci * @param {Page} page
85e484b35bSopenharmony_ci * @param {Options} options
86e484b35bSopenharmony_ci * @param {Object} data
87e484b35bSopenharmony_ci * @param {Services} services
88e484b35bSopenharmony_ci */
89e484b35bSopenharmony_ciexport function appCreate(page: Page, options: Options, data: object, services: Services): void {
90e484b35bSopenharmony_ci  if (!options || !options.appCreate || !options.appCode) {
91e484b35bSopenharmony_ci    return;
92e484b35bSopenharmony_ci  }
93e484b35bSopenharmony_ci  if (options.pcPreview && options.pcPreview === 'enable') {
94e484b35bSopenharmony_ci    global.pcPreview = true;
95e484b35bSopenharmony_ci  }
96e484b35bSopenharmony_ci  const packageName: string = page.packageName;
97e484b35bSopenharmony_ci  const appPage: Page = new Page(options.appInstanceId, options, packageName, data);
98e484b35bSopenharmony_ci  pageMap.unshift(appPage);
99e484b35bSopenharmony_ci  Log.debug(`Create a page with: ${packageName}.`);
100e484b35bSopenharmony_ci  appMap[packageName] = new App(packageName, options.appInstanceId);
101e484b35bSopenharmony_ci  const timerAPIs: object = genTimerAPI(appPage);
102e484b35bSopenharmony_ci  appMap[packageName].setTimer(timerAPIs);
103e484b35bSopenharmony_ci  const code = options.appCode;
104e484b35bSopenharmony_ci  global.__appProto__ = getPageGlobal(packageName);
105e484b35bSopenharmony_ci
106e484b35bSopenharmony_ci  // prepare page env methods
107e484b35bSopenharmony_ci  const appDefine = (...args: any[]): void => defineFn(page, packageName, ...args);
108e484b35bSopenharmony_ci  const appBootstrap = (name: string, config: any, _data: any): void => {
109e484b35bSopenharmony_ci    bootstrap(page, packageName, name, config, _data || data);
110e484b35bSopenharmony_ci    Log.debug(`After create a page(${page.id}).`);
111e484b35bSopenharmony_ci  };
112e484b35bSopenharmony_ci
113e484b35bSopenharmony_ci  const appFunction = () => pageMap.getTop(packageName) || page;
114e484b35bSopenharmony_ci
115e484b35bSopenharmony_ci  // require in top app(instance)
116e484b35bSopenharmony_ci  const appRequireModule = name => requireModule(appFunction, removePrefix(name));
117e484b35bSopenharmony_ci  const parseOptions: ParseOptions = {
118e484b35bSopenharmony_ci    $app_define$: appDefine,
119e484b35bSopenharmony_ci    $app_bootstrap$: appBootstrap,
120e484b35bSopenharmony_ci    $app_require$: appRequireModule
121e484b35bSopenharmony_ci  };
122e484b35bSopenharmony_ci  global.$app_require$ = appRequireModule;
123e484b35bSopenharmony_ci
124e484b35bSopenharmony_ci  // Compile js bundle code and get result.
125e484b35bSopenharmony_ci  if (typeof code === 'function') {
126e484b35bSopenharmony_ci    Log.info('call Function directly when appCreate');
127e484b35bSopenharmony_ci    code.call(global, parseOptions);
128e484b35bSopenharmony_ci  } else {
129e484b35bSopenharmony_ci    // Function with code and use strict mode.
130e484b35bSopenharmony_ci    const functionCode: string = `(function(global){\n\n"use strict";\n\n ${code} \n\n})(this.__appProto__)`;
131e484b35bSopenharmony_ci    compileBundle(functionCode, 'app.js', parseOptions, timerAPIs, services);
132e484b35bSopenharmony_ci  }
133e484b35bSopenharmony_ci}
134e484b35bSopenharmony_ci
135e484b35bSopenharmony_ci/**
136e484b35bSopenharmony_ci * Emit onError event.
137e484b35bSopenharmony_ci * @param {string} packageName
138e484b35bSopenharmony_ci * @param {*} errors
139e484b35bSopenharmony_ci */
140e484b35bSopenharmony_ciexport function appError(packageName: string, errors: any): void {
141e484b35bSopenharmony_ci  Log.debug(`AppError an app with: ${packageName}.`);
142e484b35bSopenharmony_ci  const app: App = appMap[packageName];
143e484b35bSopenharmony_ci  if (!app) {
144e484b35bSopenharmony_ci    Log.debug(`AppError an app error ${packageName}.`);
145e484b35bSopenharmony_ci    return;
146e484b35bSopenharmony_ci  }
147e484b35bSopenharmony_ci  Log.debug(`AppError an app error ${packageName}.`);
148e484b35bSopenharmony_ci  app.emitEvent('hook:onError', errors);
149e484b35bSopenharmony_ci}
150e484b35bSopenharmony_ci
151e484b35bSopenharmony_ci/**
152e484b35bSopenharmony_ci * Emit onShow event.
153e484b35bSopenharmony_ci * @param {string} packageName - Package name.
154e484b35bSopenharmony_ci */
155e484b35bSopenharmony_ciexport function appShow(packageName: string): void {
156e484b35bSopenharmony_ci  Log.debug(`Show an app with: ${packageName}.`);
157e484b35bSopenharmony_ci  const app: App = appMap[packageName];
158e484b35bSopenharmony_ci  if (!app) {
159e484b35bSopenharmony_ci    Log.debug(`Show an app error ${packageName}.`);
160e484b35bSopenharmony_ci    return;
161e484b35bSopenharmony_ci  }
162e484b35bSopenharmony_ci  app.emitEvent('hook:onShow');
163e484b35bSopenharmony_ci}
164e484b35bSopenharmony_ci
165e484b35bSopenharmony_ci/**
166e484b35bSopenharmony_ci * Emit onHide event.
167e484b35bSopenharmony_ci * @param {string} packageName - Package name.
168e484b35bSopenharmony_ci */
169e484b35bSopenharmony_ciexport function appHide(packageName: string): void {
170e484b35bSopenharmony_ci  Log.debug(`Hide an app with: ${packageName}.`);
171e484b35bSopenharmony_ci  const app: App = appMap[packageName];
172e484b35bSopenharmony_ci  if (!app) {
173e484b35bSopenharmony_ci    Log.debug(`Hide an app error ${packageName}.`);
174e484b35bSopenharmony_ci    return;
175e484b35bSopenharmony_ci  }
176e484b35bSopenharmony_ci  app.emitEvent('hook:onHide');
177e484b35bSopenharmony_ci}
178e484b35bSopenharmony_ci
179e484b35bSopenharmony_ci/**
180e484b35bSopenharmony_ci * Emit onDestroy event.
181e484b35bSopenharmony_ci * @param {string} packageName - Package name.
182e484b35bSopenharmony_ci */
183e484b35bSopenharmony_ciexport function appDestroy(packageName: string): void {
184e484b35bSopenharmony_ci  Log.debug(`Destroy an app with: ${packageName}.`);
185e484b35bSopenharmony_ci  const app: App = appMap[packageName];
186e484b35bSopenharmony_ci  if (!app) {
187e484b35bSopenharmony_ci    Log.error(`Destroy an app error ${packageName}.`);
188e484b35bSopenharmony_ci    return;
189e484b35bSopenharmony_ci  }
190e484b35bSopenharmony_ci  app.emitEvent('hook:onDestroy');
191e484b35bSopenharmony_ci  app.deleteGlobalKeys();
192e484b35bSopenharmony_ci  delete appMap[packageName];
193e484b35bSopenharmony_ci  const appPage: Page = pageMap[app.appInstanceId];
194e484b35bSopenharmony_ci  if (appPage) {
195e484b35bSopenharmony_ci    if (appPage.doc.taskCenter.callbackIsEmpty()) {
196e484b35bSopenharmony_ci      appPage.callTasks([{
197e484b35bSopenharmony_ci        module: 'internal.jsResult',
198e484b35bSopenharmony_ci        method: 'appDestroyFinish',
199e484b35bSopenharmony_ci        args: []
200e484b35bSopenharmony_ci      }]);
201e484b35bSopenharmony_ci      destroy(appPage);
202e484b35bSopenharmony_ci      pageMap.remove(appPage);
203e484b35bSopenharmony_ci    } else {
204e484b35bSopenharmony_ci      appPage.destroyed = true;
205e484b35bSopenharmony_ci    }
206e484b35bSopenharmony_ci  }
207e484b35bSopenharmony_ci}
208e484b35bSopenharmony_ci
209e484b35bSopenharmony_ci/**
210e484b35bSopenharmony_ci * Init language resource.
211e484b35bSopenharmony_ci * @param {*} i18nData
212e484b35bSopenharmony_ci */
213e484b35bSopenharmony_ciexport function updateLocale(i18nData: any): void {
214e484b35bSopenharmony_ci  if (i18nData) {
215e484b35bSopenharmony_ci    global.aceapp._i18n_data_ = { messages: i18nData.resources };
216e484b35bSopenharmony_ci  } else {
217e484b35bSopenharmony_ci    global.aceapp._i18n_data_ = null;
218e484b35bSopenharmony_ci  }
219e484b35bSopenharmony_ci}
220e484b35bSopenharmony_ci
221e484b35bSopenharmony_ci/**
222e484b35bSopenharmony_ci * Init image dpi.
223e484b35bSopenharmony_ci * @param {Object} dpiData
224e484b35bSopenharmony_ci */
225e484b35bSopenharmony_ciexport function updateDpi(dpiData: object): void {
226e484b35bSopenharmony_ci  if (dpiData) {
227e484b35bSopenharmony_ci    global.aceapp._dpi_data_ = { images: dpiData };
228e484b35bSopenharmony_ci  } else {
229e484b35bSopenharmony_ci    global.aceapp._dpi_data_ = null;
230e484b35bSopenharmony_ci  }
231e484b35bSopenharmony_ci}
232