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