1/* 2 * Copyright (c) 2023 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 16/// <reference path='./import.ts' /> 17interface XComponentParam { 18 id: string; 19 type: string | XComponentType; 20 imageAIOptions: ImageAIOptions; 21 libraryname?: string; 22 controller?: XComponentController; 23} 24class ArkXComponentComponent extends ArkComponent implements XComponentAttribute { 25 _modifiersWithKeys: Map<Symbol, AttributeModifierWithKey>; 26 nativePtr: KNode; 27 xComponentType: XComponentType = XComponentType.SURFACE; 28 libraryname?: string = undefined; 29 30 constructor(nativePtr: KNode, classType?: ModifierType) { 31 super(nativePtr, classType); 32 } 33 allowChildCount(): number { 34 if (this.xComponentType === XComponentType.COMPONENT) { 35 return undefined; 36 } 37 return 0; 38 } 39 applyModifierPatch(): void { 40 let expiringItemsWithKeys = []; 41 this._modifiersWithKeys.forEach((value, key) => { 42 if (value.applyStage(this.nativePtr, this)) { 43 expiringItemsWithKeys.push(key); 44 } 45 }); 46 expiringItemsWithKeys.forEach(key => { 47 this._modifiersWithKeys.delete(key); 48 }); 49 } 50 initialize(value: Object[]): this { 51 if (!isUndefined(value[0]) && !isNull(value[0]) && isObject(value[0])) { 52 this.xComponentType = (value[0] as XComponentParam).type; 53 this.libraryname = (value[0] as XComponentParam).libraryname; 54 modifierWithKey(this._modifiersWithKeys, XComponentInitializeModifier.identity, 55 XComponentInitializeModifier, value[0] as XComponentParam); 56 } 57 return this; 58 } 59 background(builder: CustomBuilder, options?: { align?: Alignment; }): this { 60 throw new Error('Method not implemented.'); 61 } 62 backgroundColor(value: ResourceColor): this { 63 modifierWithKey(this._modifiersWithKeys, XComponentBackgroundColorModifier.identity, 64 XComponentBackgroundColorModifier, value); 65 return this; 66 } 67 backgroundImage(src: ResourceStr, repeat?: ImageRepeat): this { 68 if (this.xComponentType !== XComponentType.NODE) { 69 return this; 70 } 71 let arkBackgroundImage = new ArkBackgroundImage(); 72 arkBackgroundImage.src = src; 73 arkBackgroundImage.repeat = repeat; 74 modifierWithKey(this._modifiersWithKeys, BackgroundImageModifier.identity, BackgroundImageModifier, arkBackgroundImage); 75 return this; 76 } 77 backgroundImageSize(value: SizeOptions | ImageSize): this { 78 if (this.xComponentType !== XComponentType.NODE) { 79 return this; 80 } 81 modifierWithKey(this._modifiersWithKeys, BackgroundImageSizeModifier.identity, BackgroundImageSizeModifier, value); 82 return this; 83 } 84 backgroundImagePosition(value: Alignment | Position): this { 85 if (this.xComponentType !== XComponentType.NODE) { 86 return this; 87 } 88 modifierWithKey(this._modifiersWithKeys, BackgroundImagePositionModifier.identity, BackgroundImagePositionModifier, value); 89 return this; 90 } 91 opacity(value: number | Resource): this { 92 modifierWithKey(this._modifiersWithKeys, XComponentOpacityModifier.identity, XComponentOpacityModifier, value); 93 return this; 94 } 95 foregroundColor(value: string | number | Resource | Color): this { 96 throw new Error('Method not implemented.'); 97 } 98 onClick(event: (event: ClickEvent) => void): this { 99 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 100 modifierWithKey(this._modifiersWithKeys, OnClickModifier.identity, OnClickModifier, event); 101 } 102 return this; 103 } 104 onHover(event: (isHover: boolean, event: HoverEvent) => void): this { 105 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 106 modifierWithKey(this._modifiersWithKeys, OnHoverModifier.identity, OnHoverModifier, event); 107 } 108 return this; 109 } 110 onMouse(event: (event: MouseEvent) => void): this { 111 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 112 modifierWithKey(this._modifiersWithKeys, OnMouseModifier.identity, OnMouseModifier, event); 113 } 114 return this; 115 } 116 onTouch(event: (event: TouchEvent) => void): this { 117 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 118 modifierWithKey(this._modifiersWithKeys, OnTouchModifier.identity, OnTouchModifier, event); 119 } 120 return this; 121 } 122 onKeyEvent(event: (event: KeyEvent) => void): this { 123 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 124 modifierWithKey(this._modifiersWithKeys, OnKeyEventModifier.identity, OnKeyEventModifier, event); 125 } 126 return this; 127 } 128 onFocus(event: () => void): this { 129 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 130 modifierWithKey(this._modifiersWithKeys, OnFocusModifier.identity, OnFocusModifier, event); 131 } 132 return this; 133 } 134 onBlur(event: () => void): this { 135 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 136 modifierWithKey(this._modifiersWithKeys, OnBlurModifier.identity, OnBlurModifier, event); 137 } 138 return this; 139 } 140 animation(value: AnimateParam): this { 141 throw new Error('Method not implemented.'); 142 } 143 gesture(gesture: GestureType, mask?: GestureMask): this { 144 throw new Error('Method not implemented.'); 145 } 146 priorityGesture(gesture: GestureType, mask?: GestureMask): this { 147 throw new Error('Method not implemented.'); 148 } 149 parallelGesture(gesture: GestureType, mask?: GestureMask): this { 150 throw new Error('Method not implemented.'); 151 } 152 blur(value: number, options?: BlurOptions): this { 153 if (this.xComponentType !== XComponentType.NODE) { 154 return this; 155 } 156 let blur = new ArkBlurOptions(); 157 blur.value = value; 158 blur.options = options; 159 modifierWithKey(this._modifiersWithKeys, BlurModifier.identity, BlurModifier, blur); 160 return this; 161 } 162 linearGradientBlur(value: number, options: LinearGradientBlurOptions): this { 163 if (this.xComponentType !== XComponentType.NODE) { 164 return this; 165 } 166 if (isUndefined(value) || isNull(value) || isUndefined(options) || isNull(options)) { 167 modifierWithKey(this._modifiersWithKeys, LinearGradientBlurModifier.identity, LinearGradientBlurModifier, 168 undefined); 169 return this; 170 } 171 let arkLinearGradientBlur = new ArkLinearGradientBlur(); 172 arkLinearGradientBlur.blurRadius = value; 173 arkLinearGradientBlur.fractionStops = options.fractionStops; 174 arkLinearGradientBlur.direction = options.direction; 175 modifierWithKey(this._modifiersWithKeys, LinearGradientBlurModifier.identity, LinearGradientBlurModifier, 176 arkLinearGradientBlur); 177 return this; 178 } 179 brightness(value: number): this { 180 if (this.xComponentType !== XComponentType.NODE) { 181 return this; 182 } 183 if (!isNumber(value)) { 184 modifierWithKey(this._modifiersWithKeys, BrightnessModifier.identity, BrightnessModifier, undefined); 185 } 186 else { 187 modifierWithKey(this._modifiersWithKeys, BrightnessModifier.identity, BrightnessModifier, value); 188 } 189 return this; 190 } 191 contrast(value: number): this { 192 if (this.xComponentType !== XComponentType.NODE) { 193 return this; 194 } 195 if (!isNumber(value)) { 196 modifierWithKey(this._modifiersWithKeys, ContrastModifier.identity, ContrastModifier, undefined); 197 } 198 else { 199 modifierWithKey(this._modifiersWithKeys, ContrastModifier.identity, ContrastModifier, value); 200 } 201 return this; 202 } 203 grayscale(value: number): this { 204 modifierWithKey(this._modifiersWithKeys, XComponentGrayscaleModifier.identity, XComponentGrayscaleModifier, value); 205 return this; 206 } 207 colorBlend(value: string | Resource | Color): this { 208 if (this.xComponentType !== XComponentType.NODE) { 209 return this; 210 } 211 modifierWithKey(this._modifiersWithKeys, ColorBlendModifier.identity, ColorBlendModifier, value); 212 return this; 213 } 214 saturate(value: number): this { 215 if (this.xComponentType !== XComponentType.NODE) { 216 return this; 217 } 218 if (!isNumber(value)) { 219 modifierWithKey(this._modifiersWithKeys, SaturateModifier.identity, SaturateModifier, undefined); 220 } 221 else { 222 modifierWithKey(this._modifiersWithKeys, SaturateModifier.identity, SaturateModifier, value); 223 } 224 return this; 225 } 226 sepia(value: number): this { 227 if (this.xComponentType !== XComponentType.NODE) { 228 return this; 229 } 230 if (!isNumber(value)) { 231 modifierWithKey(this._modifiersWithKeys, SepiaModifier.identity, SepiaModifier, undefined); 232 } 233 else { 234 modifierWithKey(this._modifiersWithKeys, SepiaModifier.identity, SepiaModifier, value); 235 } 236 return this; 237 } 238 invert(value: number | InvertOptions): this { 239 if (this.xComponentType !== XComponentType.NODE) { 240 return this; 241 } 242 if (!isUndefined(value)) { 243 modifierWithKey(this._modifiersWithKeys, InvertModifier.identity, InvertModifier, value); 244 } 245 else { 246 modifierWithKey(this._modifiersWithKeys, InvertModifier.identity, InvertModifier, undefined); 247 } 248 return this; 249 } 250 hueRotate(value: string | number): this { 251 if (this.xComponentType !== XComponentType.NODE) { 252 return this; 253 } 254 if (!isNumber(value) && !isString(value)) { 255 modifierWithKey(this._modifiersWithKeys, HueRotateModifier.identity, HueRotateModifier, undefined); 256 } 257 else { 258 modifierWithKey(this._modifiersWithKeys, HueRotateModifier.identity, HueRotateModifier, value); 259 } 260 return this; 261 } 262 useEffect(value: boolean): this { 263 throw new Error('Method not implemented.'); 264 } 265 backdropBlur(value: number, options?: BlurOptions): this { 266 if (this.xComponentType !== XComponentType.NODE) { 267 return this; 268 } 269 let blur = new ArkBlurOptions(); 270 blur.value = value; 271 blur.options = options; 272 modifierWithKey(this._modifiersWithKeys, BackdropBlurModifier.identity, BackdropBlurModifier, blur); 273 return this; 274 } 275 renderGroup(value: boolean): this { 276 throw new Error('Method not implemented.'); 277 } 278 onAppear(event: () => void): this { 279 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 280 modifierWithKey(this._modifiersWithKeys, OnAppearModifier.identity, OnAppearModifier, event); 281 } 282 return this; 283 } 284 onDisAppear(event: () => void): this { 285 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 286 modifierWithKey(this._modifiersWithKeys, OnDisappearModifier.identity, OnDisappearModifier, event); 287 } 288 return this; 289 } 290 onAttach(callback: Callback<void>): this { 291 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 292 modifierWithKey(this._modifiersWithKeys, OnAttachModifier.identity, OnAttachModifier, callback); 293 } 294 return this; 295 } 296 onDetach(callback: Callback<void>): this { 297 if (this.xComponentType === XComponentType.NODE || isUndefined(this.libraryname)) { 298 modifierWithKey(this._modifiersWithKeys, OnDetachModifier.identity, OnDetachModifier, callback); 299 } 300 return this; 301 } 302 flexGrow(value: number): this { 303 throw new Error('Method not implemented.'); 304 } 305 direction(value: Direction): this { 306 throw new Error('Method not implemented.'); 307 } 308 align(value: Alignment): this { 309 throw new Error('Method not implemented.'); 310 } 311 useSizeType(value: { 312 xs?: number | { span: number; offset: number }; 313 sm?: number | { span: number; offset: number }; 314 md?: number | { span: number; offset: number }; 315 lg?: number | { span: number; offset: number }; 316 }): this { 317 throw new Error('Method not implemented.'); 318 } 319 clip(value: boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute): this { 320 throw new Error('Method not implemented.'); 321 } 322 geometryTransition(id: string): this { 323 throw new Error('Method not implemented.'); 324 } 325 bindPopup(show: boolean, popup: PopupOptions | CustomPopupOptions): this { 326 throw new Error('Method not implemented.'); 327 } 328 bindMenu(content: CustomBuilder | MenuElement[], options?: MenuOptions): this { 329 throw new Error('Method not implemented.'); 330 } 331 bindContextMenu(content: CustomBuilder, responseType: ResponseType, options?: ContextMenuOptions): this { 332 throw new Error('Method not implemented.'); 333 } 334 bindContentCover(isShow: unknown, builder: unknown, options?: unknown): this { 335 throw new Error('Method not implemented.'); 336 } 337 bindSheet(isShow: boolean, builder: CustomBuilder, options?: SheetOptions): this { 338 throw new Error('Method not implemented.'); 339 } 340 stateStyles(value: StateStyles): this { 341 throw new Error('Method not implemented.'); 342 } 343 restoreId(value: number): this { 344 throw new Error('Method not implemented.'); 345 } 346 onVisibleAreaChange(ratios: number[], event: (isVisible: boolean, currentRatio: number) => void): this { 347 throw new Error('Method not implemented.'); 348 } 349 sphericalEffect(value: number): this { 350 if (this.xComponentType !== XComponentType.NODE) { 351 return this; 352 } 353 modifierWithKey(this._modifiersWithKeys, SphericalEffectModifier.identity, SphericalEffectModifier, value); 354 return this; 355 } 356 lightUpEffect(value: number): this { 357 if (this.xComponentType !== XComponentType.NODE) { 358 return this; 359 } 360 modifierWithKey(this._modifiersWithKeys, LightUpEffectModifier.identity, LightUpEffectModifier, value); 361 return this; 362 } 363 pixelStretchEffect(options: PixelStretchEffectOptions): this { 364 if (this.xComponentType !== XComponentType.NODE) { 365 return this; 366 } 367 modifierWithKey(this._modifiersWithKeys, PixelStretchEffectModifier.identity, PixelStretchEffectModifier, options); 368 return this; 369 } 370 accessibilityGroup(value: boolean): this { 371 throw new Error('Method not implemented.'); 372 } 373 obscured(reasons: ObscuredReasons[]): this { 374 throw new Error('Method not implemented.'); 375 } 376 reuseId(id: string): this { 377 throw new Error('Method not implemented.'); 378 } 379 renderFit(fitMode: RenderFit): this { 380 modifierWithKey(this._modifiersWithKeys, XComponentRenderFitModifier.identity, XComponentRenderFitModifier, fitMode); 381 return this; 382 } 383 attributeModifier(modifier: AttributeModifier<CommonAttribute>): this { 384 return this; 385 } 386 onLoad(callback: (event?: object) => void): this { 387 modifierWithKey(this._modifiersWithKeys, XComponentOnLoadModifier.identity, XComponentOnLoadModifier, callback); 388 return this; 389 } 390 onDestroy(event: () => void): this { 391 modifierWithKey(this._modifiersWithKeys, XComponentOnDestroyModifier.identity, XComponentOnDestroyModifier, event); 392 return this; 393 } 394 enableAnalyzer(value: boolean): this { 395 modifierWithKey(this._modifiersWithKeys, XComponentEnableAnalyzerModifier.identity, XComponentEnableAnalyzerModifier, value); 396 return this; 397 } 398 enableSecure(value: boolean): this { 399 modifierWithKey(this._modifiersWithKeys, XComponentEnableSecureModifier.identity, XComponentEnableSecureModifier, value); 400 return this; 401 } 402 hdrBrightness(value: number): this { 403 modifierWithKey(this._modifiersWithKeys, XComponentHdrBrightnessModifier.identity, XComponentHdrBrightnessModifier, value); 404 return this; 405 } 406 enableTransparentLayer(value: boolean): this { 407 modifierWithKey(this._modifiersWithKeys, XComponentEnableTransparentLayerModifier.identity, XComponentEnableTransparentLayerModifier, value); 408 return this; 409 } 410} 411 412// @ts-ignore 413globalThis.XComponent.attributeModifier = function (modifier) { 414 const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); 415 let nativeNode = getUINativeModule().getFrameNodeById(elmtId); 416 let component = this.createOrGetNode(elmtId, () => { 417 return new ArkXComponentComponent(nativeNode); 418 }); 419 applyUIAttributes(modifier, nativeNode, component); 420 component.applyModifierPatch(); 421}; 422 423class XComponentInitializeModifier extends ModifierWithKey<XComponentParam> { 424 constructor(value: XComponentParam) { 425 super(value); 426 } 427 static identity: Symbol = Symbol('xComponentInitialize'); 428 applyPeer(node: KNode, reset: boolean): void { 429 if (reset) { 430 getUINativeModule().xComponent.resetXComponentInitialize(node); 431 } else { 432 getUINativeModule().xComponent.setXComponentInitialize(node, this.value?.id, 433 this.value?.type, this.value?.imageAIOptions, this.value?.libraryname, this.value?.controller); 434 } 435 } 436} 437 438class XComponentOpacityModifier extends ModifierWithKey<number | Resource> { 439 constructor(value: number | Resource) { 440 super(value); 441 } 442 static identity: Symbol = Symbol('xComponentOpacity'); 443 applyPeer(node: KNode, reset: boolean): void { 444 if (reset) { 445 getUINativeModule().xComponent.resetOpacity(node); 446 } else { 447 getUINativeModule().xComponent.setOpacity(node, this.value); 448 } 449 } 450 451 checkObjectDiff(): boolean { 452 return !isBaseOrResourceEqual(this.stageValue, this.value); 453 } 454} 455 456class XComponentBackgroundColorModifier extends ModifierWithKey<ResourceColor> { 457 constructor(value: ResourceColor) { 458 super(value); 459 } 460 static identity: Symbol = Symbol('xComponentBackgroundColor'); 461 applyPeer(node: KNode, reset: boolean): void { 462 if (reset) { 463 getUINativeModule().xComponent.resetBackgroundColor(node); 464 } else { 465 getUINativeModule().xComponent.setBackgroundColor(node, this.value); 466 } 467 } 468 469 checkObjectDiff(): boolean { 470 return !isBaseOrResourceEqual(this.stageValue, this.value); 471 } 472} 473 474class XComponentGrayscaleModifier extends ModifierWithKey<number> { 475 constructor(value: number) { 476 super(value); 477 } 478 static identity: Symbol = Symbol('xComponentGrayscale'); 479 applyPeer(node: KNode, reset: boolean): void { 480 if (reset) { 481 getUINativeModule().xComponent.resetGrayscale(node); 482 } else { 483 getUINativeModule().xComponent.setGrayscale(node, this.value); 484 } 485 } 486} 487 488class XComponentOnLoadModifier extends ModifierWithKey<(event?: object) => void> { 489 constructor(value: (event?: object) => void) { 490 super(value); 491 } 492 static identity: Symbol = Symbol('xComponentOnLoad'); 493 applyPeer(node: KNode, reset: boolean): void { 494 if (reset) { 495 getUINativeModule().xComponent.resetOnLoad(node); 496 } else { 497 getUINativeModule().xComponent.setOnLoad(node, this.value); 498 } 499 } 500} 501 502class XComponentOnDestroyModifier extends ModifierWithKey<() => void> { 503 constructor(value: () => void) { 504 super(value); 505 } 506 static identity: Symbol = Symbol('xComponentOnDestroy'); 507 applyPeer(node: KNode, reset: boolean): void { 508 if (reset) { 509 getUINativeModule().xComponent.resetOnDestroy(node); 510 } else { 511 getUINativeModule().xComponent.setOnDestroy(node, this.value); 512 } 513 } 514} 515 516class XComponentEnableAnalyzerModifier extends ModifierWithKey<boolean> { 517 constructor(value: boolean) { 518 super(value); 519 } 520 static identity: Symbol = Symbol('xComponentEnableAnalyzer'); 521 applyPeer(node: KNode, reset: boolean): void { 522 if (reset) { 523 getUINativeModule().xComponent.resetEnableAnalyzer(node); 524 } else { 525 getUINativeModule().xComponent.setEnableAnalyzer(node, this.value); 526 } 527 } 528 529 checkObjectDiff(): boolean { 530 return !isBaseOrResourceEqual(this.stageValue, this.value); 531 } 532} 533 534class XComponentEnableSecureModifier extends ModifierWithKey<boolean> { 535 constructor(value: boolean) { 536 super(value); 537 } 538 static identity: Symbol = Symbol('xComponentEnableSecure'); 539 applyPeer(node: KNode, reset: boolean): void { 540 if (reset) { 541 getUINativeModule().xComponent.resetEnableSecure(node); 542 } else { 543 getUINativeModule().xComponent.setEnableSecure(node, this.value); 544 } 545 } 546 547 checkObjectDiff(): boolean { 548 return !isBaseOrResourceEqual(this.stageValue, this.value); 549 } 550} 551 552class XComponentHdrBrightnessModifier extends ModifierWithKey<number> { 553 constructor(value: number) { 554 super(value); 555 } 556 static identity: Symbol = Symbol('xComponentHdrBrightness'); 557 applyPeer(node: KNode, reset: boolean): void { 558 if (reset) { 559 getUINativeModule().xComponent.resetHdrBrightness(node); 560 } else { 561 getUINativeModule().xComponent.setHdrBrightness(node, this.value); 562 } 563 } 564 565 checkObjectDiff(): boolean { 566 return !isBaseOrResourceEqual(this.stageValue, this.value); 567 } 568} 569 570class XComponentEnableTransparentLayerModifier extends ModifierWithKey<boolean> { 571 constructor(value: boolean) { 572 super(value); 573 } 574 static identity: Symbol = Symbol('xComponentEnableTransparentLayer'); 575 applyPeer(node: KNode, reset: boolean): void { 576 if (reset) { 577 getUINativeModule().xComponent.resetEnableTransparentLayer(node); 578 } else { 579 getUINativeModule().xComponent.setEnableTransparentLayer(node, this.value); 580 } 581 } 582 583 checkObjectDiff(): boolean { 584 return !isBaseOrResourceEqual(this.stageValue, this.value); 585 } 586} 587 588class XComponentRenderFitModifier extends ModifierWithKey<number> { 589 constructor(value: number) { 590 super(value); 591 } 592 static identity: Symbol = Symbol('xComponentRenderFit'); 593 applyPeer(node: KNode, reset: boolean): void { 594 if (reset) { 595 getUINativeModule().xComponent.resetRenderFit(node); 596 } else { 597 getUINativeModule().xComponent.setRenderFit(node, this.value); 598 } 599 } 600} 601