@lingxia/elements 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/platform.d.ts +1 -0
- package/dist/platform.js +4 -0
- package/dist/video.d.ts +3 -0
- package/dist/video.js +77 -1
- package/package.json +1 -1
- package/src/index.ts +0 -20
- package/src/platform.ts +4 -0
- package/src/video.ts +77 -1
- package/dist/input.d.ts +0 -117
- package/dist/input.js +0 -699
- package/dist/text_component_native_attrs.d.ts +0 -53
- package/dist/text_component_native_attrs.js +0 -111
- package/dist/text_component_shared.d.ts +0 -7
- package/dist/text_component_shared.js +0 -148
- package/dist/textarea.d.ts +0 -129
- package/dist/textarea.js +0 -841
- package/src/input.ts +0 -799
- package/src/text_component_native_attrs.ts +0 -137
- package/src/text_component_shared.ts +0 -147
- package/src/textarea.ts +0 -959
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export { registerVideoComponent, LxVideoElement, type LxVideoAttributes, } from "./video.js";
|
|
2
2
|
export { registerMediaSwiperComponent, LxMediaSwiperElement, type LxMediaSwiperAttributes, type LxMediaSwiperItem, type LxMediaSwiperChangeEvent, type LxMediaSwiperChangeEventDetail, type LxMediaSwiperTransitionEndEvent, type LxMediaSwiperTransitionEndEventDetail, type LxMediaSwiperItemEvent, type LxMediaSwiperEventDetail, type LxMediaSwiperEndReachedEvent, type LxMediaSwiperEndReachedEventDetail, type LxMediaSwiperErrorEvent, type LxMediaSwiperErrorEventDetail, type LxMediaSwiperChangeSource, type LxMediaSwiperErrorCode, } from "./media_swiper.js";
|
|
3
3
|
export { registerPickerComponent, LxPickerElement, type LxPickerAttributes, type LxPickerColumn, type LxPickerCascadingColumns, type LxPickerEvent, type LxPickerEventDetail, } from "./picker.js";
|
|
4
|
-
export { registerInputComponent, LxInputElement, type LxInputAttributes, type LxInputEvent, type LxInputEventDetail, } from "./input.js";
|
|
5
|
-
export { registerTextareaComponent, LxTextareaElement, type LxTextareaAttributes, type LxTextareaEvent, type LxTextareaEventDetail, } from "./textarea.js";
|
|
6
4
|
export { LxNavigatorElement, type LxNavigatorAttributes, type LxNavigatorEvent, type NavigatorEnvVersion, type NavigatorOpenType, type NavigatorQuery, type NavigatorQueryValue, type NavigatorTarget, } from "./navigator.js";
|
|
7
5
|
export { buildVideoNativeAttrs, buildMediaSwiperNativeAttrs, buildNavigatorNativeAttrs, buildPickerNativeAttrs, getPickerDisplayText, getPickerValueFromIndex, VIDEO_DOM_EVENT_MAP, MEDIA_SWIPER_DOM_EVENT_MAP, } from "./native_component_wrapper_shared.js";
|
|
8
|
-
export { buildInputNativeAttrs, buildTextareaNativeAttrs, } from "./text_component_native_attrs.js";
|
|
9
6
|
export { isHarmony, isIOS, isAndroid, isMacOS, isDesktop, getOS, } from "./platform.js";
|
|
10
7
|
export { ensureComponentId, rectEquals, NativeComponentUpdateState, type Rect, } from "./component.js";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export { registerVideoComponent, LxVideoElement, } from "./video.js";
|
|
2
2
|
export { registerMediaSwiperComponent, LxMediaSwiperElement, } from "./media_swiper.js";
|
|
3
3
|
export { registerPickerComponent, LxPickerElement, } from "./picker.js";
|
|
4
|
-
export { registerInputComponent, LxInputElement, } from "./input.js";
|
|
5
|
-
export { registerTextareaComponent, LxTextareaElement, } from "./textarea.js";
|
|
6
4
|
export { LxNavigatorElement, } from "./navigator.js";
|
|
7
5
|
export { buildVideoNativeAttrs, buildMediaSwiperNativeAttrs, buildNavigatorNativeAttrs, buildPickerNativeAttrs, getPickerDisplayText, getPickerValueFromIndex, VIDEO_DOM_EVENT_MAP, MEDIA_SWIPER_DOM_EVENT_MAP, } from "./native_component_wrapper_shared.js";
|
|
8
|
-
export { buildInputNativeAttrs, buildTextareaNativeAttrs, } from "./text_component_native_attrs.js";
|
|
9
6
|
export { isHarmony, isIOS, isAndroid, isMacOS, isDesktop, getOS, } from "./platform.js";
|
|
10
7
|
export { ensureComponentId, rectEquals, NativeComponentUpdateState, } from "./component.js";
|
package/dist/platform.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export declare function isHarmony(): boolean;
|
|
|
2
2
|
export declare function isIOS(): boolean;
|
|
3
3
|
export declare function isAndroid(): boolean;
|
|
4
4
|
export declare function isMacOS(): boolean;
|
|
5
|
+
export declare function isWindows(): boolean;
|
|
5
6
|
export declare function isDesktop(): boolean;
|
|
6
7
|
export declare function getOS(): string;
|
package/dist/platform.js
CHANGED
|
@@ -14,6 +14,10 @@ export function isMacOS() {
|
|
|
14
14
|
var _a, _b, _c;
|
|
15
15
|
return ((_c = (_b = (_a = window.LingXiaBridge) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.isMacOS) === null || _c === void 0 ? void 0 : _c.call(_b)) === true;
|
|
16
16
|
}
|
|
17
|
+
export function isWindows() {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
return ((_c = (_b = (_a = window.LingXiaBridge) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.isWindows) === null || _c === void 0 ? void 0 : _c.call(_b)) === true;
|
|
20
|
+
}
|
|
17
21
|
export function isDesktop() {
|
|
18
22
|
var _a, _b, _c;
|
|
19
23
|
return ((_c = (_b = (_a = window.LingXiaBridge) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.isDesktop) === null || _c === void 0 ? void 0 : _c.call(_b)) === true;
|
package/dist/video.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export declare class LxVideoElement extends HTMLElement {
|
|
|
50
50
|
private updateState;
|
|
51
51
|
private unregister?;
|
|
52
52
|
private resizeObserver?;
|
|
53
|
+
private winSettleFrame;
|
|
53
54
|
private pendingLayoutFrame;
|
|
54
55
|
private boundUpdatePosition;
|
|
55
56
|
private _handlers;
|
|
@@ -110,6 +111,7 @@ export declare class LxVideoElement extends HTMLElement {
|
|
|
110
111
|
set onratechange(cb: EventListener);
|
|
111
112
|
get onratechange(): EventListener;
|
|
112
113
|
private ensurePlaceholderStyle;
|
|
114
|
+
private syncPosterPlaceholder;
|
|
113
115
|
private collectProps;
|
|
114
116
|
private shouldRefreshForAttribute;
|
|
115
117
|
private startAttrObserver;
|
|
@@ -125,6 +127,7 @@ export declare class LxVideoElement extends HTMLElement {
|
|
|
125
127
|
private startSizeObserver;
|
|
126
128
|
private stopSizeObserver;
|
|
127
129
|
private scheduleMountRetry;
|
|
130
|
+
private scheduleWindowsMountSettle;
|
|
128
131
|
private scheduleIOSBootstrapFrames;
|
|
129
132
|
private mountOrUpdateHarmony;
|
|
130
133
|
private ensureHarmonyEmbed;
|
package/dist/video.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sendNativeComponentMessage, registerNativeComponentHandler, addNativeComponentLayoutInvalidationListener } from "./nativecomponent.js";
|
|
2
2
|
import { measureElement } from "./dom.js";
|
|
3
3
|
import { ensureComponentId, NativeComponentUpdateState, iOSNativeComponentHelper } from "./component.js";
|
|
4
|
-
import { isAndroid, isHarmony, isIOS } from "./platform.js";
|
|
4
|
+
import { isAndroid, isHarmony, isIOS, isWindows } from "./platform.js";
|
|
5
5
|
const HARMONY_PROPS_PREFIX = "data:application/json,";
|
|
6
6
|
// Component implementation
|
|
7
7
|
export class LxVideoElement extends HTMLElement {
|
|
@@ -10,6 +10,7 @@ export class LxVideoElement extends HTMLElement {
|
|
|
10
10
|
this.componentId = null;
|
|
11
11
|
this.mounted = false;
|
|
12
12
|
this.updateState = new NativeComponentUpdateState();
|
|
13
|
+
this.winSettleFrame = null;
|
|
13
14
|
this.pendingLayoutFrame = null;
|
|
14
15
|
this.boundUpdatePosition = this.updatePosition.bind(this);
|
|
15
16
|
this._handlers = {};
|
|
@@ -198,6 +199,17 @@ export class LxVideoElement extends HTMLElement {
|
|
|
198
199
|
else {
|
|
199
200
|
this.mountOrUpdate();
|
|
200
201
|
this.startTracking();
|
|
202
|
+
// Windows only: the WebView2 surface is created at an intermediate size
|
|
203
|
+
// and resized to its final content bounds shortly after this element
|
|
204
|
+
// mounts, which reflows the page and moves the element. Unlike the other
|
|
205
|
+
// platforms' webviews, WebView2 doesn't reliably fire the resize /
|
|
206
|
+
// ResizeObserver that would make us re-report, and an early update can be
|
|
207
|
+
// lost in the bridge transport during page load — so the native overlay
|
|
208
|
+
// can stay pinned at the mount-time rect. Re-measure + re-report across the
|
|
209
|
+
// settle window to land the final position. No-op on every other platform.
|
|
210
|
+
if (isWindows()) {
|
|
211
|
+
this.scheduleWindowsMountSettle();
|
|
212
|
+
}
|
|
201
213
|
}
|
|
202
214
|
}
|
|
203
215
|
disconnectedCallback() {
|
|
@@ -241,6 +253,9 @@ export class LxVideoElement extends HTMLElement {
|
|
|
241
253
|
}
|
|
242
254
|
if (!this.isConnected)
|
|
243
255
|
return;
|
|
256
|
+
if (name === "poster" || name === "object-fit" || name === "objectfit") {
|
|
257
|
+
this.syncPosterPlaceholder();
|
|
258
|
+
}
|
|
244
259
|
// Keep content-rotate/object-fit updates immediate across all native platforms.
|
|
245
260
|
const forcePropsUpdate = name === "content-rotate" || name === "object-fit" || name === "objectfit";
|
|
246
261
|
if (isHarmony() && forcePropsUpdate) {
|
|
@@ -314,6 +329,24 @@ export class LxVideoElement extends HTMLElement {
|
|
|
314
329
|
this.style.backgroundColor = "black";
|
|
315
330
|
if (!this.style.aspectRatio)
|
|
316
331
|
this.style.aspectRatio = "16 / 9";
|
|
332
|
+
this.syncPosterPlaceholder();
|
|
333
|
+
}
|
|
334
|
+
/// The poster doubles as the element's CSS background: on platforms
|
|
335
|
+
/// where the native layer hides while no media is presented (Windows:
|
|
336
|
+
/// initial state, after stop, on error), the placeholder shows it.
|
|
337
|
+
syncPosterPlaceholder() {
|
|
338
|
+
var _a;
|
|
339
|
+
const poster = this.getAttribute("poster");
|
|
340
|
+
if (!poster) {
|
|
341
|
+
this.style.backgroundImage = "";
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const objectFit = this.parseObjectFitValue((_a = this.getAttribute("object-fit")) !== null && _a !== void 0 ? _a : this.getAttribute("objectfit"));
|
|
345
|
+
const size = objectFit === "cover" ? "cover" : objectFit === "fill" ? "100% 100%" : "contain";
|
|
346
|
+
this.style.backgroundImage = `url("${poster.replace(/"/g, '\\"')}")`;
|
|
347
|
+
this.style.backgroundSize = size;
|
|
348
|
+
this.style.backgroundPosition = "center";
|
|
349
|
+
this.style.backgroundRepeat = "no-repeat";
|
|
317
350
|
}
|
|
318
351
|
collectProps() {
|
|
319
352
|
var _a;
|
|
@@ -520,6 +553,10 @@ export class LxVideoElement extends HTMLElement {
|
|
|
520
553
|
(_a = this.removeLayoutInvalidationListener) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
521
554
|
this.removeLayoutInvalidationListener = undefined;
|
|
522
555
|
this.stopSizeObserver();
|
|
556
|
+
if (this.winSettleFrame !== null) {
|
|
557
|
+
cancelAnimationFrame(this.winSettleFrame);
|
|
558
|
+
this.winSettleFrame = null;
|
|
559
|
+
}
|
|
523
560
|
if (this.pendingLayoutFrame !== null) {
|
|
524
561
|
cancelAnimationFrame(this.pendingLayoutFrame);
|
|
525
562
|
this.pendingLayoutFrame = null;
|
|
@@ -575,6 +612,45 @@ export class LxVideoElement extends HTMLElement {
|
|
|
575
612
|
this.mountOrUpdate();
|
|
576
613
|
});
|
|
577
614
|
}
|
|
615
|
+
scheduleWindowsMountSettle() {
|
|
616
|
+
if (typeof requestAnimationFrame === "undefined")
|
|
617
|
+
return;
|
|
618
|
+
if (this.winSettleFrame !== null)
|
|
619
|
+
return;
|
|
620
|
+
// Re-measure across the page-load / WebView2-resize settle window. The
|
|
621
|
+
// reflow that moves this element can land well after mount, so keep checking
|
|
622
|
+
// until the rect has been stable for a while; decide() dedups, so updates
|
|
623
|
+
// only fire when the rect changes.
|
|
624
|
+
let lastKey = "";
|
|
625
|
+
let stable = 0;
|
|
626
|
+
let elapsed = 0;
|
|
627
|
+
const tick = () => {
|
|
628
|
+
this.winSettleFrame = null;
|
|
629
|
+
if (!this.isConnected)
|
|
630
|
+
return;
|
|
631
|
+
// Force the re-send (don't dedup): an early update can be lost in the
|
|
632
|
+
// bridge transport during page load, and once the element has settled a
|
|
633
|
+
// dedup'd re-measure sees "no change" and never re-delivers it. Forcing
|
|
634
|
+
// each frame re-delivers the current rect until it lands.
|
|
635
|
+
this.mountOrUpdate(true);
|
|
636
|
+
const r = this.getBoundingClientRect();
|
|
637
|
+
const key = `${Math.round(r.top)}:${Math.round(r.width)}`;
|
|
638
|
+
if (key === lastKey) {
|
|
639
|
+
stable += 1;
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
stable = 0;
|
|
643
|
+
lastKey = key;
|
|
644
|
+
}
|
|
645
|
+
elapsed += 1;
|
|
646
|
+
// Keep re-sending until the layout has held steady for a while (so a late
|
|
647
|
+
// settle is still caught), capped so it never runs unbounded.
|
|
648
|
+
if (stable < 12 && elapsed < 180) {
|
|
649
|
+
this.winSettleFrame = requestAnimationFrame(tick);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
this.winSettleFrame = requestAnimationFrame(tick);
|
|
653
|
+
}
|
|
578
654
|
scheduleIOSBootstrapFrames() {
|
|
579
655
|
if (!isIOS())
|
|
580
656
|
return;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -33,21 +33,6 @@ export {
|
|
|
33
33
|
type LxPickerEventDetail,
|
|
34
34
|
} from "./picker.js";
|
|
35
35
|
|
|
36
|
-
export {
|
|
37
|
-
registerInputComponent,
|
|
38
|
-
LxInputElement,
|
|
39
|
-
type LxInputAttributes,
|
|
40
|
-
type LxInputEvent,
|
|
41
|
-
type LxInputEventDetail,
|
|
42
|
-
} from "./input.js";
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
registerTextareaComponent,
|
|
46
|
-
LxTextareaElement,
|
|
47
|
-
type LxTextareaAttributes,
|
|
48
|
-
type LxTextareaEvent,
|
|
49
|
-
type LxTextareaEventDetail,
|
|
50
|
-
} from "./textarea.js";
|
|
51
36
|
|
|
52
37
|
export {
|
|
53
38
|
LxNavigatorElement,
|
|
@@ -71,11 +56,6 @@ export {
|
|
|
71
56
|
MEDIA_SWIPER_DOM_EVENT_MAP,
|
|
72
57
|
} from "./native_component_wrapper_shared.js";
|
|
73
58
|
|
|
74
|
-
export {
|
|
75
|
-
buildInputNativeAttrs,
|
|
76
|
-
buildTextareaNativeAttrs,
|
|
77
|
-
} from "./text_component_native_attrs.js";
|
|
78
|
-
|
|
79
59
|
export {
|
|
80
60
|
isHarmony,
|
|
81
61
|
isIOS,
|
package/src/platform.ts
CHANGED
|
@@ -16,6 +16,10 @@ export function isMacOS(): boolean {
|
|
|
16
16
|
return window.LingXiaBridge?.platform?.isMacOS?.() === true;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
export function isWindows(): boolean {
|
|
20
|
+
return window.LingXiaBridge?.platform?.isWindows?.() === true;
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
export function isDesktop(): boolean {
|
|
20
24
|
return window.LingXiaBridge?.platform?.isDesktop?.() === true;
|
|
21
25
|
}
|
package/src/video.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./nativecomponent.js";
|
|
6
6
|
import { measureElement } from "./dom.js";
|
|
7
7
|
import { ensureComponentId, NativeComponentUpdateState, iOSNativeComponentHelper } from "./component.js";
|
|
8
|
-
import { isAndroid, isHarmony, isIOS } from "./platform.js";
|
|
8
|
+
import { isAndroid, isHarmony, isIOS, isWindows } from "./platform.js";
|
|
9
9
|
|
|
10
10
|
const HARMONY_PROPS_PREFIX = "data:application/json,";
|
|
11
11
|
|
|
@@ -85,6 +85,7 @@ export class LxVideoElement extends HTMLElement {
|
|
|
85
85
|
private updateState = new NativeComponentUpdateState();
|
|
86
86
|
private unregister?: () => void;
|
|
87
87
|
private resizeObserver?: ResizeObserver;
|
|
88
|
+
private winSettleFrame: number | null = null;
|
|
88
89
|
private pendingLayoutFrame: number | null = null;
|
|
89
90
|
private boundUpdatePosition = this.updatePosition.bind(this);
|
|
90
91
|
private _handlers: Record<string, EventListenerOrEventListenerObject> = {};
|
|
@@ -268,6 +269,17 @@ export class LxVideoElement extends HTMLElement {
|
|
|
268
269
|
} else {
|
|
269
270
|
this.mountOrUpdate();
|
|
270
271
|
this.startTracking();
|
|
272
|
+
// Windows only: the WebView2 surface is created at an intermediate size
|
|
273
|
+
// and resized to its final content bounds shortly after this element
|
|
274
|
+
// mounts, which reflows the page and moves the element. Unlike the other
|
|
275
|
+
// platforms' webviews, WebView2 doesn't reliably fire the resize /
|
|
276
|
+
// ResizeObserver that would make us re-report, and an early update can be
|
|
277
|
+
// lost in the bridge transport during page load — so the native overlay
|
|
278
|
+
// can stay pinned at the mount-time rect. Re-measure + re-report across the
|
|
279
|
+
// settle window to land the final position. No-op on every other platform.
|
|
280
|
+
if (isWindows()) {
|
|
281
|
+
this.scheduleWindowsMountSettle();
|
|
282
|
+
}
|
|
271
283
|
}
|
|
272
284
|
}
|
|
273
285
|
|
|
@@ -314,6 +326,9 @@ export class LxVideoElement extends HTMLElement {
|
|
|
314
326
|
}
|
|
315
327
|
}
|
|
316
328
|
if (!this.isConnected) return;
|
|
329
|
+
if (name === "poster" || name === "object-fit" || name === "objectfit") {
|
|
330
|
+
this.syncPosterPlaceholder();
|
|
331
|
+
}
|
|
317
332
|
// Keep content-rotate/object-fit updates immediate across all native platforms.
|
|
318
333
|
const forcePropsUpdate = name === "content-rotate" || name === "object-fit" || name === "objectfit";
|
|
319
334
|
if (isHarmony() && forcePropsUpdate) {
|
|
@@ -399,6 +414,27 @@ export class LxVideoElement extends HTMLElement {
|
|
|
399
414
|
if (!this.style.position) this.style.position = "relative"; // Needed for iOS scroll container
|
|
400
415
|
if (!this.style.backgroundColor) this.style.backgroundColor = "black";
|
|
401
416
|
if (!this.style.aspectRatio) this.style.aspectRatio = "16 / 9";
|
|
417
|
+
this.syncPosterPlaceholder();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/// The poster doubles as the element's CSS background: on platforms
|
|
421
|
+
/// where the native layer hides while no media is presented (Windows:
|
|
422
|
+
/// initial state, after stop, on error), the placeholder shows it.
|
|
423
|
+
private syncPosterPlaceholder() {
|
|
424
|
+
const poster = this.getAttribute("poster");
|
|
425
|
+
if (!poster) {
|
|
426
|
+
this.style.backgroundImage = "";
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const objectFit = this.parseObjectFitValue(
|
|
430
|
+
this.getAttribute("object-fit") ?? this.getAttribute("objectfit")
|
|
431
|
+
);
|
|
432
|
+
const size =
|
|
433
|
+
objectFit === "cover" ? "cover" : objectFit === "fill" ? "100% 100%" : "contain";
|
|
434
|
+
this.style.backgroundImage = `url("${poster.replace(/"/g, '\\"')}")`;
|
|
435
|
+
this.style.backgroundSize = size;
|
|
436
|
+
this.style.backgroundPosition = "center";
|
|
437
|
+
this.style.backgroundRepeat = "no-repeat";
|
|
402
438
|
}
|
|
403
439
|
|
|
404
440
|
private collectProps() {
|
|
@@ -621,6 +657,10 @@ export class LxVideoElement extends HTMLElement {
|
|
|
621
657
|
this.removeLayoutInvalidationListener?.();
|
|
622
658
|
this.removeLayoutInvalidationListener = undefined;
|
|
623
659
|
this.stopSizeObserver();
|
|
660
|
+
if (this.winSettleFrame !== null) {
|
|
661
|
+
cancelAnimationFrame(this.winSettleFrame);
|
|
662
|
+
this.winSettleFrame = null;
|
|
663
|
+
}
|
|
624
664
|
if (this.pendingLayoutFrame !== null) {
|
|
625
665
|
cancelAnimationFrame(this.pendingLayoutFrame);
|
|
626
666
|
this.pendingLayoutFrame = null;
|
|
@@ -675,6 +715,42 @@ export class LxVideoElement extends HTMLElement {
|
|
|
675
715
|
});
|
|
676
716
|
}
|
|
677
717
|
|
|
718
|
+
private scheduleWindowsMountSettle(): void {
|
|
719
|
+
if (typeof requestAnimationFrame === "undefined") return;
|
|
720
|
+
if (this.winSettleFrame !== null) return;
|
|
721
|
+
// Re-measure across the page-load / WebView2-resize settle window. The
|
|
722
|
+
// reflow that moves this element can land well after mount, so keep checking
|
|
723
|
+
// until the rect has been stable for a while; decide() dedups, so updates
|
|
724
|
+
// only fire when the rect changes.
|
|
725
|
+
let lastKey = "";
|
|
726
|
+
let stable = 0;
|
|
727
|
+
let elapsed = 0;
|
|
728
|
+
const tick = () => {
|
|
729
|
+
this.winSettleFrame = null;
|
|
730
|
+
if (!this.isConnected) return;
|
|
731
|
+
// Force the re-send (don't dedup): an early update can be lost in the
|
|
732
|
+
// bridge transport during page load, and once the element has settled a
|
|
733
|
+
// dedup'd re-measure sees "no change" and never re-delivers it. Forcing
|
|
734
|
+
// each frame re-delivers the current rect until it lands.
|
|
735
|
+
this.mountOrUpdate(true);
|
|
736
|
+
const r = this.getBoundingClientRect();
|
|
737
|
+
const key = `${Math.round(r.top)}:${Math.round(r.width)}`;
|
|
738
|
+
if (key === lastKey) {
|
|
739
|
+
stable += 1;
|
|
740
|
+
} else {
|
|
741
|
+
stable = 0;
|
|
742
|
+
lastKey = key;
|
|
743
|
+
}
|
|
744
|
+
elapsed += 1;
|
|
745
|
+
// Keep re-sending until the layout has held steady for a while (so a late
|
|
746
|
+
// settle is still caught), capped so it never runs unbounded.
|
|
747
|
+
if (stable < 12 && elapsed < 180) {
|
|
748
|
+
this.winSettleFrame = requestAnimationFrame(tick);
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
this.winSettleFrame = requestAnimationFrame(tick);
|
|
752
|
+
}
|
|
753
|
+
|
|
678
754
|
private scheduleIOSBootstrapFrames(): void {
|
|
679
755
|
if (!isIOS()) return;
|
|
680
756
|
// Keep a short frame-based bootstrap window so late-created WKChildScrollView
|
package/dist/input.d.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
export interface LxInputEventDetail {
|
|
2
|
-
value?: string;
|
|
3
|
-
cursor?: number;
|
|
4
|
-
keyCode?: number;
|
|
5
|
-
height?: number;
|
|
6
|
-
duration?: number;
|
|
7
|
-
encryptedValue?: string;
|
|
8
|
-
encryptError?: string;
|
|
9
|
-
pass?: boolean;
|
|
10
|
-
timeout?: boolean;
|
|
11
|
-
}
|
|
12
|
-
export interface LxInputEvent extends CustomEvent<LxInputEventDetail> {
|
|
13
|
-
detail: LxInputEventDetail;
|
|
14
|
-
}
|
|
15
|
-
export type LxInputAttributes = {
|
|
16
|
-
id?: string;
|
|
17
|
-
value?: string;
|
|
18
|
-
type?: 'text' | 'number' | 'password' | 'digit';
|
|
19
|
-
password?: boolean | string;
|
|
20
|
-
placeholder?: string;
|
|
21
|
-
'placeholder-style'?: string;
|
|
22
|
-
'placeholder-class'?: string;
|
|
23
|
-
maxlength?: number | string;
|
|
24
|
-
'cursor-spacing'?: number | string;
|
|
25
|
-
'auto-focus'?: boolean | string;
|
|
26
|
-
disabled?: boolean | string;
|
|
27
|
-
focus?: boolean | string;
|
|
28
|
-
'confirm-type'?: 'send' | 'search' | 'next' | 'go' | 'done';
|
|
29
|
-
'always-embed'?: boolean | string;
|
|
30
|
-
'confirm-hold'?: boolean | string;
|
|
31
|
-
cursor?: number | string;
|
|
32
|
-
'cursor-color'?: string;
|
|
33
|
-
'selection-start'?: number | string;
|
|
34
|
-
'selection-end'?: number | string;
|
|
35
|
-
'adjust-position'?: boolean | string;
|
|
36
|
-
'hold-keyboard'?: boolean | string;
|
|
37
|
-
className?: string;
|
|
38
|
-
style?: any;
|
|
39
|
-
ref?: any;
|
|
40
|
-
onInput?: (e: LxInputEvent) => void;
|
|
41
|
-
onChange?: (e: LxInputEvent) => void;
|
|
42
|
-
onFocus?: (e: LxInputEvent) => void;
|
|
43
|
-
onBlur?: (e: LxInputEvent) => void;
|
|
44
|
-
onConfirm?: (e: LxInputEvent) => void;
|
|
45
|
-
onKeyboardheightchange?: (e: LxInputEvent) => void;
|
|
46
|
-
onNicknamereview?: (e: LxInputEvent) => void;
|
|
47
|
-
pageBindings?: Record<string, string>;
|
|
48
|
-
};
|
|
49
|
-
declare global {
|
|
50
|
-
namespace JSX {
|
|
51
|
-
interface IntrinsicElements {
|
|
52
|
-
"lx-input": LxInputAttributes;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
export declare class LxInputElement extends HTMLElement {
|
|
57
|
-
static get observedAttributes(): string[];
|
|
58
|
-
private componentId;
|
|
59
|
-
private mounted;
|
|
60
|
-
private unregister?;
|
|
61
|
-
private _handlers;
|
|
62
|
-
private rawHandlers;
|
|
63
|
-
private harmonyEmbed?;
|
|
64
|
-
private lastHarmonyProps?;
|
|
65
|
-
private pendingHarmonyProps?;
|
|
66
|
-
private pendingHarmonyRetryTimer;
|
|
67
|
-
private pendingHarmonyRetryCount;
|
|
68
|
-
private attrObserver?;
|
|
69
|
-
private shadow?;
|
|
70
|
-
private innerInput?;
|
|
71
|
-
private readonly updateState;
|
|
72
|
-
private resizeObserver?;
|
|
73
|
-
private pendingLayoutFrame;
|
|
74
|
-
private focusLayoutSyncTimer;
|
|
75
|
-
private readonly layoutEventListener;
|
|
76
|
-
private _pageBindings;
|
|
77
|
-
set pageBindings(bindings: Record<string, string>);
|
|
78
|
-
get pageBindings(): Record<string, string>;
|
|
79
|
-
private upgradeProperty;
|
|
80
|
-
private registerNativeHandler;
|
|
81
|
-
private unmountNativeComponentById;
|
|
82
|
-
private teardownHarmonyEmbed;
|
|
83
|
-
connectedCallback(): void;
|
|
84
|
-
disconnectedCallback(): void;
|
|
85
|
-
attributeChangedCallback(name: string): void;
|
|
86
|
-
private getAttr;
|
|
87
|
-
private getBoolAttr;
|
|
88
|
-
private getNumAttr;
|
|
89
|
-
private getPropOrAttr;
|
|
90
|
-
private shouldTrackNativeLayout;
|
|
91
|
-
private startTracking;
|
|
92
|
-
private stopTracking;
|
|
93
|
-
private startSizeObserver;
|
|
94
|
-
private stopSizeObserver;
|
|
95
|
-
private schedulePositionSync;
|
|
96
|
-
private collectProps;
|
|
97
|
-
private getHostTextColor;
|
|
98
|
-
private resyncHarmonyLayoutAfterFocus;
|
|
99
|
-
private startFocusLayoutSync;
|
|
100
|
-
private stopFocusLayoutSync;
|
|
101
|
-
private shouldRefreshForAttribute;
|
|
102
|
-
private startAttrObserver;
|
|
103
|
-
private stopAttrObserver;
|
|
104
|
-
private collectDataset;
|
|
105
|
-
private getInputType;
|
|
106
|
-
private mountDesktopInput;
|
|
107
|
-
private mountInput;
|
|
108
|
-
syncNativeProps(): void;
|
|
109
|
-
private ensureHostLayout;
|
|
110
|
-
set oninput(cb: EventListener | null);
|
|
111
|
-
get oninput(): EventListener | null;
|
|
112
|
-
private ensureHarmonyEmbed;
|
|
113
|
-
private encodeHarmonyProps;
|
|
114
|
-
private pushHarmonyPropsUpdate;
|
|
115
|
-
private scheduleHarmonyPropsRetry;
|
|
116
|
-
}
|
|
117
|
-
export declare function registerInputComponent(): void;
|