• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2024 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
16interface LayoutConstraint {
17  maxSize: Size;
18  minSize: Size;
19  percentReference: Size;
20}
21
22class FrameNode {
23  public _nodeId: number;
24  protected _commonAttribute: ArkComponent;
25  protected _commonEvent: UICommonEvent;
26  protected _childList: Map<number, FrameNode>;
27  protected _nativeRef: NativeStrongRef | NativeWeakRef;
28  protected renderNode_: RenderNode;
29  protected baseNode_: BaseNode;
30  protected uiContext_: UIContext | undefined | null;
31  protected nodePtr_: NodePtr;
32  protected instanceId_?: number;
33  private nodeAdapterRef_?: NodeAdapter;
34  constructor(uiContext: UIContext, type: string, options?: object) {
35    if (uiContext === undefined) {
36      throw Error('Node constructor error, param uiContext error');
37    } else {
38      if (!(typeof uiContext === "object") || !("instanceId_" in uiContext)) {
39        throw Error(
40          'Node constructor error, param uiContext is invalid'
41        );
42      }
43    }
44    this.instanceId_ = uiContext.instanceId_;
45    this.uiContext_ = uiContext;
46    this._nodeId = -1;
47    this._childList = new Map();
48    if (type === 'BuilderRootFrameNode') {
49      this.renderNode_ = new RenderNode(type);
50      this.renderNode_.setFrameNode(new WeakRef(this));
51      return;
52    }
53    if (type === 'ProxyFrameNode') {
54      return;
55    }
56    let result;
57    __JSScopeUtil__.syncInstanceId(this.instanceId_);
58    if (type === undefined || type === "CustomFrameNode") {
59      this.renderNode_ = new RenderNode('CustomFrameNode');
60      result = getUINativeModule().frameNode.createFrameNode(this);
61    } else {
62      result = getUINativeModule().frameNode.createTypedFrameNode(this, type, options);
63    }
64    __JSScopeUtil__.restoreInstanceId();
65    this._nativeRef = result?.nativeStrongRef;
66    this._nodeId = result?.nodeId;
67    this.nodePtr_ = this._nativeRef?.getNativeHandle();
68    this.renderNode_?.setNodePtr(result?.nativeStrongRef);
69    this.renderNode_?.setFrameNode(new WeakRef(this));
70    if (result === undefined || this._nodeId === -1) {
71      return;
72    }
73    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(this._nodeId, new WeakRef(this));
74    FrameNodeFinalizationRegisterProxy.register(this, this._nodeId);
75
76  }
77  invalidate() {
78    if (this.nodePtr_ === undefined || this.nodePtr_ === null) {
79      return;
80    }
81    getUINativeModule().frameNode.invalidate(this.nodePtr_);
82  }
83  getType(): string {
84    return 'CustomFrameNode';
85  }
86  setRenderNode(nativeRef: NativeStrongRef): void {
87    this.renderNode_?.setNodePtr(nativeRef);
88  }
89  getRenderNode(): RenderNode | null {
90    if (
91      this.renderNode_ !== undefined &&
92      this.renderNode_ !== null &&
93      this.renderNode_.getNodePtr() !== null
94    ) {
95      return this.renderNode_;
96    }
97    return null;
98  }
99  setNodePtr(nativeRef: NativeStrongRef | NativeWeakRef, nodePtr: NodePtr): void {
100    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.delete(this._nodeId);
101    this._nativeRef = nativeRef;
102    this.nodePtr_ = nodePtr ? nodePtr : this._nativeRef?.getNativeHandle();
103    this._nodeId = getUINativeModule().frameNode.getIdByNodePtr(this.nodePtr_);
104    if (this._nodeId === -1) {
105      return;
106    }
107    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(this._nodeId, new WeakRef(this));
108    FrameNodeFinalizationRegisterProxy.register(this, this._nodeId);
109  }
110  resetNodePtr(): void {
111    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.delete(this._nodeId);
112    this._nodeId = -1;
113    this._nativeRef = null;
114    this.nodePtr_ = null;
115    this.renderNode_?.resetNodePtr();
116  }
117  setBaseNode(baseNode: BaseNode | null): void {
118    this.baseNode_ = baseNode;
119    this.renderNode_?.setBaseNode(baseNode);
120  }
121  setAdapterRef(adapter: NodeAdapter | undefined): void {
122    this.nodeAdapterRef_ = adapter;
123  }
124  getNodePtr(): NodePtr | null {
125    return this.nodePtr_;
126  }
127  dispose(): void {
128    this.renderNode_?.dispose();
129    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.delete(this._nodeId);
130    this._nodeId = -1;
131    this._nativeRef = null;
132    this.nodePtr_ = null;
133  }
134
135  static disposeTreeRecursively(node: FrameNode | null): void {
136    if (node === null) {
137      return;
138    }
139    let child = node.getFirstChildWithoutExpand();
140    FrameNode.disposeTreeRecursively(child);
141    let sibling = node.getNextSiblingWithoutExpand();
142    FrameNode.disposeTreeRecursively(sibling);
143    node.dispose();
144  }
145
146  disposeTree(): void {
147    let parent = this.getParent();
148    if (parent?.getNodeType() === "NodeContainer") {
149      getUINativeModule().nodeContainer.clean(parent?.getNodePtr());
150    } else {
151      parent?.removeChild(this);
152    }
153    FrameNode.disposeTreeRecursively(this);
154  }
155
156  checkType(): void {
157    if (!this.isModifiable()) {
158      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
159    }
160  }
161  isModifiable(): boolean {
162    return this._nativeRef !== undefined && this._nativeRef !== null;
163  }
164
165  convertToFrameNode(nodePtr: NodePtr, nodeId: number = -1): FrameNode | null {
166    if (nodeId === -1) {
167      nodeId = getUINativeModule().frameNode.getIdByNodePtr(nodePtr);
168    }
169    if (nodeId !== -1 && !getUINativeModule().frameNode.isModifiable(nodePtr)) {
170      let frameNode = new ProxyFrameNode(this.uiContext_);
171      let node = getUINativeModule().nativeUtils.createNativeWeakRef(nodePtr);
172      frameNode.setNodePtr(node);
173      frameNode._nodeId = nodeId;
174      FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(frameNode._nodeId, new WeakRef(frameNode));
175      FrameNodeFinalizationRegisterProxy.register(frameNode, frameNode._nodeId);
176      return frameNode;
177    }
178    return null;
179  }
180
181  checkValid(node?: FrameNode): boolean {
182    return true;
183  }
184
185  appendChild(node: FrameNode): void {
186    if (node === undefined || node === null) {
187      return;
188    }
189    if (node.getType() === 'ProxyFrameNode' || !this.checkValid(node)) {
190      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
191    }
192    __JSScopeUtil__.syncInstanceId(this.instanceId_);
193    let flag = getUINativeModule().frameNode.appendChild(this.nodePtr_, node.nodePtr_);
194    __JSScopeUtil__.restoreInstanceId();
195    if (!flag) {
196      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
197    }
198    this._childList.set(node._nodeId, node);
199  }
200
201  addComponentContent(content: ComponentContent): void {
202    if (content === undefined || content === null || content.getNodePtr() === null || content.getNodePtr() == undefined) {
203      return;
204    }
205    if (!this.checkValid() || !this.isModifiable()) {
206      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
207    }
208    __JSScopeUtil__.syncInstanceId(this.instanceId_);
209    let flag = getUINativeModule().frameNode.appendChild(this.nodePtr_, content.getNodeWithoutProxy());
210    __JSScopeUtil__.restoreInstanceId();
211    if (!flag) {
212      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
213    } else {
214      content.setAttachedParent(new WeakRef<FrameNode>(this));
215    }
216  }
217
218  removeComponentContent(content: ComponentContent): void {
219    if (content === undefined || content === null || content.getNodePtr() === null || content.getNodePtr() === undefined) {
220      return;
221    }
222    __JSScopeUtil__.syncInstanceId(this.instanceId_);
223    getUINativeModule().frameNode.removeChild(this.nodePtr_, content.getNodePtr());
224    content.setAttachedParent(undefined);
225    __JSScopeUtil__.restoreInstanceId();
226  }
227
228  insertChildAfter(child: FrameNode, sibling: FrameNode): void {
229    if (child === undefined || child === null) {
230      return;
231    }
232    if (child.getType() === 'ProxyFrameNode' || !this.checkValid(child)) {
233      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
234    }
235    let flag = true;
236    __JSScopeUtil__.syncInstanceId(this.instanceId_);
237    if (sibling === undefined || sibling === null) {
238      flag = getUINativeModule().frameNode.insertChildAfter(this.nodePtr_, child.nodePtr_, null);
239    } else {
240      flag = getUINativeModule().frameNode.insertChildAfter(this.nodePtr_, child.nodePtr_, sibling.getNodePtr());
241    }
242    __JSScopeUtil__.restoreInstanceId();
243    if (!flag) {
244      throw { message: 'The FrameNode is not modifiable.', code: 100021 };
245    }
246    this._childList.set(child._nodeId, child);
247  }
248
249  removeChild(node: FrameNode): void {
250    if (node === undefined || node === null) {
251      return;
252    }
253    __JSScopeUtil__.syncInstanceId(this.instanceId_);
254    getUINativeModule().frameNode.removeChild(this.nodePtr_, node.nodePtr_);
255    __JSScopeUtil__.restoreInstanceId();
256    this._childList.delete(node._nodeId);
257  }
258
259  clearChildren(): void {
260    __JSScopeUtil__.syncInstanceId(this.instanceId_);
261    getUINativeModule().frameNode.clearChildren(this.nodePtr_);
262    __JSScopeUtil__.restoreInstanceId();
263    this._childList.clear();
264  }
265  getChild(index: number, isExpanded?: boolean): FrameNode | null {
266    const result = getUINativeModule().frameNode.getChild(this.getNodePtr(), index, isExpanded);
267    const nodeId = result?.nodeId;
268    if (nodeId === undefined || nodeId === -1) {
269      return null;
270    }
271    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
272      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
273      return frameNode === undefined ? null : frameNode;
274    }
275    return this.convertToFrameNode(result.nodePtr, result.nodeId);
276  }
277
278  getFirstChild(isExpanded?: boolean): FrameNode | null {
279    const result = getUINativeModule().frameNode.getFirst(this.getNodePtr(), isExpanded);
280    const nodeId = result?.nodeId;
281    if (nodeId === undefined || nodeId === -1) {
282      return null;
283    }
284    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
285      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
286      return frameNode === undefined ? null : frameNode;
287    }
288    return this.convertToFrameNode(result.nodePtr, result.nodeId);
289  }
290
291  getFirstChildWithoutExpand(): FrameNode | null {
292    const result = getUINativeModule().frameNode.getFirst(this.getNodePtr(), false);
293    const nodeId = result?.nodeId;
294    if (nodeId === undefined || nodeId === -1) {
295      return null;
296    }
297    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
298      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
299      return frameNode === undefined ? null : frameNode;
300    }
301    return this.convertToFrameNode(result.nodePtr, result.nodeId);
302  }
303
304  getNextSibling(isExpanded?: boolean): FrameNode | null {
305    const result = getUINativeModule().frameNode.getNextSibling(this.getNodePtr(), isExpanded);
306    const nodeId = result?.nodeId;
307    if (nodeId === undefined || nodeId === -1) {
308      return null;
309    }
310    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
311      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
312      return frameNode === undefined ? null : frameNode;
313    }
314    return this.convertToFrameNode(result.nodePtr, result.nodeId);
315  }
316
317  getNextSiblingWithoutExpand(): FrameNode | null {
318    const result = getUINativeModule().frameNode.getNextSibling(this.getNodePtr(), false);
319    const nodeId = result?.nodeId;
320    if (nodeId === undefined || nodeId === -1) {
321      return null;
322    }
323    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
324      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
325      return frameNode === undefined ? null : frameNode;
326    }
327    return this.convertToFrameNode(result.nodePtr, result.nodeId);
328  }
329
330  getPreviousSibling(isExpanded?: boolean): FrameNode | null {
331    const result = getUINativeModule().frameNode.getPreviousSibling(this.getNodePtr(), isExpanded);
332    const nodeId = result?.nodeId;
333    if (nodeId === undefined || nodeId === -1) {
334      return null;
335    }
336    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
337      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
338      return frameNode === undefined ? null : frameNode;
339    }
340    return this.convertToFrameNode(result.nodePtr, result.nodeId);
341  }
342
343  getParent(): FrameNode | null {
344    const result = getUINativeModule().frameNode.getParent(this.getNodePtr());
345    const nodeId = result?.nodeId;
346    if (nodeId === undefined || nodeId === -1) {
347      return null;
348    }
349    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
350      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
351      return frameNode === undefined ? null : frameNode;
352    }
353    return this.convertToFrameNode(result.nodePtr, result.nodeId);
354  }
355
356  getChildrenCount(isExpanded?: boolean): number {
357    return getUINativeModule().frameNode.getChildrenCount(this.nodePtr_, isExpanded);
358  }
359
360  getPositionToParent(): Position {
361    const position = getUINativeModule().frameNode.getPositionToParent(this.getNodePtr());
362    return { x: position[0], y: position[1] };
363  }
364
365  getPositionToScreen(): Position {
366    const position = getUINativeModule().frameNode.getPositionToScreen(this.getNodePtr());
367    return { x: position[0], y: position[1] };
368  }
369
370  getPositionToWindow(): Position {
371    const position = getUINativeModule().frameNode.getPositionToWindow(this.getNodePtr());
372    return { x: position[0], y: position[1] };
373  }
374
375  getPositionToParentWithTransform(): Position {
376    const position = getUINativeModule().frameNode.getPositionToParentWithTransform(this.getNodePtr());
377    return { x: position[0], y: position[1] };
378  }
379
380  getPositionToScreenWithTransform(): Position {
381    const position = getUINativeModule().frameNode.getPositionToScreenWithTransform(this.getNodePtr());
382    return { x: position[0], y: position[1] };
383  }
384
385  getPositionToWindowWithTransform(): Position {
386    const position = getUINativeModule().frameNode.getPositionToWindowWithTransform(this.getNodePtr());
387    return { x: position[0], y: position[1] };
388  }
389
390  getMeasuredSize(): Size {
391    const size = getUINativeModule().frameNode.getMeasuredSize(this.getNodePtr());
392    return { width: size[0], height: size[1] };
393  }
394
395  getLayoutPosition(): Position {
396    const position = getUINativeModule().frameNode.getLayoutPosition(this.getNodePtr());
397    return { x: position[0], y: position[1] };
398  }
399
400  getUserConfigBorderWidth(): EdgesT<LengthMetrics> {
401    const borderWidth = getUINativeModule().frameNode.getConfigBorderWidth(this.getNodePtr());
402    return {
403      top: new LengthMetrics(borderWidth[0], borderWidth[1]),
404      right: new LengthMetrics(borderWidth[2], borderWidth[3]),
405      bottom: new LengthMetrics(borderWidth[4], borderWidth[5]),
406      left: new LengthMetrics(borderWidth[6], borderWidth[7])
407    };
408  }
409
410  getUserConfigPadding(): EdgesT<LengthMetrics> {
411    const borderWidth = getUINativeModule().frameNode.getConfigPadding(this.getNodePtr());
412    return {
413      top: new LengthMetrics(borderWidth[0], borderWidth[1]),
414      right: new LengthMetrics(borderWidth[2], borderWidth[3]),
415      bottom: new LengthMetrics(borderWidth[4], borderWidth[5]),
416      left: new LengthMetrics(borderWidth[6], borderWidth[7])
417    };
418  }
419
420  getUserConfigMargin(): EdgesT<LengthMetrics> {
421    const margin = getUINativeModule().frameNode.getConfigMargin(this.getNodePtr());
422    return {
423      top: new LengthMetrics(margin[0], margin[1]),
424      right: new LengthMetrics(margin[2], margin[3]),
425      bottom: new LengthMetrics(margin[4], margin[5]),
426      left: new LengthMetrics(margin[6], margin[7])
427    };
428  }
429
430  getUserConfigSize(): SizeT<LengthMetrics> {
431    const size = getUINativeModule().frameNode.getConfigSize(this.getNodePtr());
432    return {
433      width: new LengthMetrics(size[0], size[1]),
434      height: new LengthMetrics(size[2], size[3])
435    };
436  }
437
438  getId(): string {
439    return getUINativeModule().frameNode.getId(this.getNodePtr());
440  }
441
442  getUniqueId(): number {
443    return getUINativeModule().frameNode.getIdByNodePtr(this.getNodePtr());
444  }
445
446  getNodeType(): string {
447    return getUINativeModule().frameNode.getNodeType(this.getNodePtr());
448  }
449
450  getOpacity(): number {
451    return getUINativeModule().frameNode.getOpacity(this.getNodePtr());
452  }
453
454  isVisible(): boolean {
455    return getUINativeModule().frameNode.isVisible(this.getNodePtr());
456  }
457
458  isClipToFrame(): boolean {
459    return getUINativeModule().frameNode.isClipToFrame(this.getNodePtr());
460  }
461
462  isAttached(): boolean {
463    return getUINativeModule().frameNode.isAttached(this.getNodePtr());
464  }
465
466  getInspectorInfo(): Object {
467    const inspectorInfoStr = getUINativeModule().frameNode.getInspectorInfo(this.getNodePtr());
468    const inspectorInfo = JSON.parse(inspectorInfoStr);
469    return inspectorInfo;
470  }
471
472  getCustomProperty(key: string): Object | undefined {
473    if (key === undefined) {
474      return undefined;
475    }
476    let value = __getCustomProperty__(this._nodeId, key);
477    if (value === undefined) {
478      const valueStr = getUINativeModule().frameNode.getCustomPropertyCapiByKey(this.getNodePtr(), key);
479      value = valueStr === undefined ? undefined : valueStr;
480    }
481    return value;
482  }
483
484  setMeasuredSize(size: Size): void {
485    getUINativeModule().frameNode.setMeasuredSize(this.getNodePtr(), Math.max(size.width, 0),
486      Math.max(size.height, 0));
487  }
488
489  setLayoutPosition(position: Position): void {
490    getUINativeModule().frameNode.setLayoutPosition(this.getNodePtr(), position.x, position.y);
491  }
492
493  measure(constraint: LayoutConstraint): void {
494    const minSize: Size = constraint.minSize;
495    const maxSize: Size = constraint.maxSize;
496    const percentReference: Size = constraint.percentReference;
497    __JSScopeUtil__.syncInstanceId(this.instanceId_);
498    getUINativeModule().frameNode.measureNode(this.getNodePtr(), minSize.width, minSize.height, maxSize.width,
499      maxSize.height, percentReference.width, percentReference.height);
500    __JSScopeUtil__.restoreInstanceId();
501  }
502
503  layout(position: Position): void {
504    getUINativeModule().frameNode.layoutNode(this.getNodePtr(), position.x, position.y);
505  }
506
507  setNeedsLayout(): void {
508    getUINativeModule().frameNode.setNeedsLayout(this.getNodePtr());
509  }
510
511  get commonAttribute(): ArkComponent {
512    if (this._commonAttribute === undefined) {
513      this._commonAttribute = new ArkComponent(this.nodePtr_, ModifierType.FRAME_NODE);
514      this._commonAttribute.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_);
515    }
516    this._commonAttribute.setNodePtr(this.nodePtr_);
517    return this._commonAttribute;
518  }
519
520  get commonEvent(): UICommonEvent {
521    let node = this.getNodePtr();
522    if (this._commonEvent === undefined) {
523      this._commonEvent = new UICommonEvent(node);
524    }
525    this._commonEvent.setNodePtr(node);
526    this._commonEvent.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_);
527    return this._commonEvent;
528  }
529  updateInstance(uiContext: UIContext): void {
530    this.uiContext_ = uiContext;
531    this.instanceId_ = uiContext.instanceId_;
532  }
533}
534
535class ImmutableFrameNode extends FrameNode {
536  isModifiable(): boolean {
537    return false;
538  }
539  invalidate() {
540    return;
541  }
542  appendChild(node: FrameNode): void {
543    throw { message: 'The FrameNode is not modifiable.', code: 100021 };
544  }
545  insertChildAfter(child: FrameNode, sibling: FrameNode): void {
546    throw { message: 'The FrameNode is not modifiable.', code: 100021 };
547  }
548  removeChild(node: FrameNode): void {
549    throw { message: 'The FrameNode is not modifiable.', code: 100021 };
550  }
551  clearChildren(): void {
552    throw { message: 'The FrameNode is not modifiable.', code: 100021 };
553  }
554  get commonAttribute(): ArkComponent {
555    if (this._commonAttribute === undefined) {
556      this._commonAttribute = new ArkComponent(undefined, ModifierType.FRAME_NODE);
557    }
558    this._commonAttribute.setNodePtr(undefined);
559    return this._commonAttribute;
560  }
561}
562
563class BuilderRootFrameNode extends ImmutableFrameNode {
564  constructor(uiContext: UIContext, type: string = 'BuilderRootFrameNode') {
565    super(uiContext, type);
566  }
567  getType(): string {
568    return 'BuilderRootFrameNode';
569  }
570}
571
572class ProxyFrameNode extends ImmutableFrameNode {
573  _nativeRef: NativeWeakRef;
574
575  constructor(uiContext: UIContext, type: string = 'ProxyFrameNode') {
576    super(uiContext, type);
577  }
578
579  setNodePtr(nativeRef: NativeWeakRef) {
580    this._nativeRef = nativeRef;
581    this.nodePtr_ = this._nativeRef.getNativeHandle();
582  }
583  getType(): string {
584    return 'ProxyFrameNode';
585  }
586  getRenderNode(): RenderNode | null {
587    return null;
588  }
589  getNodePtr(): NodePtr | null {
590    if (this._nativeRef === undefined || this._nativeRef === null || this._nativeRef.invalid()) {
591      return null;
592    }
593    return this.nodePtr_;
594  }
595  dispose(): void {
596    this.renderNode_?.dispose();
597    FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.delete(this._nodeId);
598    this._nodeId = -1;
599    this._nativeRef = undefined;
600    this.nodePtr_ = undefined;
601  }
602}
603
604class FrameNodeUtils {
605  static searchNodeInRegisterProxy(nodePtr: NodePtr): FrameNode | null {
606    let nodeId = getUINativeModule().frameNode.getIdByNodePtr(nodePtr);
607    if (nodeId === -1) {
608      return null;
609    }
610    if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) {
611      let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref();
612      return frameNode === undefined ? null : frameNode;
613    }
614    return null;
615  }
616
617  static createFrameNode(uiContext: UIContext, nodePtr: NodePtr): FrameNode | null {
618    let nodeId = getUINativeModule().frameNode.getIdByNodePtr(nodePtr);
619    if (nodeId !== -1 && !getUINativeModule().frameNode.isModifiable(nodePtr)) {
620      let frameNode = new ProxyFrameNode(uiContext);
621      let node = getUINativeModule().nativeUtils.createNativeWeakRef(nodePtr);
622      frameNode.setNodePtr(node);
623      frameNode._nodeId = nodeId;
624      FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(nodeId, new WeakRef(frameNode));
625      FrameNodeFinalizationRegisterProxy.register(frameNode, nodeId);
626      return frameNode;
627    }
628    return null;
629  }
630}
631
632class TypedFrameNode<T extends ArkComponent> extends FrameNode {
633  attribute_: T;
634  attrCreator_: (node: NodePtr, type: ModifierType) => T
635
636  constructor(uiContext: UIContext, type: string, attrCreator: (node: NodePtr, type: ModifierType) => T, options?: object) {
637    super(uiContext, type, options);
638    this.attrCreator_ = attrCreator;
639  }
640
641  initialize(...args: Object[]): T {
642    return this.attribute.initialize(args);
643  }
644
645  get attribute(): T {
646    if (this.attribute_ === undefined) {
647      this.attribute_ = this.attrCreator_(this.nodePtr_, ModifierType.FRAME_NODE);
648    }
649    this.attribute_.setNodePtr(this.nodePtr_);
650    this.attribute_.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_);
651    return this.attribute_;
652  }
653
654  checkValid(node?: FrameNode): boolean {
655    if (this.attribute_ === undefined) {
656      this.attribute_ = this.attrCreator_(this.nodePtr_, ModifierType.FRAME_NODE);
657    }
658
659    if (this.attribute_.allowChildCount !== undefined) {
660      const allowCount = this.attribute_.allowChildCount();
661      if (this.getChildrenCount() >= allowCount) {
662        return false;
663      }
664    }
665
666    if (this.attribute_.allowChildTypes !== undefined && node !== undefined) {
667      const childType = node.getNodeType();
668      const allowTypes = this.attribute_.allowChildTypes();
669      let isValid = false;
670      allowTypes.forEach((nodeType: string) => {
671        if (nodeType === childType) {
672          isValid = true;
673        }
674      });
675      return isValid;
676    }
677    return true;
678  }
679}
680
681const __creatorMap__ = new Map<string, (context: UIContext, options?: object) => FrameNode>(
682  [
683    ['Text', (context: UIContext): FrameNode=> {
684      return new TypedFrameNode(context, 'Text', (node: NodePtr, type: ModifierType): ArkTextComponent => {
685        return new ArkTextComponent(node, type);
686      })
687    }],
688    ['Column', (context: UIContext): FrameNode=> {
689      return new TypedFrameNode(context, 'Column', (node: NodePtr, type: ModifierType): ArkColumnComponent => {
690        return new ArkColumnComponent(node, type);
691      })
692    }],
693    ['Row', (context: UIContext): FrameNode=> {
694      return new TypedFrameNode(context, 'Row', (node: NodePtr, type: ModifierType): ArkRowComponent => {
695        return new ArkRowComponent(node, type);
696      })
697    }],
698    ['Stack', (context: UIContext): FrameNode=> {
699      return new TypedFrameNode(context, 'Stack', (node: NodePtr, type: ModifierType): ArkStackComponent => {
700        return new ArkStackComponent(node, type);
701      })
702    }],
703    ['GridRow', (context: UIContext): FrameNode=> {
704      let node = new TypedFrameNode(context, 'GridRow', (node: NodePtr, type: ModifierType): ArkGridRowComponent => {
705        return new ArkGridRowComponent(node, type);
706      })
707      node.initialize();
708      return node;
709    }],
710    ['TextInput', (context: UIContext): FrameNode=> {
711      return new TypedFrameNode(context, 'TextInput', (node: NodePtr, type: ModifierType): ArkTextInputComponent => {
712        return new ArkTextInputComponent(node, type);
713      })
714    }],
715    ['GridCol', (context: UIContext): FrameNode=> {
716      let node = new TypedFrameNode(context, 'GridCol', (node: NodePtr, type: ModifierType): ArkGridColComponent => {
717        return new ArkGridColComponent(node, type);
718      })
719      node.initialize();
720      return node;
721    }],
722    ['Blank', (context: UIContext): FrameNode=> {
723      return new TypedFrameNode(context, 'Blank', (node: NodePtr, type: ModifierType): ArkBlankComponent => {
724        return new ArkBlankComponent(node, type);
725      })
726    }],
727    ['Image', (context: UIContext): FrameNode=> {
728      return new TypedFrameNode(context, 'Image', (node: NodePtr, type: ModifierType): ArkImageComponent => {
729        return new ArkImageComponent(node, type);
730      })
731    }],
732    ['Flex', (context: UIContext): FrameNode=> {
733      return new TypedFrameNode(context, 'Flex', (node: NodePtr, type: ModifierType): ArkFlexComponent => {
734        return new ArkFlexComponent(node, type);
735      })
736    }],
737    ['Swiper', (context: UIContext): FrameNode=> {
738      return new TypedFrameNode(context, 'Swiper', (node: NodePtr, type: ModifierType): ArkSwiperComponent => {
739        return new ArkSwiperComponent(node, type);
740      })
741    }],
742    ['Progress', (context: UIContext): FrameNode=> {
743      return new TypedFrameNode(context, 'Progress', (node: NodePtr, type: ModifierType): ArkProgressComponent => {
744        return new ArkProgressComponent(node, type);
745      })
746    }],
747    ['Scroll', (context: UIContext): FrameNode=> {
748      return new TypedFrameNode(context, 'Scroll', (node: NodePtr, type: ModifierType): ArkScrollComponent => {
749        return new ArkScrollComponent(node, type);
750      })
751    }],
752    ['RelativeContainer', (context: UIContext): FrameNode=> {
753      return new TypedFrameNode(context, 'RelativeContainer', (node: NodePtr, type: ModifierType): ArkRelativeContainerComponent => {
754        return new ArkRelativeContainerComponent(node, type);
755      })
756    }],
757    ['List', (context: UIContext): FrameNode=> {
758      return new TypedFrameNode(context, 'List', (node: NodePtr, type: ModifierType): ArkListComponent => {
759        return new ArkListComponent(node, type);
760      })
761    }],
762    ['ListItem', (context: UIContext): FrameNode=> {
763      return new TypedFrameNode(context, 'ListItem', (node: NodePtr, type: ModifierType): ArkListItemComponent => {
764        return new ArkListItemComponent(node, type);
765      })
766    }],
767    ['Divider', (context: UIContext): FrameNode=> {
768      return new TypedFrameNode(context, 'Divider', (node: NodePtr, type: ModifierType): ArkDividerComponent => {
769        return new ArkDividerComponent(node, type);
770      })
771    }],
772    ['LoadingProgress', (context: UIContext): FrameNode=> {
773      return new TypedFrameNode(context, 'LoadingProgress', (node: NodePtr, type: ModifierType): ArkLoadingProgressComponent => {
774        return new ArkLoadingProgressComponent(node, type);
775      })
776    }],
777    ['Search', (context: UIContext): FrameNode=> {
778      return new TypedFrameNode(context, 'Search', (node: NodePtr, type: ModifierType): ArkSearchComponent => {
779        return new ArkSearchComponent(node, type);
780      })
781    }],
782    ['Button', (context: UIContext): FrameNode=> {
783      return new TypedFrameNode(context, 'Button', (node: NodePtr, type: ModifierType): ArkButtonComponent => {
784        return new ArkButtonComponent(node, type);
785      })
786    }],
787    ['XComponent', (context: UIContext, options?: object): FrameNode=> {
788      return new TypedFrameNode(context, 'XComponent', (node: NodePtr, type: ModifierType): ArkXComponentComponent => {
789        return new ArkXComponentComponent(node, type);
790      }, options);
791    }],
792    ['ListItemGroup', (context: UIContext): FrameNode=> {
793      return new TypedFrameNode(context, 'ListItemGroup', (node: NodePtr, type: ModifierType): ArkListItemGroupComponent => {
794        return new ArkListItemGroupComponent(node, type);
795      })
796    }],
797    ['WaterFlow', (context: UIContext): FrameNode=> {
798      return new TypedFrameNode(context, 'WaterFlow', (node: NodePtr, type: ModifierType): ArkWaterFlowComponent => {
799        return new ArkWaterFlowComponent(node, type);
800      })
801    }],
802    ['FlowItem', (context: UIContext): FrameNode=> {
803      return new TypedFrameNode(context, 'FlowItem', (node: NodePtr, type: ModifierType): ArkFlowItemComponent => {
804        return new ArkFlowItemComponent(node, type);
805      })
806    }],
807  ]
808)
809
810class typeNode {
811  static createNode(context: UIContext, type: string, options?: object): FrameNode {
812    let creator = __creatorMap__.get(type)
813    if (creator === undefined) {
814      return undefined
815    }
816    return creator(context, options);
817  }
818}
819