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 const result = getUINativeModule().frameNode.getParent(this.getNodePtr()); 379 const nodeId = result?.nodeId; 380 if (nodeId === undefined || nodeId === -1) { 381 return null; 382 } 383 if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) { 384 let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref(); 385 return frameNode === undefined ? null : frameNode; 386 } 387 return this.convertToFrameNode(result.nodePtr, result.nodeId); 388 } 389 390 getChildrenCount(isExpanded?: boolean): number { 391 __JSScopeUtil__.syncInstanceId(this.instanceId_); 392 const childrenCount = getUINativeModule().frameNode.getChildrenCount(this.nodePtr_, isExpanded); 393 __JSScopeUtil__.restoreInstanceId(); 394 return childrenCount; 395 } 396 397 getPositionToParent(): Position { 398 const position = getUINativeModule().frameNode.getPositionToParent(this.getNodePtr()); 399 return { x: position[0], y: position[1] }; 400 } 401 402 getPositionToScreen(): Position { 403 const position = getUINativeModule().frameNode.getPositionToScreen(this.getNodePtr()); 404 return { x: position[0], y: position[1] }; 405 } 406 407 getPositionToWindow(): Position { 408 const position = getUINativeModule().frameNode.getPositionToWindow(this.getNodePtr()); 409 return { x: position[0], y: position[1] }; 410 } 411 412 getPositionToParentWithTransform(): Position { 413 const position = getUINativeModule().frameNode.getPositionToParentWithTransform(this.getNodePtr()); 414 return { x: position[0], y: position[1] }; 415 } 416 417 getPositionToScreenWithTransform(): Position { 418 const position = getUINativeModule().frameNode.getPositionToScreenWithTransform(this.getNodePtr()); 419 return { x: position[0], y: position[1] }; 420 } 421 422 getPositionToWindowWithTransform(): Position { 423 const position = getUINativeModule().frameNode.getPositionToWindowWithTransform(this.getNodePtr()); 424 return { x: position[0], y: position[1] }; 425 } 426 427 getMeasuredSize(): Size { 428 const size = getUINativeModule().frameNode.getMeasuredSize(this.getValidNodePtr()); 429 return { width: size[0], height: size[1] }; 430 } 431 432 getLayoutPosition(): Position { 433 const position = getUINativeModule().frameNode.getLayoutPosition(this.getValidNodePtr()); 434 return { x: position[0], y: position[1] }; 435 } 436 437 getUserConfigBorderWidth(): EdgesT<LengthMetrics> { 438 const borderWidth = getUINativeModule().frameNode.getConfigBorderWidth(this.getNodePtr()); 439 return { 440 top: new LengthMetrics(borderWidth[0], borderWidth[1]), 441 right: new LengthMetrics(borderWidth[2], borderWidth[3]), 442 bottom: new LengthMetrics(borderWidth[4], borderWidth[5]), 443 left: new LengthMetrics(borderWidth[6], borderWidth[7]) 444 }; 445 } 446 447 getUserConfigPadding(): EdgesT<LengthMetrics> { 448 const borderWidth = getUINativeModule().frameNode.getConfigPadding(this.getNodePtr()); 449 return { 450 top: new LengthMetrics(borderWidth[0], borderWidth[1]), 451 right: new LengthMetrics(borderWidth[2], borderWidth[3]), 452 bottom: new LengthMetrics(borderWidth[4], borderWidth[5]), 453 left: new LengthMetrics(borderWidth[6], borderWidth[7]) 454 }; 455 } 456 457 getUserConfigMargin(): EdgesT<LengthMetrics> { 458 const margin = getUINativeModule().frameNode.getConfigMargin(this.getNodePtr()); 459 return { 460 top: new LengthMetrics(margin[0], margin[1]), 461 right: new LengthMetrics(margin[2], margin[3]), 462 bottom: new LengthMetrics(margin[4], margin[5]), 463 left: new LengthMetrics(margin[6], margin[7]) 464 }; 465 } 466 467 getUserConfigSize(): SizeT<LengthMetrics> { 468 const size = getUINativeModule().frameNode.getConfigSize(this.getNodePtr()); 469 return { 470 width: new LengthMetrics(size[0], size[1]), 471 height: new LengthMetrics(size[2], size[3]) 472 }; 473 } 474 475 getId(): string { 476 return getUINativeModule().frameNode.getId(this.getNodePtr()); 477 } 478 479 getUniqueId(): number { 480 return getUINativeModule().frameNode.getIdByNodePtr(this.getNodePtr()); 481 } 482 483 getNodeType(): string { 484 return getUINativeModule().frameNode.getNodeType(this.getNodePtr()); 485 } 486 487 getOpacity(): number { 488 return getUINativeModule().frameNode.getOpacity(this.getNodePtr()); 489 } 490 491 isVisible(): boolean { 492 return getUINativeModule().frameNode.isVisible(this.getNodePtr()); 493 } 494 495 isClipToFrame(): boolean { 496 return getUINativeModule().frameNode.isClipToFrame(this.getNodePtr()); 497 } 498 499 isAttached(): boolean { 500 return getUINativeModule().frameNode.isAttached(this.getNodePtr()); 501 } 502 503 getInspectorInfo(): Object { 504 const inspectorInfoStr = getUINativeModule().frameNode.getInspectorInfo(this.getNodePtr()); 505 const inspectorInfo = JSON.parse(inspectorInfoStr); 506 return inspectorInfo; 507 } 508 509 getCustomProperty(key: string): Object | undefined { 510 if (key === undefined) { 511 return undefined; 512 } 513 let value = __getCustomProperty__(this._nodeId, key); 514 if (value === undefined) { 515 const valueStr = getUINativeModule().frameNode.getCustomPropertyCapiByKey(this.getNodePtr(), key); 516 value = valueStr === undefined ? undefined : valueStr; 517 } 518 return value; 519 } 520 521 setMeasuredSize(size: Size): void { 522 getUINativeModule().frameNode.setMeasuredSize(this.getNodePtr(), Math.max(size.width, 0), 523 Math.max(size.height, 0)); 524 } 525 526 setLayoutPosition(position: Position): void { 527 getUINativeModule().frameNode.setLayoutPosition(this.getNodePtr(), position.x, position.y); 528 } 529 530 measure(constraint: LayoutConstraint): void { 531 const minSize: Size = constraint.minSize; 532 const maxSize: Size = constraint.maxSize; 533 const percentReference: Size = constraint.percentReference; 534 __JSScopeUtil__.syncInstanceId(this.instanceId_); 535 getUINativeModule().frameNode.measureNode(this.getNodePtr(), minSize.width, minSize.height, maxSize.width, 536 maxSize.height, percentReference.width, percentReference.height); 537 __JSScopeUtil__.restoreInstanceId(); 538 } 539 540 layout(position: Position): void { 541 __JSScopeUtil__.syncInstanceId(this.instanceId_); 542 getUINativeModule().frameNode.layoutNode(this.getNodePtr(), position.x, position.y); 543 __JSScopeUtil__.restoreInstanceId(); 544 } 545 546 setNeedsLayout(): void { 547 getUINativeModule().frameNode.setNeedsLayout(this.getNodePtr()); 548 } 549 550 setCrossLanguageOptions(options: CrossLanguageOptions): void { 551 if (!this.isModifiable()) { 552 throw { message: 'The FrameNode cannot be set whether to support cross-language common attribute setting.', code: 100022 }; 553 } 554 __JSScopeUtil__.syncInstanceId(this.instanceId_); 555 const result = getUINativeModule().frameNode.setCrossLanguageOptions(this.getNodePtr(), options.attributeSetting ?? false); 556 __JSScopeUtil__.restoreInstanceId(); 557 if (result !== 0) { 558 throw { message: 'The FrameNode cannot be set whether to support cross-language common attribute setting.', code: 100022 }; 559 } 560 } 561 562 getCrossLanguageOptions(): CrossLanguageOptions { 563 __JSScopeUtil__.syncInstanceId(this.instanceId_); 564 const attributeSetting = getUINativeModule().frameNode.getCrossLanguageOptions(this.getNodePtr()); 565 __JSScopeUtil__.restoreInstanceId(); 566 return { attributeSetting: attributeSetting ?? false }; 567 } 568 569 checkIfCanCrossLanguageAttributeSetting(): boolean { 570 return this.isModifiable() || getUINativeModule().frameNode.checkIfCanCrossLanguageAttributeSetting(this.getNodePtr()); 571 } 572 573 get commonAttribute(): ArkComponent { 574 if (this._commonAttribute === undefined) { 575 this._commonAttribute = new ArkComponent(this.nodePtr_, ModifierType.FRAME_NODE); 576 this._commonAttribute.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_); 577 } 578 this._commonAttribute.setNodePtr(this.nodePtr_); 579 return this._commonAttribute; 580 } 581 582 get commonEvent(): UICommonEvent { 583 let node = this.getNodePtr(); 584 if (this._commonEvent === undefined) { 585 this._commonEvent = new UICommonEvent(node); 586 } 587 this._commonEvent.setNodePtr(node); 588 this._commonEvent.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_); 589 return this._commonEvent; 590 } 591 592 get gestureEvent(): UIGestureEvent { 593 if (this._gestureEvent === undefined) { 594 this._gestureEvent = new UIGestureEvent(); 595 this._gestureEvent.setNodePtr(this.nodePtr_); 596 let weakPtr = getUINativeModule().nativeUtils.createNativeWeakRef(this.nodePtr_); 597 this._gestureEvent.setWeakNodePtr(weakPtr); 598 __JSScopeUtil__.syncInstanceId(this.instanceId_); 599 this._gestureEvent.registerFrameNodeDeletedCallback(this.nodePtr_); 600 __JSScopeUtil__.restoreInstanceId(); 601 } 602 return this._gestureEvent; 603 } 604 updateInstance(uiContext: UIContext): void { 605 this.uiContext_ = uiContext; 606 this.instanceId_ = uiContext.instanceId_; 607 } 608} 609 610class ImmutableFrameNode extends FrameNode { 611 isModifiable(): boolean { 612 return false; 613 } 614 invalidate() { 615 return; 616 } 617 appendChild(node: FrameNode): void { 618 throw { message: 'The FrameNode is not modifiable.', code: 100021 }; 619 } 620 insertChildAfter(child: FrameNode, sibling: FrameNode): void { 621 throw { message: 'The FrameNode is not modifiable.', code: 100021 }; 622 } 623 removeChild(node: FrameNode): void { 624 throw { message: 'The FrameNode is not modifiable.', code: 100021 }; 625 } 626 clearChildren(): void { 627 throw { message: 'The FrameNode is not modifiable.', code: 100021 }; 628 } 629 get commonAttribute(): ArkComponent { 630 if (this._commonAttribute === undefined) { 631 this._commonAttribute = new ArkComponent(undefined, ModifierType.FRAME_NODE); 632 } 633 this._commonAttribute.setNodePtr(undefined); 634 return this._commonAttribute; 635 } 636} 637 638class BuilderRootFrameNode extends ImmutableFrameNode { 639 constructor(uiContext: UIContext, type: string = 'BuilderRootFrameNode') { 640 super(uiContext, type); 641 } 642 getType(): string { 643 return 'BuilderRootFrameNode'; 644 } 645} 646 647class ProxyFrameNode extends ImmutableFrameNode { 648 _nativeRef: NativeWeakRef; 649 650 constructor(uiContext: UIContext, type: string = 'ProxyFrameNode') { 651 super(uiContext, type); 652 } 653 654 setNodePtr(nativeRef: NativeWeakRef) { 655 this._nativeRef = nativeRef; 656 this.nodePtr_ = this._nativeRef.getNativeHandle(); 657 } 658 getType(): string { 659 return 'ProxyFrameNode'; 660 } 661 getRenderNode(): RenderNode | null { 662 return null; 663 } 664 getNodePtr(): NodePtr | null { 665 if (this._nativeRef === undefined || this._nativeRef === null || this._nativeRef.invalid()) { 666 return null; 667 } 668 return this.nodePtr_; 669 } 670 dispose(): void { 671 this.renderNode_?.dispose(); 672 FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.delete(this._nodeId); 673 this._nodeId = -1; 674 this._nativeRef = undefined; 675 this.nodePtr_ = undefined; 676 } 677} 678 679class FrameNodeUtils { 680 static searchNodeInRegisterProxy(nodePtr: NodePtr): FrameNode | null { 681 let nodeId = getUINativeModule().frameNode.getIdByNodePtr(nodePtr); 682 if (nodeId === -1) { 683 return null; 684 } 685 if (FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.has(nodeId)) { 686 let frameNode = FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.get(nodeId).deref(); 687 return frameNode === undefined ? null : frameNode; 688 } 689 return null; 690 } 691 692 static createFrameNode(uiContext: UIContext, nodePtr: NodePtr): FrameNode | null { 693 let nodeId = getUINativeModule().frameNode.getIdByNodePtr(nodePtr); 694 if (nodeId !== -1 && !getUINativeModule().frameNode.isModifiable(nodePtr)) { 695 let frameNode = new ProxyFrameNode(uiContext); 696 let node = getUINativeModule().nativeUtils.createNativeWeakRef(nodePtr); 697 frameNode.setNodePtr(node); 698 frameNode._nodeId = nodeId; 699 FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(nodeId, new WeakRef(frameNode)); 700 FrameNodeFinalizationRegisterProxy.register(frameNode, nodeId); 701 return frameNode; 702 } 703 return null; 704 } 705} 706 707class TypedFrameNode<T extends ArkComponent> extends FrameNode { 708 attribute_: T; 709 attrCreator_: (node: NodePtr, type: ModifierType) => T 710 711 constructor(uiContext: UIContext, type: string, attrCreator: (node: NodePtr, type: ModifierType) => T, options?: object) { 712 super(uiContext, type, options); 713 this.attrCreator_ = attrCreator; 714 } 715 716 initialize(...args: Object[]): T { 717 return this.attribute.initialize(args); 718 } 719 720 get attribute(): T { 721 if (this.attribute_ === undefined) { 722 this.attribute_ = this.attrCreator_(this.nodePtr_, ModifierType.FRAME_NODE); 723 } 724 this.attribute_.setNodePtr(this.nodePtr_); 725 this.attribute_.setInstanceId((this.uiContext_ === undefined || this.uiContext_ === null) ? -1 : this.uiContext_.instanceId_); 726 return this.attribute_; 727 } 728 729 checkValid(node?: FrameNode): boolean { 730 if (this.attribute_ === undefined) { 731 this.attribute_ = this.attrCreator_(this.nodePtr_, ModifierType.FRAME_NODE); 732 } 733 734 if (this.attribute_.allowChildCount !== undefined) { 735 const allowCount = this.attribute_.allowChildCount(); 736 if (this.getChildrenCount() >= allowCount) { 737 return false; 738 } 739 } 740 741 if (this.attribute_.allowChildTypes !== undefined && node !== undefined) { 742 const childType = node.getNodeType(); 743 const allowTypes = this.attribute_.allowChildTypes(); 744 let isValid = false; 745 allowTypes.forEach((nodeType: string) => { 746 if (nodeType === childType) { 747 isValid = true; 748 } 749 }); 750 return isValid; 751 } 752 return true; 753 } 754} 755 756const __creatorMap__ = new Map<string, (context: UIContext, options?: object) => FrameNode>( 757 [ 758 ['Text', (context: UIContext): FrameNode=> { 759 return new TypedFrameNode(context, 'Text', (node: NodePtr, type: ModifierType): ArkTextComponent => { 760 return new ArkTextComponent(node, type); 761 }) 762 }], 763 ['Column', (context: UIContext): FrameNode=> { 764 return new TypedFrameNode(context, 'Column', (node: NodePtr, type: ModifierType): ArkColumnComponent => { 765 return new ArkColumnComponent(node, type); 766 }) 767 }], 768 ['Row', (context: UIContext): FrameNode=> { 769 return new TypedFrameNode(context, 'Row', (node: NodePtr, type: ModifierType): ArkRowComponent => { 770 return new ArkRowComponent(node, type); 771 }) 772 }], 773 ['Stack', (context: UIContext): FrameNode=> { 774 return new TypedFrameNode(context, 'Stack', (node: NodePtr, type: ModifierType): ArkStackComponent => { 775 return new ArkStackComponent(node, type); 776 }) 777 }], 778 ['GridRow', (context: UIContext): FrameNode=> { 779 let node = new TypedFrameNode(context, 'GridRow', (node: NodePtr, type: ModifierType): ArkGridRowComponent => { 780 return new ArkGridRowComponent(node, type); 781 }) 782 node.initialize(); 783 return node; 784 }], 785 ['TextInput', (context: UIContext): FrameNode=> { 786 return new TypedFrameNode(context, 'TextInput', (node: NodePtr, type: ModifierType): ArkTextInputComponent => { 787 return new ArkTextInputComponent(node, type); 788 }) 789 }], 790 ['GridCol', (context: UIContext): FrameNode=> { 791 let node = new TypedFrameNode(context, 'GridCol', (node: NodePtr, type: ModifierType): ArkGridColComponent => { 792 return new ArkGridColComponent(node, type); 793 }) 794 node.initialize(); 795 return node; 796 }], 797 ['Blank', (context: UIContext): FrameNode=> { 798 return new TypedFrameNode(context, 'Blank', (node: NodePtr, type: ModifierType): ArkBlankComponent => { 799 return new ArkBlankComponent(node, type); 800 }) 801 }], 802 ['Image', (context: UIContext): FrameNode=> { 803 return new TypedFrameNode(context, 'Image', (node: NodePtr, type: ModifierType): ArkImageComponent => { 804 return new ArkImageComponent(node, type); 805 }) 806 }], 807 ['Flex', (context: UIContext): FrameNode=> { 808 return new TypedFrameNode(context, 'Flex', (node: NodePtr, type: ModifierType): ArkFlexComponent => { 809 return new ArkFlexComponent(node, type); 810 }) 811 }], 812 ['Swiper', (context: UIContext): FrameNode=> { 813 return new TypedFrameNode(context, 'Swiper', (node: NodePtr, type: ModifierType): ArkSwiperComponent => { 814 return new ArkSwiperComponent(node, type); 815 }) 816 }], 817 ['Progress', (context: UIContext): FrameNode=> { 818 return new TypedFrameNode(context, 'Progress', (node: NodePtr, type: ModifierType): ArkProgressComponent => { 819 return new ArkProgressComponent(node, type); 820 }) 821 }], 822 ['Scroll', (context: UIContext): FrameNode=> { 823 return new TypedFrameNode(context, 'Scroll', (node: NodePtr, type: ModifierType): ArkScrollComponent => { 824 return new ArkScrollComponent(node, type); 825 }) 826 }], 827 ['RelativeContainer', (context: UIContext): FrameNode=> { 828 return new TypedFrameNode(context, 'RelativeContainer', (node: NodePtr, type: ModifierType): ArkRelativeContainerComponent => { 829 return new ArkRelativeContainerComponent(node, type); 830 }) 831 }], 832 ['List', (context: UIContext): FrameNode=> { 833 return new TypedFrameNode(context, 'List', (node: NodePtr, type: ModifierType): ArkListComponent => { 834 return new ArkListComponent(node, type); 835 }) 836 }], 837 ['ListItem', (context: UIContext): FrameNode=> { 838 return new TypedFrameNode(context, 'ListItem', (node: NodePtr, type: ModifierType): ArkListItemComponent => { 839 return new ArkListItemComponent(node, type); 840 }) 841 }], 842 ['Divider', (context: UIContext): FrameNode=> { 843 return new TypedFrameNode(context, 'Divider', (node: NodePtr, type: ModifierType): ArkDividerComponent => { 844 return new ArkDividerComponent(node, type); 845 }) 846 }], 847 ['LoadingProgress', (context: UIContext): FrameNode=> { 848 return new TypedFrameNode(context, 'LoadingProgress', (node: NodePtr, type: ModifierType): ArkLoadingProgressComponent => { 849 return new ArkLoadingProgressComponent(node, type); 850 }) 851 }], 852 ['Search', (context: UIContext): FrameNode=> { 853 return new TypedFrameNode(context, 'Search', (node: NodePtr, type: ModifierType): ArkSearchComponent => { 854 return new ArkSearchComponent(node, type); 855 }) 856 }], 857 ['Button', (context: UIContext): FrameNode=> { 858 return new TypedFrameNode(context, 'Button', (node: NodePtr, type: ModifierType): ArkButtonComponent => { 859 return new ArkButtonComponent(node, type); 860 }) 861 }], 862 ['XComponent', (context: UIContext, options?: object): FrameNode=> { 863 return new TypedFrameNode(context, 'XComponent', (node: NodePtr, type: ModifierType): ArkXComponentComponent => { 864 return new ArkXComponentComponent(node, type); 865 }, options); 866 }], 867 ['ListItemGroup', (context: UIContext): FrameNode=> { 868 return new TypedFrameNode(context, 'ListItemGroup', (node: NodePtr, type: ModifierType): ArkListItemGroupComponent => { 869 return new ArkListItemGroupComponent(node, type); 870 }) 871 }], 872 ['WaterFlow', (context: UIContext): FrameNode=> { 873 return new TypedFrameNode(context, 'WaterFlow', (node: NodePtr, type: ModifierType): ArkWaterFlowComponent => { 874 return new ArkWaterFlowComponent(node, type); 875 }) 876 }], 877 ['SymbolGlyph', (context: UIContext): FrameNode=> { 878 return new TypedFrameNode(context, 'SymbolGlyph', (node: NodePtr, type: ModifierType): ArkSymbolGlyphComponent => { 879 return new ArkSymbolGlyphComponent(node, type); 880 }) 881 }], 882 ['FlowItem', (context: UIContext): FrameNode=> { 883 return new TypedFrameNode(context, 'FlowItem', (node: NodePtr, type: ModifierType): ArkFlowItemComponent => { 884 return new ArkFlowItemComponent(node, type); 885 }) 886 }], 887 ['Marquee', (context: UIContext): FrameNode=> { 888 return new TypedFrameNode(context, 'Marquee', (node: NodePtr, type: ModifierType): ArkMarqueeComponent => { 889 return new ArkMarqueeComponent(node, type); 890 }) 891 }], 892 ['TextArea', (context: UIContext): FrameNode=> { 893 return new TypedFrameNode(context, 'TextArea', (node: NodePtr, type: ModifierType): ArkTextAreaComponent => { 894 return new ArkTextAreaComponent(node, type); 895 }) 896 }], 897 ['QRCode', (context: UIContext): FrameNode=> { 898 return new TypedFrameNode(context, 'QRCode', (node: NodePtr, type: ModifierType): ArkQRCodeComponent => { 899 return new ArkQRCodeComponent(node, type); 900 }) 901 }], 902 ['Badge', (context: UIContext): FrameNode=> { 903 return new TypedFrameNode(context, 'Badge', (node: NodePtr, type: ModifierType): ArkBadgeComponent => { 904 return new ArkBadgeComponent(node, type); 905 }) 906 }], 907 ['Grid', (context: UIContext): FrameNode=> { 908 return new TypedFrameNode(context, 'Grid', (node: NodePtr, type: ModifierType): ArkGridComponent => { 909 return new ArkGridComponent(node, type); 910 }) 911 }], 912 ['GridItem', (context: UIContext): FrameNode=> { 913 return new TypedFrameNode(context, 'GridItem', (node: NodePtr, type: ModifierType): ArkGridItemComponent => { 914 return new ArkGridItemComponent(node, type); 915 }) 916 }], 917 ['TextClock', (context: UIContext): FrameNode=> { 918 return new TypedFrameNode(context, 'TextClock', (node: NodePtr, type: ModifierType): ArkTextClockComponent => { 919 return new ArkTextClockComponent(node, type); 920 }) 921 }], 922 ['TextTimer', (context: UIContext): FrameNode=> { 923 return new TypedFrameNode(context, 'TextTimer', (node: NodePtr, type: ModifierType): ArkTextTimerComponent => { 924 return new ArkTextTimerComponent(node, type); 925 }) 926 }], 927 ] 928) 929 930const __attributeMap__ = new Map<string, (node: FrameNode) => ArkComponent>( 931 [ 932 ['Scroll', (node: FrameNode): ArkScrollComponent => { 933 if (node._componentAttribute) { 934 return node._componentAttribute; 935 } 936 if (!node.getNodePtr()) { 937 return undefined; 938 } 939 node._componentAttribute = new ArkScrollComponent(node.getNodePtr(), ModifierType.FRAME_NODE); 940 return node._componentAttribute; 941 }], 942 ] 943) 944 945class typeNode { 946 static createNode(context: UIContext, type: string, options?: object): FrameNode { 947 let creator = __creatorMap__.get(type) 948 if (creator === undefined) { 949 return undefined 950 } 951 return creator(context, options); 952 } 953 954 static getAttribute(node: FrameNode, nodeType: string): ArkComponent { 955 if (node === undefined || node === null || node.getNodeType() !== nodeType) { 956 return undefined; 957 } 958 if (!node.checkIfCanCrossLanguageAttributeSetting()) { 959 return undefined; 960 } 961 let attribute = __attributeMap__.get(nodeType); 962 if (attribute === undefined || attribute === null) { 963 return undefined; 964 } 965 return attribute(node); 966 } 967 968 static bindController(node: FrameNode, controller: Scroller, nodeType: string): void { 969 if (node === undefined || node === null || controller === undefined || controller === null || 970 node.getNodeType() !== nodeType || node.getNodePtr() === null || node.getNodePtr() === undefined) { 971 throw { message: 'Parameter error. Possible causes: 1. The type of the node is error; 2. The node is null or undefined.', code: 401 }; 972 } 973 if (!node.checkIfCanCrossLanguageAttributeSetting()) { 974 throw { message: 'The FrameNode is not modifiable.', code: 100021 }; 975 } 976 getUINativeModule().scroll.setScrollInitialize(node.getNodePtr(), controller); 977 } 978} 979