@netless/app-presentation 0.1.13-beta.2 → 0.1.13-beta.4

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.mjs CHANGED
@@ -1150,6 +1150,7 @@ var _Preload = class _Preload {
1150
1150
  // 暂停后不再创建预加载链接(app 失焦降级时调用);已插入的 link 会被移除,
1151
1151
  // 挂起的 idle 回调重新进入 touch() 时也会被跳过
1152
1152
  this.paused = false;
1153
+ this.disposed = false;
1153
1154
  this.preloadMap = new Map(pages.map((e, index) => [index, {
1154
1155
  src: e.src,
1155
1156
  state: 0 /* unloaded */
@@ -1164,13 +1165,13 @@ var _Preload = class _Preload {
1164
1165
  this.destroySomeLink();
1165
1166
  }
1166
1167
  resume(index) {
1167
- if (!this.paused)
1168
+ if (!this.paused || this.disposed)
1168
1169
  return;
1169
1170
  this.paused = false;
1170
1171
  this.touch(index != null ? index : this.touchIndex, true);
1171
1172
  }
1172
1173
  touch(index, force = false) {
1173
- if (this.paused)
1174
+ if (this.paused || this.disposed)
1174
1175
  return;
1175
1176
  if (index >= this.preloadSize) {
1176
1177
  this.touchIndex = 0;
@@ -1178,11 +1179,11 @@ var _Preload = class _Preload {
1178
1179
  this.touchIndex = index;
1179
1180
  }
1180
1181
  const value = this.preloadMap.get(this.touchIndex);
1181
- if (value && value.state === 0 /* unloaded */) {
1182
+ if (value && (value.state === 0 /* unloaded */ || force && value.state === 2 /* error */)) {
1182
1183
  this.createLink(this.touchIndex, force);
1183
1184
  }
1184
1185
  if (this.loadingLinks.size < _Preload.maxLinks) {
1185
- const willLoad = [...this.preloadMap.entries()].find(([i, e]) => i > this.touchIndex && e.state !== 1 /* loaded */);
1186
+ const willLoad = [...this.preloadMap.entries()].find(([i, e]) => i > this.touchIndex && e.state === 0 /* unloaded */);
1186
1187
  if (willLoad) {
1187
1188
  this.requestAsyncCallBack(() => {
1188
1189
  this.touch(willLoad[0], false);
@@ -1215,21 +1216,27 @@ var _Preload = class _Preload {
1215
1216
  linkDom.as = "image";
1216
1217
  linkDom.href = value.src;
1217
1218
  linkDom.dataset.order = index + "";
1218
- document.head.appendChild(linkDom);
1219
1219
  linkDom.onload = () => {
1220
+ var _a;
1221
+ if (((_a = this.loadingLinks.get(index)) == null ? void 0 : _a.link) !== linkDom)
1222
+ return;
1220
1223
  const value2 = this.preloadMap.get(index);
1221
1224
  if (value2) {
1222
1225
  value2.state = 1 /* loaded */;
1223
1226
  this.preloadMap.set(index, value2);
1224
- document.head.contains(linkDom) && document.head.removeChild(linkDom);
1225
- this.loadingLinks.delete(index);
1227
+ this.removeLink(index, linkDom);
1226
1228
  this.touch(this.touchIndex + 1, false);
1227
1229
  }
1228
1230
  };
1229
1231
  linkDom.onerror = () => {
1232
+ var _a;
1233
+ if (((_a = this.loadingLinks.get(index)) == null ? void 0 : _a.link) !== linkDom)
1234
+ return;
1230
1235
  const value2 = this.preloadMap.get(index);
1231
- if (value2 == null ? void 0 : value2.src) {
1232
- linkDom.href = value2.src;
1236
+ if (value2) {
1237
+ value2.state = 2 /* error */;
1238
+ this.removeLink(index, linkDom);
1239
+ this.touch(this.touchIndex + 1, false);
1233
1240
  }
1234
1241
  };
1235
1242
  this.loadingLinks.set(index, {
@@ -1238,17 +1245,23 @@ var _Preload = class _Preload {
1238
1245
  });
1239
1246
  value.state = 0 /* unloaded */;
1240
1247
  this.preloadMap.set(index, value);
1248
+ document.head.appendChild(linkDom);
1241
1249
  return 0 /* unloaded */;
1242
1250
  }
1243
1251
  return 2 /* error */;
1244
1252
  }
1253
+ removeLink(index, link) {
1254
+ link.onload = null;
1255
+ link.onerror = null;
1256
+ document.head.contains(link) && document.head.removeChild(link);
1257
+ this.loadingLinks.delete(index);
1258
+ }
1245
1259
  destroySomeLink(excludeIndex) {
1246
1260
  for (const [index, { link }] of this.loadingLinks) {
1247
1261
  if (excludeIndex !== void 0 && index === excludeIndex) {
1248
1262
  continue;
1249
1263
  }
1250
- document.head.contains(link) && document.head.removeChild(link);
1251
- this.loadingLinks.delete(index);
1264
+ this.removeLink(index, link);
1252
1265
  }
1253
1266
  }
1254
1267
  async requestAsyncCallBack(callBack, timeout) {
@@ -1266,6 +1279,7 @@ var _Preload = class _Preload {
1266
1279
  callBack();
1267
1280
  }
1268
1281
  dispose() {
1282
+ this.disposed = true;
1269
1283
  this.destroySomeLink();
1270
1284
  this.preloadMap.clear();
1271
1285
  }
@@ -1978,19 +1992,72 @@ function cameraToSharedViewport(camera, viewSize, referenceSize) {
1978
1992
  var createPresentationRuntimeTeardown = (box, dispose2) => {
1979
1993
  let tornDown = false;
1980
1994
  return () => {
1995
+ var _a, _b, _c;
1981
1996
  if (tornDown)
1982
1997
  return;
1983
1998
  tornDown = true;
1984
1999
  try {
1985
2000
  dispose2();
1986
2001
  } finally {
1987
- box.unmountContent();
1988
- box.unmountFooter();
1989
- box.unmountStyles();
2002
+ try {
2003
+ (_a = box.unmountContent) == null ? void 0 : _a.call(box);
2004
+ } finally {
2005
+ try {
2006
+ (_b = box.unmountFooter) == null ? void 0 : _b.call(box);
2007
+ } finally {
2008
+ (_c = box.unmountStyles) == null ? void 0 : _c.call(box);
2009
+ }
2010
+ }
1990
2011
  }
1991
2012
  };
1992
2013
  };
1993
2014
 
2015
+ // src/setup-ready.ts
2016
+ var waitForCurrentPageImage = (getImage, timeoutMs, isDisposed, options) => {
2017
+ return new Promise((resolve) => {
2018
+ let settled = false;
2019
+ let timedOut = false;
2020
+ let pollTimer;
2021
+ const settle = (result) => {
2022
+ if (settled)
2023
+ return;
2024
+ settled = true;
2025
+ window.clearTimeout(timeoutTimer);
2026
+ if (pollTimer !== void 0)
2027
+ window.clearInterval(pollTimer);
2028
+ resolve(result);
2029
+ };
2030
+ const timeoutTimer = window.setTimeout(() => {
2031
+ timedOut = true;
2032
+ options == null ? void 0 : options.onTimeout();
2033
+ if (!(options == null ? void 0 : options.waitForReady()))
2034
+ settle("timeout");
2035
+ }, timeoutMs);
2036
+ const check = () => {
2037
+ var _a, _b;
2038
+ if (isDisposed()) {
2039
+ settle("disposed");
2040
+ return;
2041
+ }
2042
+ if (timedOut && !(options == null ? void 0 : options.waitForReady())) {
2043
+ settle("timeout");
2044
+ return;
2045
+ }
2046
+ const img = getImage();
2047
+ if (img == null ? void 0 : img.complete) {
2048
+ if (img.naturalWidth > 0) {
2049
+ settle("loaded");
2050
+ } else if (img.currentSrc || ((_a = img.getAttribute("src")) == null ? void 0 : _a.trim()) || ((_b = img.getAttribute("srcset")) == null ? void 0 : _b.trim())) {
2051
+ settle("error");
2052
+ }
2053
+ }
2054
+ };
2055
+ check();
2056
+ if (!settled)
2057
+ pollTimer = window.setInterval(check, 100);
2058
+ });
2059
+ };
2060
+
1994
2061
  // src/app-presentation.ts
1995
2062
  var import_debounce2 = __toESM(require_debounce());
1996
2063
  var emptySceneName = "$$empty$$";
@@ -2019,36 +2086,6 @@ var isBlurDegradationAllowed = (context) => {
2019
2086
  return boxState !== void 0 && boxState !== "normal";
2020
2087
  };
2021
2088
  var DEFAULT_SETUP_READY_TIMEOUT = 5e3;
2022
- var waitForCurrentPageImage = (view, timeoutMs, isDisposed) => {
2023
- return new Promise((resolve) => {
2024
- let settled = false;
2025
- let pollTimer;
2026
- const settle = (loaded) => {
2027
- if (settled)
2028
- return;
2029
- settled = true;
2030
- window.clearTimeout(timeoutTimer);
2031
- if (pollTimer !== void 0)
2032
- window.clearInterval(pollTimer);
2033
- resolve(loaded);
2034
- };
2035
- const timeoutTimer = window.setTimeout(() => settle(false), timeoutMs);
2036
- const check = () => {
2037
- if (isDisposed()) {
2038
- settle(false);
2039
- return;
2040
- }
2041
- const img = findBackgroundImage(view);
2042
- if (img && img.complete && img.naturalWidth > 0) {
2043
- settle(true);
2044
- }
2045
- };
2046
- check();
2047
- if (!settled) {
2048
- pollTimer = window.setInterval(check, 100);
2049
- }
2050
- });
2051
- };
2052
2089
  var resolveImageUrl = (url) => {
2053
2090
  try {
2054
2091
  return new URL(url, window.location.href).href;
@@ -2080,6 +2117,19 @@ var setupBlurThumbnailDegradation = (config) => {
2080
2117
  const boxBlurClass = box.wrapClassName("blur");
2081
2118
  let blurEpisode = false;
2082
2119
  let reDegradeEnabled = false;
2120
+ let previewSuspended = false;
2121
+ let appliedFocusState = true;
2122
+ let logicalFocused = true;
2123
+ const activityBlocked = () => {
2124
+ var _a, _b;
2125
+ const wm = context.getWindowManager();
2126
+ if ((wm == null ? void 0 : wm.lazySetupInMaximizedMode) !== true)
2127
+ return false;
2128
+ const host = (_a = context.getRuntimeActivity) == null ? void 0 : _a.call(context);
2129
+ if (host)
2130
+ return document.visibilityState === "hidden" || !host.active;
2131
+ return document.visibilityState === "hidden" || wm.boxState === "minimized" || ((_b = wm.attributes) == null ? void 0 : _b.minimized) === true || context.getBoxStatus() === "minimized";
2132
+ };
2083
2133
  let boxBlurred = box.$box.classList.contains(boxBlurClass);
2084
2134
  const setBackgroundSuspended = (suspended) => {
2085
2135
  app.whiteboardDOM.classList.toggle(
@@ -2094,7 +2144,7 @@ var setupBlurThumbnailDegradation = (config) => {
2094
2144
  const thumbnailURL = page.thumbnail;
2095
2145
  const img = findBackgroundImage(view);
2096
2146
  if (!thumbnailURL || !hasUsableThumbnail(page)) {
2097
- if (boxBlurred) {
2147
+ if (boxBlurred || activityBlocked()) {
2098
2148
  setBackgroundSuspended(true);
2099
2149
  if (img && resolveImageUrl(img.src) !== resolveImageUrl(TRANSPARENT_BACKGROUND)) {
2100
2150
  img.src = TRANSPARENT_BACKGROUND;
@@ -2116,9 +2166,12 @@ var setupBlurThumbnailDegradation = (config) => {
2116
2166
  setBackgroundSuspended(false);
2117
2167
  };
2118
2168
  const suspendCachedResources = () => {
2119
- if (!blurEpisode || !boxBlurred)
2169
+ if (!blurEpisode || !boxBlurred && !activityBlocked())
2120
2170
  return;
2121
- app.suspendPreviewResources();
2171
+ if (!previewSuspended) {
2172
+ previewSuspended = true;
2173
+ app.suspendPreviewResources();
2174
+ }
2122
2175
  const page = pages[pageIndex$.value];
2123
2176
  if (!page || !hasUsableThumbnail(page) || reDegradeEnabled) {
2124
2177
  degrade();
@@ -2129,6 +2182,7 @@ var setupBlurThumbnailDegradation = (config) => {
2129
2182
  return;
2130
2183
  blurEpisode = false;
2131
2184
  reDegradeEnabled = false;
2185
+ previewSuspended = false;
2132
2186
  restore2();
2133
2187
  app.preload.resume(pageIndex$.value);
2134
2188
  };
@@ -2159,27 +2213,40 @@ var setupBlurThumbnailDegradation = (config) => {
2159
2213
  return;
2160
2214
  reDegradeEnabled = false;
2161
2215
  };
2162
- const offFocus = context.emitter.on("focus", (isFocused) => {
2216
+ const applyActivity = () => {
2217
+ var _a;
2218
+ const lazy = ((_a = context.getWindowManager()) == null ? void 0 : _a.lazySetupInMaximizedMode) === true;
2219
+ const isFocused = (!lazy || logicalFocused) && !activityBlocked();
2220
+ if (appliedFocusState === isFocused)
2221
+ return;
2222
+ if (!isFocused && !isBlurDegradationAllowed(context) && !activityBlocked())
2223
+ return;
2163
2224
  if (isFocused) {
2164
2225
  restoreFocusedResources();
2165
2226
  } else {
2166
- if (!isBlurDegradationAllowed(context))
2167
- return;
2168
2227
  blurEpisode = true;
2169
2228
  reDegradeEnabled = true;
2170
2229
  degrade();
2171
2230
  app.preload.pause();
2172
2231
  suspendCachedResources();
2173
2232
  }
2233
+ appliedFocusState = isFocused;
2234
+ };
2235
+ const offFocus = context.emitter.on("focus", (isFocused) => {
2236
+ logicalFocused = isFocused;
2237
+ applyActivity();
2174
2238
  });
2175
2239
  dispose2.add(offFocus);
2240
+ dispose2.add(context.emitter.on("runtimeActivity", applyActivity));
2241
+ document.addEventListener("visibilitychange", applyActivity);
2242
+ dispose2.add(() => document.removeEventListener("visibilitychange", applyActivity));
2176
2243
  const updateBoxBlurred = (blurred) => {
2177
2244
  if (boxBlurred === blurred)
2178
2245
  return;
2179
2246
  boxBlurred = blurred;
2180
2247
  if (blurred)
2181
2248
  suspendCachedResources();
2182
- else
2249
+ else if (logicalFocused && !activityBlocked())
2183
2250
  restoreFocusedResources();
2184
2251
  };
2185
2252
  const onBoxBlur = () => updateBoxBlurred(true);
@@ -2626,7 +2693,7 @@ var NetlessAppPresentation = {
2626
2693
  options.useClipView
2627
2694
  )
2628
2695
  );
2629
- app.contentDOM.dataset.appPresentationVersion = "0.1.13-beta.2";
2696
+ app.contentDOM.dataset.appPresentationVersion = "0.1.13-beta.4";
2630
2697
  app.scaleDocsToFit = scaleDocsToFit;
2631
2698
  app.log = log;
2632
2699
  app.warn = warn;
@@ -3095,9 +3162,22 @@ var NetlessAppPresentation = {
3095
3162
  );
3096
3163
  const setupReadyTimeout = (_d = options.setupReadyTimeout) != null ? _d : DEFAULT_SETUP_READY_TIMEOUT;
3097
3164
  return prepareScenesPromise.then(async () => {
3098
- const loaded = await waitForCurrentPageImage(view, setupReadyTimeout, () => disposed);
3099
- if (!loaded && !disposed) {
3100
- warn(`[Presentation] setup ready wait timed out after ${setupReadyTimeout}ms`);
3165
+ const result = await waitForCurrentPageImage(
3166
+ () => findBackgroundImage(view),
3167
+ setupReadyTimeout,
3168
+ () => disposed,
3169
+ {
3170
+ waitForReady: () => Boolean(context.waitForActualSetupReady),
3171
+ onTimeout: () => warn(`[Presentation] setup page image still pending after ${setupReadyTimeout}ms`)
3172
+ }
3173
+ );
3174
+ if (disposed)
3175
+ throw new Error("[Presentation] disposed before setup ready");
3176
+ if (result === "error" && context.waitForActualSetupReady) {
3177
+ throw new Error("[Presentation] setup page image failed to load");
3178
+ }
3179
+ if (result === "error" && !disposed) {
3180
+ warn("[Presentation] setup page image failed to load; continuing setup");
3101
3181
  }
3102
3182
  return controller;
3103
3183
  });
@@ -3186,7 +3266,7 @@ var install = (register, options = {}) => {
3186
3266
  };
3187
3267
 
3188
3268
  // src/index.ts
3189
- var version = "0.1.13-beta.2";
3269
+ var version = "0.1.13-beta.4";
3190
3270
 
3191
3271
  export { NetlessAppPresentation, Presentation, Scrollbar, NetlessAppPresentation as default, install, setupBlurThumbnailDegradation, version };
3192
3272
  //# sourceMappingURL=index.mjs.map