@replohq/sandbox-runtime 1.19.1 → 1.19.3
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/LinkInterceptor.js +102 -33
- package/_vendor/replo-utils/lib/misc.mjs +1 -1
- package/_vendor/schemas/externalNavigationIframeRpc.d.ts +17 -0
- package/_vendor/schemas/externalNavigationIframeRpc.mjs +41 -0
- package/_vendor/schemas/iframeRpcChannel.mjs +1 -1
- package/_vendor/schemas/previewHealthIframeRpc.mjs +1 -1
- package/_vendor/schemas/selectMode.mjs +1 -1
- package/_vendor/schemas/selectModeIframeRpc.mjs +1 -1
- package/buildMetadata.js +3 -3
- package/package.json +4 -4
- package/previewHealth.d.ts +7 -0
- package/previewHealth.js +31 -0
package/LinkInterceptor.js
CHANGED
|
@@ -1,30 +1,50 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect } from "react";
|
|
3
|
+
import {
|
|
4
|
+
EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID,
|
|
5
|
+
EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION,
|
|
6
|
+
parentToSandboxExternalNavigationMethodConfig,
|
|
7
|
+
sandboxToParentExternalNavigationMethodConfig
|
|
8
|
+
} from "./_vendor/schemas/externalNavigationIframeRpc.mjs";
|
|
9
|
+
import {
|
|
10
|
+
createIframeRpcChannel,
|
|
11
|
+
createIframeRpcRemote
|
|
12
|
+
} from "./_vendor/schemas/iframeRpcChannel.mjs";
|
|
3
13
|
import { displayModeStore } from "./select-mode/displayModeStore";
|
|
4
|
-
const EXTERNAL_NAVIGATION_HANDLER_KEY = "__reploExternalNavigationHandler";
|
|
5
14
|
function blockNavigation(event) {
|
|
6
15
|
event.preventDefault();
|
|
7
16
|
event.stopPropagation();
|
|
8
17
|
event.stopImmediatePropagation();
|
|
9
18
|
}
|
|
10
19
|
function isNavigationLike(value) {
|
|
11
|
-
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
return typeof Reflect.get(value, "addEventListener") === "function" && typeof Reflect.get(value, "removeEventListener") === "function";
|
|
20
|
+
return typeof value === "object" && value !== null && "addEventListener" in value && typeof value.addEventListener === "function" && "removeEventListener" in value && typeof value.removeEventListener === "function";
|
|
15
21
|
}
|
|
16
22
|
function getWindowNavigation() {
|
|
17
|
-
|
|
18
|
-
return isNavigationLike(navigation) ? navigation : null;
|
|
23
|
+
return "navigation" in window && isNavigationLike(window.navigation) ? window.navigation : null;
|
|
19
24
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
const LIVE_SHARED_PREVIEW_STORAGE_KEY = "__reploLiveSharedPreview";
|
|
26
|
+
function syncStoredLiveSharedPreview(isMarked) {
|
|
27
|
+
try {
|
|
28
|
+
if (isMarked) {
|
|
29
|
+
window.sessionStorage.setItem(LIVE_SHARED_PREVIEW_STORAGE_KEY, "1");
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return window.sessionStorage.getItem(LIVE_SHARED_PREVIEW_STORAGE_KEY) === "1";
|
|
33
|
+
} catch {
|
|
34
|
+
return isMarked;
|
|
23
35
|
}
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
}
|
|
37
|
+
function getAgentPreviewMode() {
|
|
38
|
+
if (typeof window === "undefined" || window.parent === window) {
|
|
39
|
+
return null;
|
|
26
40
|
}
|
|
27
|
-
|
|
41
|
+
const marker = new URLSearchParams(window.location.search).get(
|
|
42
|
+
"__reploAgentPreview"
|
|
43
|
+
);
|
|
44
|
+
if (marker === "1") {
|
|
45
|
+
return "editor";
|
|
46
|
+
}
|
|
47
|
+
return syncStoredLiveSharedPreview(marker === "live-shared-preview") ? "live-shared-preview" : null;
|
|
28
48
|
}
|
|
29
49
|
function resolveUrl(rawUrl) {
|
|
30
50
|
try {
|
|
@@ -40,15 +60,81 @@ function urlLeavesSandbox(rawUrl) {
|
|
|
40
60
|
const resolved = resolveUrl(rawUrl);
|
|
41
61
|
return resolved === null ? null : resolved.origin !== window.location.origin;
|
|
42
62
|
}
|
|
63
|
+
function isOutboundCheckout(rawUrl) {
|
|
64
|
+
const resolved = resolveUrl(rawUrl);
|
|
65
|
+
return resolved !== null && resolved.origin !== window.location.origin && (resolved.hostname === "checkout.stripe.com" || /\/cart\/(?:c\/|\d+:\d+)|\/checkouts\//u.test(resolved.pathname));
|
|
66
|
+
}
|
|
67
|
+
let parentRemote = null;
|
|
68
|
+
function getParentRemote() {
|
|
69
|
+
parentRemote ??= createIframeRpcRemote(
|
|
70
|
+
createIframeRpcChannel({
|
|
71
|
+
subscriberWindow: window,
|
|
72
|
+
channelIdentifier: EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID,
|
|
73
|
+
version: EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION,
|
|
74
|
+
getTargetWindow: () => window.parent,
|
|
75
|
+
targetOrigin: "*",
|
|
76
|
+
isExpectedMessage: (event) => event.source === window.parent,
|
|
77
|
+
outgoingMethods: sandboxToParentExternalNavigationMethodConfig,
|
|
78
|
+
incomingMethods: parentToSandboxExternalNavigationMethodConfig,
|
|
79
|
+
handlers: {}
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
return parentRemote;
|
|
83
|
+
}
|
|
84
|
+
function openInParent(rawUrl) {
|
|
85
|
+
const resolved = resolveUrl(rawUrl);
|
|
86
|
+
if (resolved?.protocol !== "http:" && resolved?.protocol !== "https:") {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
getParentRemote().openExternal({ url: resolved.toString() });
|
|
90
|
+
}
|
|
91
|
+
function addSharedPreviewCheckoutListeners(navigation) {
|
|
92
|
+
const handleNavigate = (event) => {
|
|
93
|
+
const destinationUrl = event.destination?.url;
|
|
94
|
+
if (!destinationUrl || !isOutboundCheckout(destinationUrl)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
event.preventDefault?.();
|
|
98
|
+
openInParent(destinationUrl);
|
|
99
|
+
};
|
|
100
|
+
const handleClick = (event) => {
|
|
101
|
+
const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
102
|
+
const href = link instanceof HTMLAnchorElement ? link.getAttribute("href") : null;
|
|
103
|
+
if (!href || !isOutboundCheckout(href)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
blockNavigation(event);
|
|
107
|
+
openInParent(href);
|
|
108
|
+
};
|
|
109
|
+
navigation?.addEventListener("navigate", handleNavigate);
|
|
110
|
+
document.addEventListener("click", handleClick, true);
|
|
111
|
+
return () => {
|
|
112
|
+
navigation?.removeEventListener("navigate", handleNavigate);
|
|
113
|
+
document.removeEventListener("click", handleClick, true);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
43
116
|
function LinkInterceptor() {
|
|
44
117
|
useEffect(() => {
|
|
45
|
-
|
|
118
|
+
const mode = getAgentPreviewMode();
|
|
119
|
+
if (mode === null) {
|
|
46
120
|
return;
|
|
47
121
|
}
|
|
122
|
+
const host = window;
|
|
123
|
+
const navigation = getWindowNavigation();
|
|
124
|
+
host.__reploExternalNavigationHandler = (url) => {
|
|
125
|
+
openInParent(url);
|
|
126
|
+
return true;
|
|
127
|
+
};
|
|
128
|
+
if (mode === "live-shared-preview") {
|
|
129
|
+
const removeListeners = addSharedPreviewCheckoutListeners(navigation);
|
|
130
|
+
return () => {
|
|
131
|
+
delete host.__reploExternalNavigationHandler;
|
|
132
|
+
removeListeners();
|
|
133
|
+
};
|
|
134
|
+
}
|
|
48
135
|
const originalWindowOpen = window.open;
|
|
49
136
|
const originalPushState = history.pushState;
|
|
50
137
|
const originalReplaceState = history.replaceState;
|
|
51
|
-
const navigation = getWindowNavigation();
|
|
52
138
|
const reportNavigated = (rawUrl) => {
|
|
53
139
|
window.parent.postMessage(
|
|
54
140
|
{
|
|
@@ -58,23 +144,6 @@ function LinkInterceptor() {
|
|
|
58
144
|
"*"
|
|
59
145
|
);
|
|
60
146
|
};
|
|
61
|
-
const openInParent = (rawUrl) => {
|
|
62
|
-
const resolved = resolveUrl(rawUrl);
|
|
63
|
-
if (!resolved) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
window.parent.postMessage(
|
|
67
|
-
{
|
|
68
|
-
type: "replo:open-external",
|
|
69
|
-
url: resolved.toString()
|
|
70
|
-
},
|
|
71
|
-
"*"
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
Reflect.set(window, EXTERNAL_NAVIGATION_HANDLER_KEY, (url) => {
|
|
75
|
-
openInParent(url);
|
|
76
|
-
return true;
|
|
77
|
-
});
|
|
78
147
|
window.open = function(url, target, features) {
|
|
79
148
|
if (url !== void 0 && url !== "" && urlLeavesSandbox(url) === true) {
|
|
80
149
|
openInParent(url);
|
|
@@ -156,7 +225,7 @@ function LinkInterceptor() {
|
|
|
156
225
|
navigation?.addEventListener("navigate", handleNavigate);
|
|
157
226
|
document.addEventListener("click", handleClick, true);
|
|
158
227
|
return () => {
|
|
159
|
-
|
|
228
|
+
delete host.__reploExternalNavigationHandler;
|
|
160
229
|
window.open = originalWindowOpen;
|
|
161
230
|
history.pushState = originalPushState;
|
|
162
231
|
history.replaceState = originalReplaceState;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { coerceNumberToString, deepCloneAndMergeReplacingArrays, errorMessage, exhaustiveSwitch, formatFileSize, getFromRecordOrNull, hasOwnProperty, invariant, isEmpty, isFunction_default as isFunction, isNotNullish, isNullish, isPrimitive, isString_default as isString, mergeReplacingArrays, mergeReplacingObjects, noop, preventDefault, sleep, sleepWithSignal, warning } from '../../../chunk-THOBCJJA.mjs';
|
|
2
|
-
export { isNumber_default as isNumber } from '../../../chunk-SKVPFN7M.mjs';
|
|
3
2
|
import '../../../chunk-4ITJNSXZ.mjs';
|
|
3
|
+
export { isNumber_default as isNumber } from '../../../chunk-SKVPFN7M.mjs';
|
|
4
4
|
import '../../../chunk-XYS6G2ZC.mjs';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
export declare const EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID: "replo:external-navigation-iframe-rpc";
|
|
3
|
+
export declare const EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION: 1;
|
|
4
|
+
export declare const sandboxToParentExternalNavigationMethodConfig: {
|
|
5
|
+
openExternal: {
|
|
6
|
+
inputSchema: z.ZodObject<{
|
|
7
|
+
url: z.ZodURL;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
outputSchema: z.ZodVoid;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export declare const parentToSandboxExternalNavigationMethodConfig: {};
|
|
13
|
+
/** Opens what the frame hands up in a new tab. Null `frameOrigin` accepts any origin. */
|
|
14
|
+
export declare function createExternalNavigationParentChannel({ getFrameWindow, frameOrigin, }: {
|
|
15
|
+
getFrameWindow: () => Window | null;
|
|
16
|
+
frameOrigin: string | null;
|
|
17
|
+
}): import("./iframeRpcChannel").IframeRpcChannel<{}>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createIframeRpcChannel } from '../../chunk-36IPO47A.mjs';
|
|
2
|
+
import '../../chunk-ZTT7SNYN.mjs';
|
|
3
|
+
import '../../chunk-THOBCJJA.mjs';
|
|
4
|
+
import '../../chunk-4ITJNSXZ.mjs';
|
|
5
|
+
import '../../chunk-SKVPFN7M.mjs';
|
|
6
|
+
import '../../chunk-XYS6G2ZC.mjs';
|
|
7
|
+
import * as z from 'zod';
|
|
8
|
+
|
|
9
|
+
var EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID = "replo:external-navigation-iframe-rpc";
|
|
10
|
+
var EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION = 1;
|
|
11
|
+
var sandboxToParentExternalNavigationMethodConfig = {
|
|
12
|
+
openExternal: {
|
|
13
|
+
inputSchema: z.object({ url: z.url({ protocol: /^https?$/ }) }),
|
|
14
|
+
outputSchema: z.void()
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var parentToSandboxExternalNavigationMethodConfig = {};
|
|
18
|
+
function createExternalNavigationParentChannel({
|
|
19
|
+
getFrameWindow,
|
|
20
|
+
frameOrigin
|
|
21
|
+
}) {
|
|
22
|
+
return createIframeRpcChannel({
|
|
23
|
+
subscriberWindow: window,
|
|
24
|
+
channelIdentifier: EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID,
|
|
25
|
+
version: EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION,
|
|
26
|
+
getTargetWindow: getFrameWindow,
|
|
27
|
+
targetOrigin: "*",
|
|
28
|
+
isExpectedMessage: (event) => {
|
|
29
|
+
return event.source === getFrameWindow() && (frameOrigin === null || event.origin === frameOrigin);
|
|
30
|
+
},
|
|
31
|
+
outgoingMethods: parentToSandboxExternalNavigationMethodConfig,
|
|
32
|
+
incomingMethods: sandboxToParentExternalNavigationMethodConfig,
|
|
33
|
+
handlers: {
|
|
34
|
+
openExternal: ({ url: url2 }) => {
|
|
35
|
+
window.open(url2, "_blank", "noopener,noreferrer");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_ID, EXTERNAL_NAVIGATION_IFRAME_RPC_CHANNEL_VERSION, createExternalNavigationParentChannel, parentToSandboxExternalNavigationMethodConfig, sandboxToParentExternalNavigationMethodConfig };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createIframeRpcChannel, createIframeRpcRemote, iframeRpcCallSchema } from '../../chunk-36IPO47A.mjs';
|
|
2
2
|
import '../../chunk-ZTT7SNYN.mjs';
|
|
3
3
|
import '../../chunk-THOBCJJA.mjs';
|
|
4
|
-
import '../../chunk-SKVPFN7M.mjs';
|
|
5
4
|
import '../../chunk-4ITJNSXZ.mjs';
|
|
5
|
+
import '../../chunk-SKVPFN7M.mjs';
|
|
6
6
|
import '../../chunk-XYS6G2ZC.mjs';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createIframeRpcChannel } from '../../chunk-36IPO47A.mjs';
|
|
2
2
|
import '../../chunk-ZTT7SNYN.mjs';
|
|
3
3
|
import '../../chunk-THOBCJJA.mjs';
|
|
4
|
-
import '../../chunk-SKVPFN7M.mjs';
|
|
5
4
|
import '../../chunk-4ITJNSXZ.mjs';
|
|
5
|
+
import '../../chunk-SKVPFN7M.mjs';
|
|
6
6
|
import '../../chunk-XYS6G2ZC.mjs';
|
|
7
7
|
import * as z from 'zod';
|
|
8
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { SELECT_MODE_SELECTABLE_ATTRIBUTE, SELECT_MODE_SELECTABLE_PAYLOAD_ATTRIBUTE, displayModeSchema, getIframeOffset, isSelectedSection, readSelectablePayload, selectModeBoundingRectSchema, selectModeClickPositionSchema, selectModeDefinedStyleSchema, selectModeFiberChainEntrySchema, selectModeFormatCommandSchema, selectModeHoverRectSchema, selectModeImageSchema, selectModeImageScopeSchema, selectModeImageSourceSchema, selectModeInlineTextStatusSchema, selectModeOptimisticUpdatePayloadSchema, selectModeSelectionRectSchema, selectModeSelectionSchema, selectModeSelectionTypeSchema, selectModeSourceLocationSchema, selectModeStyleAtRuleSchema, selectModeStyleVariantSchema, selectModeTextMetricsSchema, selectModeTiptapActiveMarksSchema, selectModeVideoSchema, selectableDataPayloadSchema, selectableDataSchema, selectablePlanDataSchema, selectablePlanPayloadSchema, selectedElementSchema, transformPoint, transformRect, transformSelectableData, transformSelectedElement } from '../../chunk-QTGDSYSU.mjs';
|
|
2
2
|
import '../../chunk-THOBCJJA.mjs';
|
|
3
|
-
import '../../chunk-SKVPFN7M.mjs';
|
|
4
3
|
import '../../chunk-4ITJNSXZ.mjs';
|
|
4
|
+
import '../../chunk-SKVPFN7M.mjs';
|
|
5
5
|
import '../../chunk-XYS6G2ZC.mjs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { selectModeBoundingRectSchema, selectModeTiptapActiveMarksSchema, selectModeSelectionRectSchema, selectableDataSchema, selectModeHoverRectSchema, selectModeFormatCommandSchema, selectModeOptimisticUpdatePayloadSchema, selectModeSelectionTypeSchema, displayModeSchema, selectModeClickPositionSchema, selectedElementSchema } from '../../chunk-QTGDSYSU.mjs';
|
|
2
2
|
import '../../chunk-THOBCJJA.mjs';
|
|
3
|
-
import '../../chunk-SKVPFN7M.mjs';
|
|
4
3
|
import '../../chunk-4ITJNSXZ.mjs';
|
|
4
|
+
import '../../chunk-SKVPFN7M.mjs';
|
|
5
5
|
import '../../chunk-XYS6G2ZC.mjs';
|
|
6
6
|
import * as z from 'zod';
|
|
7
7
|
|
package/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.3",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-10-
|
|
5
|
+
"commit": "1b05582b9331219dbbcb56ff30f0876086df7e32",
|
|
6
|
+
"builtAt": "2026-10-24T18:33:20.377Z"
|
|
7
7
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.3",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sandbox-runtime",
|
|
6
|
-
"version": "1.19.
|
|
6
|
+
"version": "1.19.3",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-10-
|
|
8
|
+
"commit": "1b05582b9331219dbbcb56ff30f0876086df7e32",
|
|
9
|
+
"builtAt": "2026-10-24T18:33:20.377Z"
|
|
10
10
|
},
|
|
11
11
|
"description": "Replo sandbox runtime — editor integration for agent-built Next.js sites.",
|
|
12
12
|
"license": "SEE LICENSE IN LICENSE",
|
package/previewHealth.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ declare global {
|
|
|
19
19
|
__reploPreviewHealthMonitor?: PreviewHealthMonitor;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Next's error dialog locks the body's scroll while it's open, and the
|
|
24
|
+
* stylesheet above hides that dialog, so the page would stop scrolling for no
|
|
25
|
+
* visible reason. Only a lock taken while the dialog is mounted is released;
|
|
26
|
+
* a site's own lock (a mobile menu, a modal) is left alone.
|
|
27
|
+
*/
|
|
28
|
+
export declare function releaseNextOverlayScrollLock(): () => void;
|
|
22
29
|
/** The document's preview health actions; null outside an embedded preview. */
|
|
23
30
|
export declare function getPreviewHealthActions(): PreviewHealthActions | null;
|
|
24
31
|
export declare function resetPreviewHealthMonitorForTests(): void;
|
package/previewHealth.js
CHANGED
|
@@ -294,6 +294,7 @@ function createPreviewHealthMonitor() {
|
|
|
294
294
|
overlayStyle.dataset.reploPreviewHealth = "";
|
|
295
295
|
overlayStyle.textContent = "nextjs-portal{display:none!important}";
|
|
296
296
|
document.head.append(overlayStyle);
|
|
297
|
+
const stopScrollLockRelease = releaseNextOverlayScrollLock();
|
|
297
298
|
const stopBuildStatus = subscribeToBuildStatus({
|
|
298
299
|
onBuildErrors: actions.buildErrorsChanged
|
|
299
300
|
});
|
|
@@ -303,6 +304,7 @@ function createPreviewHealthMonitor() {
|
|
|
303
304
|
unsubscribe();
|
|
304
305
|
stopBuildStatus();
|
|
305
306
|
overlayStyle.remove();
|
|
307
|
+
stopScrollLockRelease();
|
|
306
308
|
cancelPendingRecovery();
|
|
307
309
|
if (window.__reploNextErrorFeed?.listener === handleNextError) {
|
|
308
310
|
window.__reploNextErrorFeed.listener = null;
|
|
@@ -310,6 +312,34 @@ function createPreviewHealthMonitor() {
|
|
|
310
312
|
}
|
|
311
313
|
};
|
|
312
314
|
}
|
|
315
|
+
function releaseNextOverlayScrollLock() {
|
|
316
|
+
const release = () => {
|
|
317
|
+
const portal = document.querySelector("nextjs-portal");
|
|
318
|
+
const isDialogOpen = Boolean(
|
|
319
|
+
portal?.shadowRoot?.querySelector("[data-nextjs-dialog-overlay]")
|
|
320
|
+
);
|
|
321
|
+
if (isDialogOpen && document.body.style.overflow === "hidden") {
|
|
322
|
+
document.body.style.overflow = "";
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const observer = new MutationObserver(release);
|
|
326
|
+
const observe = () => {
|
|
327
|
+
observer.observe(document.body, {
|
|
328
|
+
attributes: true,
|
|
329
|
+
attributeFilter: ["style"]
|
|
330
|
+
});
|
|
331
|
+
release();
|
|
332
|
+
};
|
|
333
|
+
if (document.body) {
|
|
334
|
+
observe();
|
|
335
|
+
} else {
|
|
336
|
+
document.addEventListener("DOMContentLoaded", observe, { once: true });
|
|
337
|
+
}
|
|
338
|
+
return () => {
|
|
339
|
+
observer.disconnect();
|
|
340
|
+
document.removeEventListener("DOMContentLoaded", observe);
|
|
341
|
+
};
|
|
342
|
+
}
|
|
313
343
|
function openSocket(url) {
|
|
314
344
|
return new Promise((resolve) => {
|
|
315
345
|
const socket = new window.WebSocket(url);
|
|
@@ -427,5 +457,6 @@ if (typeof window !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
|
427
457
|
}
|
|
428
458
|
export {
|
|
429
459
|
getPreviewHealthActions,
|
|
460
|
+
releaseNextOverlayScrollLock,
|
|
430
461
|
resetPreviewHealthMonitorForTests
|
|
431
462
|
};
|