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/**
21e484b35bSopenharmony_ci * @fileOverview
22e484b35bSopenharmony_ci * page controls from native
23e484b35bSopenharmony_ci *
24e484b35bSopenharmony_ci * - fire event
25e484b35bSopenharmony_ci * - callback
26e484b35bSopenharmony_ci * - refresh
27e484b35bSopenharmony_ci * - destroy
28e484b35bSopenharmony_ci *
29e484b35bSopenharmony_ci * corresponded with the API of page manager (framework.js)
30e484b35bSopenharmony_ci */
31e484b35bSopenharmony_ci
32e484b35bSopenharmony_ciimport {
33e484b35bSopenharmony_ci  typof,
34e484b35bSopenharmony_ci  Log
35e484b35bSopenharmony_ci} from '../../../utils/index';
36e484b35bSopenharmony_ciimport Page from '../index';
37e484b35bSopenharmony_ciimport Element from '../../../vdom/Element';
38e484b35bSopenharmony_ci
39e484b35bSopenharmony_ci/**
40e484b35bSopenharmony_ci * Destroy a page.
41e484b35bSopenharmony_ci * @param {Page} page
42e484b35bSopenharmony_ci */
43e484b35bSopenharmony_ciexport function destroy(page: Page): void {
44e484b35bSopenharmony_ci  Log.debug(`Destroy a page(${page.id}).`);
45e484b35bSopenharmony_ci
46e484b35bSopenharmony_ci  if (page.vm) {
47e484b35bSopenharmony_ci    page.vm.destroy();
48e484b35bSopenharmony_ci  }
49e484b35bSopenharmony_ci
50e484b35bSopenharmony_ci  page.id = null;
51e484b35bSopenharmony_ci  page.options = null;
52e484b35bSopenharmony_ci  page.vm = null;
53e484b35bSopenharmony_ci  page.doc.taskCenter.destroyCallback();
54e484b35bSopenharmony_ci  page.doc.destroy();
55e484b35bSopenharmony_ci  page.doc = null;
56e484b35bSopenharmony_ci  page.customComponentMap = null;
57e484b35bSopenharmony_ci  page.commonModules = null;
58e484b35bSopenharmony_ci}
59e484b35bSopenharmony_ci
60e484b35bSopenharmony_ci/**
61e484b35bSopenharmony_ci * Fire an event to update domChanges of a page.
62e484b35bSopenharmony_ci * @param {Page} page
63e484b35bSopenharmony_ci * @param {*} ref
64e484b35bSopenharmony_ci * @param {*} type
65e484b35bSopenharmony_ci * @param {Object} e
66e484b35bSopenharmony_ci * @param {Object} domChanges
67e484b35bSopenharmony_ci * @param {*[] | null} args
68e484b35bSopenharmony_ci * @return any
69e484b35bSopenharmony_ci */
70e484b35bSopenharmony_ciexport function fireEvent(page: Page, ref?: any, type?: any, e?: object, domChanges?: boolean, ...args: any[] | null): any {
71e484b35bSopenharmony_ci  Log.debug(`Fire a '${type}' event on an element(${ref}) in page(${page.id}), args = ${JSON.stringify(args)}.`);
72e484b35bSopenharmony_ci  if (Array.isArray(ref)) {
73e484b35bSopenharmony_ci    ref.some((ref) => {
74e484b35bSopenharmony_ci      return fireEvent(page, ref, type, e) !== false;
75e484b35bSopenharmony_ci    });
76e484b35bSopenharmony_ci    return;
77e484b35bSopenharmony_ci  }
78e484b35bSopenharmony_ci  const el: Element = page.doc.getRef(ref);
79e484b35bSopenharmony_ci  if (el) {
80e484b35bSopenharmony_ci    const options: {params?: any} = {};
81e484b35bSopenharmony_ci    if (args) {
82e484b35bSopenharmony_ci      options.params = [...args];
83e484b35bSopenharmony_ci    }
84e484b35bSopenharmony_ci    const result: any = page.doc.fireEvent(el, type, e, domChanges, options);
85e484b35bSopenharmony_ci    page.differ.flush();
86e484b35bSopenharmony_ci    page.doc.taskCenter.send('dom', { action: 'updateFinish' }, []);
87e484b35bSopenharmony_ci    return result;
88e484b35bSopenharmony_ci  }
89e484b35bSopenharmony_ci  return new Error(`Invalid element reference '${ref}'.`);
90e484b35bSopenharmony_ci}
91e484b35bSopenharmony_ci
92e484b35bSopenharmony_ci/**
93e484b35bSopenharmony_ci * Update page content on a callback.
94e484b35bSopenharmony_ci * @param {Page}  page
95e484b35bSopenharmony_ci * @param {number}  callbackId
96e484b35bSopenharmony_ci * @param {Object} data
97e484b35bSopenharmony_ci * @param {boolean} ifKeepAlive
98e484b35bSopenharmony_ci * @return {*}
99e484b35bSopenharmony_ci */
100e484b35bSopenharmony_ciexport function callback(page: Page, callbackId?: number, data?: object, ifKeepAlive?: boolean): any {
101e484b35bSopenharmony_ci  Log.debug(`runtime/main/page/api/misc.js: Invoke a callback(${callbackId}) with `
102e484b35bSopenharmony_ci    + `${JSON.stringify(data)} in page(${page.id}) ifKeepAlive = ${ifKeepAlive}.`);
103e484b35bSopenharmony_ci  const result: any = page.doc.taskCenter.consumeCallback(callbackId, data, ifKeepAlive);
104e484b35bSopenharmony_ci  updateActions(page);
105e484b35bSopenharmony_ci  page.doc.taskCenter.send('dom', { action: 'updateFinish' }, []);
106e484b35bSopenharmony_ci  return result;
107e484b35bSopenharmony_ci}
108e484b35bSopenharmony_ci
109e484b35bSopenharmony_ci/**
110e484b35bSopenharmony_ci * Fire an event to update domChanges of a page.
111e484b35bSopenharmony_ci * @param {Page} page - page.
112e484b35bSopenharmony_ci * @param {*} - correspond to fireEvent args.
113e484b35bSopenharmony_ci * @return {*}
114e484b35bSopenharmony_ci */
115e484b35bSopenharmony_ciexport function fireEventSync(page: Page, ...args: any[]): any {
116e484b35bSopenharmony_ci  const result: any = fireEvent(page, ...args);
117e484b35bSopenharmony_ci  if (page && page.callTasks) {
118e484b35bSopenharmony_ci    let callbackId = '';
119e484b35bSopenharmony_ci    for (let i = 0; i < args.length; i++) {
120e484b35bSopenharmony_ci      if (args[i]._callbackId !== undefined) {
121e484b35bSopenharmony_ci        callbackId = args[i]._callbackId;
122e484b35bSopenharmony_ci        break;
123e484b35bSopenharmony_ci      }
124e484b35bSopenharmony_ci    }
125e484b35bSopenharmony_ci    let resultStr = result || {};
126e484b35bSopenharmony_ci    if (Array.isArray(resultStr)) {
127e484b35bSopenharmony_ci      resultStr = result[0] || {};
128e484b35bSopenharmony_ci    }
129e484b35bSopenharmony_ci    if (resultStr.constructor !== String) {
130e484b35bSopenharmony_ci      resultStr = JSON.stringify(resultStr);
131e484b35bSopenharmony_ci    }
132e484b35bSopenharmony_ci    return page.callTasks([{
133e484b35bSopenharmony_ci      module: 'internal.jsResult',
134e484b35bSopenharmony_ci      method: 'callbackNative',
135e484b35bSopenharmony_ci      args: [callbackId, resultStr]
136e484b35bSopenharmony_ci    }]);
137e484b35bSopenharmony_ci  }
138e484b35bSopenharmony_ci}
139e484b35bSopenharmony_ci
140e484b35bSopenharmony_ci/**
141e484b35bSopenharmony_ci * Collect all virtual-DOM mutations together and send them to renderer.
142e484b35bSopenharmony_ci * @param {Page} page
143e484b35bSopenharmony_ci */
144e484b35bSopenharmony_ciexport function updateActions(page: Page): void {
145e484b35bSopenharmony_ci  page.differ.flush();
146e484b35bSopenharmony_ci}
147e484b35bSopenharmony_ci
148e484b35bSopenharmony_ci/**
149e484b35bSopenharmony_ci * Call all tasks from a page to renderer (native).
150e484b35bSopenharmony_ci * @param {object} page
151e484b35bSopenharmony_ci * @param {*} tasks
152e484b35bSopenharmony_ci * @return {*}
153e484b35bSopenharmony_ci */
154e484b35bSopenharmony_ciexport function callTasks(page: Page, tasks: any): any {
155e484b35bSopenharmony_ci  let result: any;
156e484b35bSopenharmony_ci  if (typof(tasks) !== 'array') {
157e484b35bSopenharmony_ci    tasks = [tasks];
158e484b35bSopenharmony_ci  }
159e484b35bSopenharmony_ci  tasks.forEach(task => {
160e484b35bSopenharmony_ci    result = page.doc.taskCenter.send(
161e484b35bSopenharmony_ci      'module',
162e484b35bSopenharmony_ci      {
163e484b35bSopenharmony_ci        module: task.module,
164e484b35bSopenharmony_ci        method: task.method
165e484b35bSopenharmony_ci      },
166e484b35bSopenharmony_ci      task.args
167e484b35bSopenharmony_ci    );
168e484b35bSopenharmony_ci  });
169e484b35bSopenharmony_ci  return result;
170e484b35bSopenharmony_ci}
171