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