@netless/window-manager 1.0.18 → 1.0.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 +13 -0
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +285 -13
- package/dist/index.mjs.map +1 -1
- package/docs/cn/box-size-change.md +144 -0
- package/package.json +3 -3
- package/src/App/AppBoxSizeSynchronizer.ts +124 -0
- package/src/App/AppContext.ts +2 -0
- package/src/App/AppProxy.ts +63 -1
- package/src/AppManager.ts +9 -0
- package/src/BoxManager.ts +15 -0
- package/src/ContainerResizeObserver.ts +134 -4
- package/src/constants.ts +4 -0
- package/src/index.ts +13 -1
- package/src/typings.ts +2 -0
|
@@ -2,25 +2,58 @@ import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observe
|
|
|
2
2
|
import { WindowManager } from "./index";
|
|
3
3
|
import type { EmitterType } from "./InternalEmitter";
|
|
4
4
|
import type { UnsubscribeFn } from "emittery";
|
|
5
|
-
import {
|
|
5
|
+
import type { Logger } from "white-web-sdk";
|
|
6
|
+
import { CONTAINER_STATE_LOG_DEBOUNCE } from "./constants";
|
|
7
|
+
import { ArgusLog, LocalConsole } from "./Utils/log";
|
|
6
8
|
|
|
7
9
|
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
|
|
8
10
|
|
|
11
|
+
export type ContainerInternalState = {
|
|
12
|
+
mainViewElement?: HTMLElement;
|
|
13
|
+
mainViewSize?: Pick<DOMRectReadOnly, "width" | "height">;
|
|
14
|
+
teleBoxContainerRect?: Pick<DOMRectReadOnly, "width" | "height">;
|
|
15
|
+
mainViewDidRelease?: boolean;
|
|
16
|
+
containerSizeRatio?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
9
19
|
export class ContainerResizeObserver {
|
|
10
20
|
private containerResizeObserver?: ResizeObserver;
|
|
11
21
|
private disposer?: UnsubscribeFn;
|
|
12
22
|
|
|
13
23
|
private updateSizerLocalConsole = new LocalConsole("updateSizer", 100);
|
|
24
|
+
private containerStateArgusLog?: ArgusLog;
|
|
25
|
+
private containerStateLogTimer?: ReturnType<typeof setTimeout>;
|
|
26
|
+
private pendingContainerState?: {
|
|
27
|
+
origin?: string;
|
|
28
|
+
observedSize?: Pick<DOMRectReadOnly, "width" | "height">;
|
|
29
|
+
};
|
|
30
|
+
private container?: HTMLElement;
|
|
31
|
+
private sizer?: HTMLElement;
|
|
32
|
+
private wrapper?: HTMLDivElement;
|
|
14
33
|
|
|
15
|
-
constructor(
|
|
34
|
+
constructor(
|
|
35
|
+
private emitter: EmitterType,
|
|
36
|
+
logger?: Logger,
|
|
37
|
+
private getInternalState?: () => ContainerInternalState
|
|
38
|
+
) {
|
|
39
|
+
if (logger) {
|
|
40
|
+
this.containerStateArgusLog = new ArgusLog(logger, "containerState");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
16
43
|
|
|
17
44
|
public static create(
|
|
18
45
|
container: HTMLElement,
|
|
19
46
|
sizer: HTMLElement,
|
|
20
47
|
wrapper: HTMLDivElement,
|
|
21
|
-
emitter: EmitterType
|
|
48
|
+
emitter: EmitterType,
|
|
49
|
+
logger?: Logger,
|
|
50
|
+
getInternalState?: () => ContainerInternalState
|
|
22
51
|
) {
|
|
23
|
-
const containerResizeObserver = new ContainerResizeObserver(
|
|
52
|
+
const containerResizeObserver = new ContainerResizeObserver(
|
|
53
|
+
emitter,
|
|
54
|
+
logger,
|
|
55
|
+
getInternalState
|
|
56
|
+
);
|
|
24
57
|
containerResizeObserver.observePlaygroundSize(container, sizer, wrapper);
|
|
25
58
|
return containerResizeObserver;
|
|
26
59
|
}
|
|
@@ -30,6 +63,9 @@ export class ContainerResizeObserver {
|
|
|
30
63
|
sizer: HTMLElement,
|
|
31
64
|
wrapper: HTMLDivElement
|
|
32
65
|
) {
|
|
66
|
+
this.container = container;
|
|
67
|
+
this.sizer = sizer;
|
|
68
|
+
this.wrapper = wrapper;
|
|
33
69
|
this.updateSizer(
|
|
34
70
|
container.getBoundingClientRect(),
|
|
35
71
|
sizer,
|
|
@@ -60,6 +96,7 @@ export class ContainerResizeObserver {
|
|
|
60
96
|
wrapper: HTMLDivElement,
|
|
61
97
|
origin?: string
|
|
62
98
|
) {
|
|
99
|
+
const observedSize = { width, height };
|
|
63
100
|
if (width && height) {
|
|
64
101
|
if (height / width > WindowManager.containerSizeRatio) {
|
|
65
102
|
height = width * WindowManager.containerSizeRatio;
|
|
@@ -82,12 +119,105 @@ export class ContainerResizeObserver {
|
|
|
82
119
|
origin,
|
|
83
120
|
});
|
|
84
121
|
}
|
|
122
|
+
this.scheduleContainerStateLog(origin, observedSize);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public logCurrentState(origin: string): void {
|
|
126
|
+
this.scheduleContainerStateLog(origin);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private scheduleContainerStateLog(
|
|
130
|
+
origin?: string,
|
|
131
|
+
observedSize?: Pick<DOMRectReadOnly, "width" | "height">
|
|
132
|
+
): void {
|
|
133
|
+
if (!this.containerStateArgusLog || !this.container || !this.sizer || !this.wrapper) return;
|
|
134
|
+
|
|
135
|
+
this.pendingContainerState = {
|
|
136
|
+
origin,
|
|
137
|
+
observedSize: observedSize
|
|
138
|
+
? { width: observedSize.width, height: observedSize.height }
|
|
139
|
+
: undefined,
|
|
140
|
+
};
|
|
141
|
+
if (this.containerStateLogTimer != null) {
|
|
142
|
+
clearTimeout(this.containerStateLogTimer);
|
|
143
|
+
}
|
|
144
|
+
this.containerStateLogTimer = setTimeout(
|
|
145
|
+
this.flushContainerStateLog,
|
|
146
|
+
CONTAINER_STATE_LOG_DEBOUNCE
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private flushContainerStateLog = (): void => {
|
|
151
|
+
this.containerStateLogTimer = undefined;
|
|
152
|
+
const pendingState = this.pendingContainerState;
|
|
153
|
+
this.pendingContainerState = undefined;
|
|
154
|
+
if (
|
|
155
|
+
!pendingState ||
|
|
156
|
+
!this.containerStateArgusLog ||
|
|
157
|
+
!this.container ||
|
|
158
|
+
!this.sizer ||
|
|
159
|
+
!this.wrapper
|
|
160
|
+
) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const internalState = this.getInternalState?.();
|
|
165
|
+
const root = this.container.parentElement;
|
|
166
|
+
const rootRect = root?.getBoundingClientRect();
|
|
167
|
+
const playgroundRect = this.container.getBoundingClientRect();
|
|
168
|
+
const sizerRect = this.sizer.getBoundingClientRect();
|
|
169
|
+
const wrapperRect = this.wrapper.getBoundingClientRect();
|
|
170
|
+
const mainViewRect = internalState?.mainViewElement?.getBoundingClientRect();
|
|
171
|
+
const rootStyle = root ? window.getComputedStyle(root) : undefined;
|
|
172
|
+
this.containerStateArgusLog.log(
|
|
173
|
+
`origin: ${pendingState.origin || "unknown"}, connected: ${Boolean(
|
|
174
|
+
root?.isConnected
|
|
175
|
+
)}, ` +
|
|
176
|
+
`observed: ${this.formatSize(
|
|
177
|
+
pendingState.observedSize || playgroundRect
|
|
178
|
+
)}, root: ${this.formatSize(rootRect)}, playground: ${this.formatSize(
|
|
179
|
+
playgroundRect
|
|
180
|
+
)}, sizer: ${this.formatSize(sizerRect)}, wrapper: ${this.formatSize(
|
|
181
|
+
wrapperRect
|
|
182
|
+
)}, mainViewDOM: ${this.formatSize(mainViewRect)}, mainViewSize: ${this.formatSize(
|
|
183
|
+
internalState?.mainViewSize
|
|
184
|
+
)}, teleBoxRect: ${this.formatSize(
|
|
185
|
+
internalState?.teleBoxContainerRect
|
|
186
|
+
)}, didRelease: ${internalState?.mainViewDidRelease ?? "unknown"}, ratio: ${
|
|
187
|
+
internalState?.containerSizeRatio ?? "unknown"
|
|
188
|
+
}, display: ${rootStyle?.display || "unknown"}, visibility: ${
|
|
189
|
+
rootStyle?.visibility || "unknown"
|
|
190
|
+
}, clientRects: ${root?.getClientRects().length || 0}, inViewport: ${
|
|
191
|
+
rootRect
|
|
192
|
+
? rootRect.bottom > 0 &&
|
|
193
|
+
rootRect.right > 0 &&
|
|
194
|
+
rootRect.top < window.innerHeight &&
|
|
195
|
+
rootRect.left < window.innerWidth
|
|
196
|
+
: false
|
|
197
|
+
}`
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
private formatSize(rect?: Pick<DOMRectReadOnly, "width" | "height">): string {
|
|
202
|
+
if (!rect) return "unknown";
|
|
203
|
+
return `${Math.round(rect.width * 100) / 100}x${Math.round(rect.height * 100) / 100}`;
|
|
85
204
|
}
|
|
86
205
|
|
|
87
206
|
public disconnect() {
|
|
88
207
|
this.updateSizerLocalConsole.destroy();
|
|
208
|
+
if (this.containerStateLogTimer != null) {
|
|
209
|
+
clearTimeout(this.containerStateLogTimer);
|
|
210
|
+
this.containerStateLogTimer = undefined;
|
|
211
|
+
}
|
|
212
|
+
this.pendingContainerState = undefined;
|
|
213
|
+
this.containerStateArgusLog?.destroy();
|
|
214
|
+
this.containerStateArgusLog = undefined;
|
|
89
215
|
this.containerResizeObserver?.disconnect();
|
|
90
216
|
this.disposer?.();
|
|
91
217
|
this.disposer = undefined;
|
|
218
|
+
this.container = undefined;
|
|
219
|
+
this.sizer = undefined;
|
|
220
|
+
this.wrapper = undefined;
|
|
221
|
+
this.getInternalState = undefined;
|
|
92
222
|
}
|
|
93
223
|
}
|
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -528,7 +528,18 @@ export class WindowManager
|
|
|
528
528
|
playground,
|
|
529
529
|
sizer,
|
|
530
530
|
wrapper,
|
|
531
|
-
internalEmitter
|
|
531
|
+
internalEmitter,
|
|
532
|
+
manager.Logger,
|
|
533
|
+
() => {
|
|
534
|
+
const mainView = manager.appManager?.mainViewProxy.view;
|
|
535
|
+
return {
|
|
536
|
+
mainViewElement: mainView?.divElement,
|
|
537
|
+
mainViewSize: mainView?.size,
|
|
538
|
+
teleBoxContainerRect: manager.boxManager?.teleBoxManager.containerRect,
|
|
539
|
+
mainViewDidRelease: Boolean((mainView as any)?.didRelease),
|
|
540
|
+
containerSizeRatio: manager.containerSizeRatio,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
532
543
|
);
|
|
533
544
|
WindowManager.wrapper = wrapper;
|
|
534
545
|
WindowManager.sizer = sizer;
|
|
@@ -577,6 +588,7 @@ export class WindowManager
|
|
|
577
588
|
this.appManager?.resetMinimized();
|
|
578
589
|
this.appManager?.displayerWritableListener(!this.room.isWritable);
|
|
579
590
|
WindowManager.container = container;
|
|
591
|
+
this.containerResizeObserver?.logCurrentState("bindContainer");
|
|
580
592
|
this.extendPluginManager?.refreshContainer(container);
|
|
581
593
|
}
|
|
582
594
|
|
package/src/typings.ts
CHANGED
|
@@ -59,6 +59,8 @@ export type AppEmitterEvent<T = any> = {
|
|
|
59
59
|
seek: number;
|
|
60
60
|
pageStateChange: PageState;
|
|
61
61
|
boxStatusChange: { appId: string; status: TeleBoxState };
|
|
62
|
+
/** Actual app content size in CSS pixels after the box layout is applied. */
|
|
63
|
+
boxSizeChange: { appId: string; width: number; height: number };
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
export type RegisterEventData = {
|