@netless/window-manager 1.0.13-test.19 → 1.0.13-test.20
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 +12 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +332 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Utils/Reactive.ts +2 -2
- package/src/View/MainView.ts +0 -1
- package/src/index.ts +430 -8
package/package.json
CHANGED
package/src/Utils/Reactive.ts
CHANGED
|
@@ -30,8 +30,8 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export const safeListenPropsUpdated = <T
|
|
34
|
-
getProps: () => T,
|
|
33
|
+
export const safeListenPropsUpdated = <T extends Record<string, unknown>>(
|
|
34
|
+
getProps: () => T | null | undefined,
|
|
35
35
|
callback: AkkoObjectUpdatedListener<T>,
|
|
36
36
|
onDestroyed?: (props: unknown) => void
|
|
37
37
|
) => {
|
package/src/View/MainView.ts
CHANGED
|
@@ -11,7 +11,6 @@ import type { AppManager } from "../AppManager";
|
|
|
11
11
|
import { Events } from "../constants";
|
|
12
12
|
import { LocalConsole } from "../Utils/log";
|
|
13
13
|
|
|
14
|
-
(window as any).___local_log = (window as any).___local_log || new Set();
|
|
15
14
|
export class MainViewProxy {
|
|
16
15
|
/** Refresh the view's camera in an interval of 1.5s. */
|
|
17
16
|
public polling = false;
|
package/src/index.ts
CHANGED
|
@@ -199,6 +199,25 @@ export type MountParams = {
|
|
|
199
199
|
useBoxesStatus?: boolean;
|
|
200
200
|
};
|
|
201
201
|
|
|
202
|
+
type DiagnosticColorChannels = {
|
|
203
|
+
raw: string;
|
|
204
|
+
r?: number;
|
|
205
|
+
g?: number;
|
|
206
|
+
b?: number;
|
|
207
|
+
a?: number;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
type DiagnosticRect = {
|
|
211
|
+
x: number;
|
|
212
|
+
y: number;
|
|
213
|
+
width: number;
|
|
214
|
+
height: number;
|
|
215
|
+
top: number;
|
|
216
|
+
right: number;
|
|
217
|
+
bottom: number;
|
|
218
|
+
left: number;
|
|
219
|
+
};
|
|
220
|
+
|
|
202
221
|
export const reconnectRefresher = new ReconnectRefresher({ emitter: internalEmitter });
|
|
203
222
|
export class WindowManager
|
|
204
223
|
extends InvisiblePlugin<WindowMangerAttributes, any>
|
|
@@ -253,16 +272,9 @@ export class WindowManager
|
|
|
253
272
|
super(context);
|
|
254
273
|
WindowManager.displayer = context.displayer;
|
|
255
274
|
(window as any).NETLESS_DEPS = __APP_DEPENDENCIES__;
|
|
256
|
-
this.visibleStateListener();
|
|
257
|
-
document.addEventListener("visibilitychange", this.visibleStateListener);
|
|
258
275
|
this.emitter.on('mainViewScenePathChange', this.onMainViewScenePathChangeHandler)
|
|
259
276
|
}
|
|
260
277
|
|
|
261
|
-
|
|
262
|
-
private visibleStateListener = () => {
|
|
263
|
-
console.log("[window-manager] visibleStateListener isVisible:" + !document.hidden);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
278
|
public static onCreate(manager: WindowManager) {
|
|
267
279
|
WindowManager._resolve(manager);
|
|
268
280
|
}
|
|
@@ -400,6 +412,7 @@ export class WindowManager
|
|
|
400
412
|
|
|
401
413
|
public onMainViewScenePathChangeHandler = (scenePath: string) => {
|
|
402
414
|
const mainViewElement = this.mainView.divElement;
|
|
415
|
+
this.logMainViewVisibilityDiagnostics("onMainViewScenePathChange", scenePath, mainViewElement);
|
|
403
416
|
if (mainViewElement) {
|
|
404
417
|
const backgroundImage = mainViewElement.querySelector('.background img');
|
|
405
418
|
if (backgroundImage) {
|
|
@@ -416,6 +429,415 @@ export class WindowManager
|
|
|
416
429
|
console.log("[window-manager] onMainViewScenePathChange scenePath:" + scenePath + ' mainViewElement is not found');
|
|
417
430
|
}
|
|
418
431
|
|
|
432
|
+
public logMainViewVisibilityDiagnostics(
|
|
433
|
+
tag: string,
|
|
434
|
+
scenePath?: string,
|
|
435
|
+
mainViewElement?: HTMLDivElement | null
|
|
436
|
+
): void {
|
|
437
|
+
const element = mainViewElement ?? this.mainView?.divElement;
|
|
438
|
+
const label = scenePath ? `${tag}:${scenePath}` : tag;
|
|
439
|
+
const payload = this.collectMainViewVisibilityDiagnostics(element, scenePath);
|
|
440
|
+
this.emitMainViewVisibilityDiagnostic(label, payload.summary);
|
|
441
|
+
if (payload.details) {
|
|
442
|
+
this.emitMainViewVisibilityDiagnostic(`${label}:details`, payload.details);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private emitMainViewVisibilityDiagnostic(tag: string, payload: unknown): void {
|
|
447
|
+
const content = `[window-manager][visibility][${tag}] ${JSON.stringify(payload)}`;
|
|
448
|
+
// console.log(content);
|
|
449
|
+
this._roomLogger?.info(content);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
private collectMainViewVisibilityDiagnostics(
|
|
453
|
+
mainViewElement: HTMLDivElement | null | undefined,
|
|
454
|
+
scenePath?: string
|
|
455
|
+
): {
|
|
456
|
+
summary: Record<string, any>;
|
|
457
|
+
details: Record<string, any> | null;
|
|
458
|
+
} {
|
|
459
|
+
const element = mainViewElement ?? null;
|
|
460
|
+
const backgroundImage = element?.querySelector(".background img") as HTMLImageElement | null;
|
|
461
|
+
const elementDiagnostic = element ? this.collectElementDiagnostic(element) : null;
|
|
462
|
+
const chainDiagnostics = element ? this.collectElementChainDiagnostics(element) : [];
|
|
463
|
+
const elementRect = element?.getBoundingClientRect?.() ?? null;
|
|
464
|
+
const centerPoint = elementRect
|
|
465
|
+
? {
|
|
466
|
+
x: elementRect.left + elementRect.width / 2,
|
|
467
|
+
y: elementRect.top + elementRect.height / 2,
|
|
468
|
+
}
|
|
469
|
+
: undefined;
|
|
470
|
+
const topElement =
|
|
471
|
+
centerPoint &&
|
|
472
|
+
Number.isFinite(centerPoint.x) &&
|
|
473
|
+
Number.isFinite(centerPoint.y)
|
|
474
|
+
? document.elementFromPoint(centerPoint.x, centerPoint.y)
|
|
475
|
+
: null;
|
|
476
|
+
const overlayStack =
|
|
477
|
+
centerPoint &&
|
|
478
|
+
Number.isFinite(centerPoint.x) &&
|
|
479
|
+
Number.isFinite(centerPoint.y) &&
|
|
480
|
+
document.elementsFromPoint
|
|
481
|
+
? document
|
|
482
|
+
.elementsFromPoint(centerPoint.x, centerPoint.y)
|
|
483
|
+
.slice(0, 10)
|
|
484
|
+
.map(item => this.describeElement(item))
|
|
485
|
+
.filter((item): item is string => item !== null)
|
|
486
|
+
: [];
|
|
487
|
+
const topElementDiagnostic = topElement ? this.collectElementDiagnostic(topElement) : null;
|
|
488
|
+
const backgroundImageDiagnostic = backgroundImage
|
|
489
|
+
? this.collectImageDiagnostic(backgroundImage)
|
|
490
|
+
: null;
|
|
491
|
+
const blockers: string[] = [];
|
|
492
|
+
const warnings: string[] = [];
|
|
493
|
+
const suspiciousAncestors: Array<Record<string, any>> = [];
|
|
494
|
+
const mainViewBlockers: string[] = [];
|
|
495
|
+
const mainViewWarnings: string[] = [];
|
|
496
|
+
|
|
497
|
+
if (!element) {
|
|
498
|
+
blockers.push("mainViewElement.missing");
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (document.hidden || document.visibilityState === "hidden") {
|
|
502
|
+
blockers.push("document.hidden");
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (elementDiagnostic) {
|
|
506
|
+
this.appendRenderImpactIssues(
|
|
507
|
+
"mainViewElement",
|
|
508
|
+
elementDiagnostic,
|
|
509
|
+
mainViewBlockers,
|
|
510
|
+
mainViewWarnings
|
|
511
|
+
);
|
|
512
|
+
blockers.push(...mainViewBlockers);
|
|
513
|
+
warnings.push(...mainViewWarnings);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
chainDiagnostics.slice(1).forEach((diagnostic, index) => {
|
|
517
|
+
const ancestorBlockers: string[] = [];
|
|
518
|
+
const ancestorWarnings: string[] = [];
|
|
519
|
+
this.appendRenderImpactIssues(
|
|
520
|
+
`ancestor[${index + 1}]`,
|
|
521
|
+
diagnostic,
|
|
522
|
+
ancestorBlockers,
|
|
523
|
+
ancestorWarnings
|
|
524
|
+
);
|
|
525
|
+
if (ancestorBlockers.length > 0 || ancestorWarnings.length > 0) {
|
|
526
|
+
blockers.push(...ancestorBlockers);
|
|
527
|
+
warnings.push(...ancestorWarnings);
|
|
528
|
+
suspiciousAncestors.push(this.pickRenderRelevantFields(diagnostic));
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
let backgroundImageStatus: Record<string, any> | null = null;
|
|
533
|
+
const backgroundImageBlockers: string[] = [];
|
|
534
|
+
const backgroundImageWarnings: string[] = [];
|
|
535
|
+
if (backgroundImageDiagnostic) {
|
|
536
|
+
backgroundImageStatus = this.pickBackgroundImageStatus(backgroundImageDiagnostic);
|
|
537
|
+
this.appendRenderImpactIssues(
|
|
538
|
+
"backgroundImage",
|
|
539
|
+
backgroundImageDiagnostic,
|
|
540
|
+
backgroundImageBlockers,
|
|
541
|
+
backgroundImageWarnings
|
|
542
|
+
);
|
|
543
|
+
blockers.push(...backgroundImageBlockers);
|
|
544
|
+
warnings.push(...backgroundImageWarnings);
|
|
545
|
+
if (backgroundImageDiagnostic.complete === false) {
|
|
546
|
+
warnings.push("backgroundImage.loading");
|
|
547
|
+
} else if (backgroundImageDiagnostic.naturalWidth === 0) {
|
|
548
|
+
warnings.push("backgroundImage.empty");
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
let topElementSummary: Record<string, any> | null = null;
|
|
553
|
+
if (topElementDiagnostic) {
|
|
554
|
+
const coveredByOutsideElement = Boolean(
|
|
555
|
+
element && topElement && topElement !== element && !element.contains(topElement)
|
|
556
|
+
);
|
|
557
|
+
topElementSummary = {
|
|
558
|
+
node: topElementDiagnostic.node,
|
|
559
|
+
coveredByOutsideElement,
|
|
560
|
+
};
|
|
561
|
+
if (coveredByOutsideElement) {
|
|
562
|
+
warnings.push(`center.coveredBy:${topElementDiagnostic.node}`);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const summary: Record<string, any> = {
|
|
567
|
+
scenePath: scenePath || null,
|
|
568
|
+
timestamp: new Date().toISOString(),
|
|
569
|
+
status:
|
|
570
|
+
blockers.length > 0
|
|
571
|
+
? "blocked"
|
|
572
|
+
: warnings.length > 0
|
|
573
|
+
? "uncertain"
|
|
574
|
+
: "likely-renderable",
|
|
575
|
+
canRender: blockers.length === 0,
|
|
576
|
+
blockers,
|
|
577
|
+
warnings,
|
|
578
|
+
};
|
|
579
|
+
if (
|
|
580
|
+
backgroundImageStatus &&
|
|
581
|
+
backgroundImageDiagnostic &&
|
|
582
|
+
(backgroundImageDiagnostic.complete === false ||
|
|
583
|
+
backgroundImageDiagnostic.naturalWidth === 0)
|
|
584
|
+
) {
|
|
585
|
+
summary.backgroundImage = backgroundImageStatus;
|
|
586
|
+
}
|
|
587
|
+
if (topElementSummary?.coveredByOutsideElement) {
|
|
588
|
+
summary.coveringElement = topElementSummary.node;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const shouldEmitDetails =
|
|
592
|
+
blockers.length > 0 ||
|
|
593
|
+
warnings.some(
|
|
594
|
+
warning =>
|
|
595
|
+
warning !== "backgroundImage.loading" &&
|
|
596
|
+
warning !== "backgroundImage.empty"
|
|
597
|
+
);
|
|
598
|
+
const details: Record<string, any> = {};
|
|
599
|
+
if ((mainViewBlockers.length > 0 || mainViewWarnings.length > 0) && elementDiagnostic) {
|
|
600
|
+
details.mainViewElement = this.pickRenderRelevantFields(elementDiagnostic);
|
|
601
|
+
}
|
|
602
|
+
if (
|
|
603
|
+
suspiciousAncestors.length > 0
|
|
604
|
+
) {
|
|
605
|
+
details.suspiciousAncestors = suspiciousAncestors;
|
|
606
|
+
}
|
|
607
|
+
if (
|
|
608
|
+
backgroundImageDiagnostic &&
|
|
609
|
+
(backgroundImageBlockers.length > 0 ||
|
|
610
|
+
backgroundImageWarnings.length > 0 ||
|
|
611
|
+
backgroundImageDiagnostic.complete === false ||
|
|
612
|
+
backgroundImageDiagnostic.naturalWidth === 0)
|
|
613
|
+
) {
|
|
614
|
+
details.backgroundImage = {
|
|
615
|
+
...this.pickRenderRelevantFields(backgroundImageDiagnostic),
|
|
616
|
+
loadState: backgroundImageStatus,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
if (topElementSummary?.coveredByOutsideElement && topElementDiagnostic) {
|
|
620
|
+
details.topElementAtCenter = {
|
|
621
|
+
...this.pickRenderRelevantFields(topElementDiagnostic),
|
|
622
|
+
overlayStack,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return {
|
|
627
|
+
summary,
|
|
628
|
+
details: shouldEmitDetails && Object.keys(details).length > 0 ? details : null,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
private collectElementChainDiagnostics(element: Element): Array<Record<string, any>> {
|
|
633
|
+
const chain: Array<Record<string, any>> = [];
|
|
634
|
+
let current: Element | null = element;
|
|
635
|
+
while (current) {
|
|
636
|
+
const diagnostic = this.collectElementDiagnostic(current);
|
|
637
|
+
if (diagnostic) {
|
|
638
|
+
chain.push(diagnostic);
|
|
639
|
+
}
|
|
640
|
+
current = current.parentElement;
|
|
641
|
+
}
|
|
642
|
+
return chain;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
private collectImageDiagnostic(image: HTMLImageElement): Record<string, any> {
|
|
646
|
+
const diagnostic = this.collectElementDiagnostic(image);
|
|
647
|
+
return {
|
|
648
|
+
...diagnostic,
|
|
649
|
+
currentSrc: image.currentSrc,
|
|
650
|
+
src: image.getAttribute("src"),
|
|
651
|
+
complete: image.complete,
|
|
652
|
+
naturalWidth: image.naturalWidth,
|
|
653
|
+
naturalHeight: image.naturalHeight,
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
private appendRenderImpactIssues(
|
|
658
|
+
label: string,
|
|
659
|
+
diagnostic: Record<string, any>,
|
|
660
|
+
blockers: string[],
|
|
661
|
+
warnings: string[]
|
|
662
|
+
): void {
|
|
663
|
+
const opacity = Number.parseFloat(diagnostic.opacity || "1");
|
|
664
|
+
if (diagnostic.hiddenAttribute) {
|
|
665
|
+
blockers.push(`${label}.hiddenAttribute`);
|
|
666
|
+
}
|
|
667
|
+
if (diagnostic.display === "none") {
|
|
668
|
+
blockers.push(`${label}.display:none`);
|
|
669
|
+
}
|
|
670
|
+
if (diagnostic.visibility === "hidden" || diagnostic.visibility === "collapse") {
|
|
671
|
+
blockers.push(`${label}.visibility:${diagnostic.visibility}`);
|
|
672
|
+
}
|
|
673
|
+
if (Number.isFinite(opacity) && opacity <= 0.01) {
|
|
674
|
+
blockers.push(`${label}.opacity:${diagnostic.opacity}`);
|
|
675
|
+
}
|
|
676
|
+
if (diagnostic.contentVisibility === "hidden") {
|
|
677
|
+
blockers.push(`${label}.contentVisibility:hidden`);
|
|
678
|
+
}
|
|
679
|
+
if (diagnostic.transform !== "none") {
|
|
680
|
+
warnings.push(`${label}.transform`);
|
|
681
|
+
}
|
|
682
|
+
if (diagnostic.filter !== "none") {
|
|
683
|
+
warnings.push(`${label}.filter`);
|
|
684
|
+
}
|
|
685
|
+
if (diagnostic.backdropFilter !== "none") {
|
|
686
|
+
warnings.push(`${label}.backdropFilter`);
|
|
687
|
+
}
|
|
688
|
+
if (diagnostic.clipPath !== "none") {
|
|
689
|
+
warnings.push(`${label}.clipPath`);
|
|
690
|
+
}
|
|
691
|
+
if (diagnostic.maskImage !== "none") {
|
|
692
|
+
warnings.push(`${label}.maskImage`);
|
|
693
|
+
}
|
|
694
|
+
if (diagnostic.mixBlendMode !== "normal") {
|
|
695
|
+
warnings.push(`${label}.mixBlendMode:${diagnostic.mixBlendMode}`);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
private pickRenderRelevantFields(diagnostic: Record<string, any>): Record<string, any> {
|
|
700
|
+
const result: Record<string, any> = {
|
|
701
|
+
node: diagnostic.node,
|
|
702
|
+
display: diagnostic.display,
|
|
703
|
+
visibility: diagnostic.visibility,
|
|
704
|
+
opacity: diagnostic.opacity,
|
|
705
|
+
hiddenAttribute: diagnostic.hiddenAttribute,
|
|
706
|
+
contentVisibility: diagnostic.contentVisibility,
|
|
707
|
+
backgroundColor: diagnostic.backgroundColor,
|
|
708
|
+
backgroundAlpha: diagnostic.backgroundColorChannels?.a ?? null,
|
|
709
|
+
color: diagnostic.color,
|
|
710
|
+
colorAlpha: diagnostic.colorChannels?.a ?? null,
|
|
711
|
+
textFillColor: diagnostic.textFillColor,
|
|
712
|
+
textFillAlpha: diagnostic.textFillColorChannels?.a ?? null,
|
|
713
|
+
};
|
|
714
|
+
if (diagnostic.transform !== "none") {
|
|
715
|
+
result.transform = diagnostic.transform;
|
|
716
|
+
}
|
|
717
|
+
if (diagnostic.filter !== "none") {
|
|
718
|
+
result.filter = diagnostic.filter;
|
|
719
|
+
}
|
|
720
|
+
if (diagnostic.backdropFilter !== "none") {
|
|
721
|
+
result.backdropFilter = diagnostic.backdropFilter;
|
|
722
|
+
}
|
|
723
|
+
if (diagnostic.mixBlendMode !== "normal") {
|
|
724
|
+
result.mixBlendMode = diagnostic.mixBlendMode;
|
|
725
|
+
}
|
|
726
|
+
if (diagnostic.clipPath !== "none") {
|
|
727
|
+
result.clipPath = diagnostic.clipPath;
|
|
728
|
+
}
|
|
729
|
+
if (diagnostic.maskImage !== "none") {
|
|
730
|
+
result.maskImage = diagnostic.maskImage;
|
|
731
|
+
}
|
|
732
|
+
if (diagnostic.overflow !== "visible") {
|
|
733
|
+
result.overflow = diagnostic.overflow;
|
|
734
|
+
}
|
|
735
|
+
if (diagnostic.zIndex !== "auto") {
|
|
736
|
+
result.zIndex = diagnostic.zIndex;
|
|
737
|
+
}
|
|
738
|
+
return result;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
private pickBackgroundImageStatus(diagnostic: Record<string, any>): Record<string, any> {
|
|
742
|
+
return {
|
|
743
|
+
found: true,
|
|
744
|
+
complete: diagnostic.complete,
|
|
745
|
+
currentSrc: diagnostic.currentSrc || diagnostic.src || "",
|
|
746
|
+
naturalWidth: diagnostic.naturalWidth,
|
|
747
|
+
naturalHeight: diagnostic.naturalHeight,
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
private collectElementDiagnostic(element: Element | null): Record<string, any> | null {
|
|
752
|
+
if (!element) {
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
const style = window.getComputedStyle(element);
|
|
756
|
+
const htmlElement = element as HTMLElement;
|
|
757
|
+
return {
|
|
758
|
+
node: this.describeElement(element),
|
|
759
|
+
isConnected: element.isConnected,
|
|
760
|
+
hiddenAttribute: htmlElement.hidden,
|
|
761
|
+
ariaHidden: htmlElement.getAttribute("aria-hidden"),
|
|
762
|
+
opacity: style.opacity,
|
|
763
|
+
alpha: style.opacity,
|
|
764
|
+
display: style.display,
|
|
765
|
+
visibility: style.visibility,
|
|
766
|
+
backgroundColor: style.backgroundColor,
|
|
767
|
+
backgroundColorChannels: this.parseColorChannels(style.backgroundColor),
|
|
768
|
+
color: style.color,
|
|
769
|
+
colorChannels: this.parseColorChannels(style.color),
|
|
770
|
+
textFillColor: style.getPropertyValue("-webkit-text-fill-color"),
|
|
771
|
+
textFillColorChannels: this.parseColorChannels(
|
|
772
|
+
style.getPropertyValue("-webkit-text-fill-color")
|
|
773
|
+
),
|
|
774
|
+
filter: style.filter,
|
|
775
|
+
backdropFilter: style.getPropertyValue("backdrop-filter"),
|
|
776
|
+
mixBlendMode: style.mixBlendMode,
|
|
777
|
+
transform: style.transform,
|
|
778
|
+
contentVisibility: style.getPropertyValue("content-visibility"),
|
|
779
|
+
clipPath: style.clipPath,
|
|
780
|
+
maskImage:
|
|
781
|
+
style.getPropertyValue("mask-image") ||
|
|
782
|
+
style.getPropertyValue("-webkit-mask-image"),
|
|
783
|
+
overflow: style.overflow,
|
|
784
|
+
zIndex: style.zIndex,
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
private describeElement(element: Element | null): string | null {
|
|
789
|
+
if (!element) {
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
const tagName = element.tagName.toLowerCase();
|
|
793
|
+
const id = element.id ? `#${element.id}` : "";
|
|
794
|
+
const className =
|
|
795
|
+
typeof (element as HTMLElement).className === "string" &&
|
|
796
|
+
(element as HTMLElement).className.trim()
|
|
797
|
+
? `.${(element as HTMLElement).className.trim().replace(/\s+/g, ".")}`
|
|
798
|
+
: "";
|
|
799
|
+
return `${tagName}${id}${className}`;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
private serializeRect(rect?: DOMRect | null): DiagnosticRect | null {
|
|
803
|
+
if (!rect) {
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
return {
|
|
807
|
+
x: rect.x,
|
|
808
|
+
y: rect.y,
|
|
809
|
+
width: rect.width,
|
|
810
|
+
height: rect.height,
|
|
811
|
+
top: rect.top,
|
|
812
|
+
right: rect.right,
|
|
813
|
+
bottom: rect.bottom,
|
|
814
|
+
left: rect.left,
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
private parseColorChannels(value?: string | null): DiagnosticColorChannels {
|
|
819
|
+
const raw = value?.trim() || "";
|
|
820
|
+
if (!raw) {
|
|
821
|
+
return { raw };
|
|
822
|
+
}
|
|
823
|
+
if (raw === "transparent") {
|
|
824
|
+
return { raw, r: 0, g: 0, b: 0, a: 0 };
|
|
825
|
+
}
|
|
826
|
+
const matches = raw.match(/^rgba?\((.+)\)$/i);
|
|
827
|
+
if (!matches) {
|
|
828
|
+
return { raw };
|
|
829
|
+
}
|
|
830
|
+
const parts = matches[1].split(",").map(part => part.trim());
|
|
831
|
+
const [r, g, b, a] = parts.map(part => Number(part));
|
|
832
|
+
return {
|
|
833
|
+
raw,
|
|
834
|
+
r: Number.isFinite(r) ? r : undefined,
|
|
835
|
+
g: Number.isFinite(g) ? g : undefined,
|
|
836
|
+
b: Number.isFinite(b) ? b : undefined,
|
|
837
|
+
a: Number.isFinite(a) ? a : raw.startsWith("rgb(") ? 1 : undefined,
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
419
841
|
private static initManager(room: Room): Promise<WindowManager | undefined> {
|
|
420
842
|
return createInvisiblePlugin(room);
|
|
421
843
|
}
|
|
@@ -488,6 +910,7 @@ export class WindowManager
|
|
|
488
910
|
this.appManager.setBoxManager(boxManager);
|
|
489
911
|
}
|
|
490
912
|
this.bindMainView(mainViewElement, params.disableCameraTransform);
|
|
913
|
+
this.logMainViewVisibilityDiagnostics("bindContainer.afterBindMainView");
|
|
491
914
|
if (WindowManager.wrapper) {
|
|
492
915
|
this.cursorManager?.setupWrapper(WindowManager.wrapper);
|
|
493
916
|
}
|
|
@@ -1083,7 +1506,6 @@ export class WindowManager
|
|
|
1083
1506
|
WindowManager.playground.parentNode?.removeChild(WindowManager.playground);
|
|
1084
1507
|
}
|
|
1085
1508
|
WindowManager.params = undefined;
|
|
1086
|
-
document.removeEventListener("visibilitychange", this.visibleStateListener);
|
|
1087
1509
|
this.emitter.off('mainViewScenePathChange', this.onMainViewScenePathChangeHandler);
|
|
1088
1510
|
this._iframeBridge?.destroy();
|
|
1089
1511
|
this._iframeBridge = undefined;
|