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