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