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