• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { interceptCallback } from '../main/manage/event/callbackIntercept';
17import Element from './Element';
18
19/**
20 * This factory class create native components classes, like div, image, text, etc...<br>
21 * Each class is extends from Element, and saved in static property nativeElementClassMap.
22 */
23class NativeElementClassFactory {
24  /**
25   * Map for native element class
26   * @type {Map}
27   * @static
28   */
29  public static nativeElementClassMap: Map<string, any> = new Map();
30
31  /**
32   * Create a native element class form native, and saved in nativeElementClassMap.
33   * @param {string} tagName - Name of element class.
34   * @param {Function[]} methods - Prototype methods of element class.
35   * @static
36   */
37  public static createNativeElementClass(tagName: string, methods: any[]) {
38    // Skip when no special component methods.
39    if (!methods || !methods.length) {
40      return;
41    }
42
43    class NativeElement extends Element {
44      constructor(props) {
45        super(tagName, props, true);
46      }
47    }
48
49    // Add methods to prototype.
50    methods.forEach(methodName => {
51      Object.defineProperty(NativeElement.prototype, methodName, {
52        configurable: true,
53        enumerable: true,
54        get: function moduleGetter() {
55          return (...args: any) => {
56            const taskCenter = this.getTaskCenter(this.docId);
57            if (taskCenter) {
58              // support aceapp callback style
59              args = interceptCallback(args);
60              if (methodName === 'scrollTo' && args[0].id) {
61                args[0].id = findEl(this, args[0].id);
62              }
63              const ret = taskCenter.send('component', {
64                ref: this.ref,
65                component: tagName,
66                method: methodName
67              }, args);
68              return ret;
69            }
70          };
71        }
72      });
73    });
74
75    // Add to element type map.
76    this.nativeElementClassMap.set(tagName, NativeElement);
77  }
78}
79
80function findEl(parent, id) {
81  if (!parent) {
82    return;
83  }
84  if (parent.id === id) {
85    return parent.ref;
86  }
87  let ans;
88  const children = parent.children;
89  if (children) {
90    for (const child in children) {
91      ans = ans || findEl(children[child], id);
92    }
93  }
94  return ans;
95}
96
97export default NativeElementClassFactory;
98