@stringpush/sdk 0.2.0 → 0.3.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/README.md +7 -6
- package/dist/{chunk-FROJCNV7.umd.cjs → chunk-D2H2PTN2.umd.cjs} +134 -4
- package/dist/chunk-D2H2PTN2.umd.cjs.map +1 -0
- package/dist/{chunk-X3WTVBZ6.mjs → chunk-YYR2BH3L.mjs} +132 -2
- package/dist/chunk-YYR2BH3L.mjs.map +1 -0
- package/dist/{edit-launcher-PTZ5BIO2.mjs → edit-launcher-YJB2FBO7.mjs} +118 -74
- package/dist/edit-launcher-YJB2FBO7.mjs.map +1 -0
- package/dist/{edit-launcher-DB2DJSQJ.umd.cjs → edit-launcher-Z5AGCAQB.umd.cjs} +120 -76
- package/dist/edit-launcher-Z5AGCAQB.umd.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +7 -3
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.cjs +19 -15
- package/dist/index.umd.cjs.map +1 -1
- package/dist/{overlay-MLOXYRPA.umd.cjs → overlay-WO46AIRO.umd.cjs} +461 -143
- package/dist/overlay-WO46AIRO.umd.cjs.map +1 -0
- package/dist/{overlay-7KC2RRGB.mjs → overlay-Y3NQFQBI.mjs} +454 -136
- package/dist/overlay-Y3NQFQBI.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-FROJCNV7.umd.cjs.map +0 -1
- package/dist/chunk-X3WTVBZ6.mjs.map +0 -1
- package/dist/edit-launcher-DB2DJSQJ.umd.cjs.map +0 -1
- package/dist/edit-launcher-PTZ5BIO2.mjs.map +0 -1
- package/dist/overlay-7KC2RRGB.mjs.map +0 -1
- package/dist/overlay-MLOXYRPA.umd.cjs.map +0 -1
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
adminOriginFromSignInUrl,
|
|
3
|
+
buildOverlayGrantUrl,
|
|
4
|
+
clearEditToken,
|
|
2
5
|
decodeEditTokenClaims,
|
|
6
|
+
listenForOverlayGrant,
|
|
7
|
+
newRequestId,
|
|
8
|
+
openOverlayGrantPopup,
|
|
3
9
|
persistEditToken,
|
|
4
|
-
readEditTokenFromStorage
|
|
5
|
-
|
|
10
|
+
readEditTokenFromStorage,
|
|
11
|
+
redirectToOverlayGrant,
|
|
12
|
+
watchPopupClosed
|
|
13
|
+
} from "./chunk-YYR2BH3L.mjs";
|
|
6
14
|
|
|
7
15
|
// src/edit-launcher/constants.ts
|
|
8
16
|
var LAUNCHER_ROOT_ID = "translation-edit-launcher-root";
|
|
@@ -84,6 +92,7 @@ function mountEditLauncher(context) {
|
|
|
84
92
|
overflow: hidden;
|
|
85
93
|
text-overflow: ellipsis;
|
|
86
94
|
}
|
|
95
|
+
.edit-bar__hint.is-error { color: #b91c1c; }
|
|
87
96
|
.fab {
|
|
88
97
|
flex-shrink: 0;
|
|
89
98
|
border: none;
|
|
@@ -99,32 +108,6 @@ function mountEditLauncher(context) {
|
|
|
99
108
|
}
|
|
100
109
|
.fab:hover { background: #3730a3; }
|
|
101
110
|
.fab.is-editing { background: #0f766e; box-shadow: 0 2px 8px rgba(15, 118, 110, 0.28); }
|
|
102
|
-
.panel {
|
|
103
|
-
position: fixed;
|
|
104
|
-
bottom: 72px;
|
|
105
|
-
left: 20px;
|
|
106
|
-
z-index: 2147483645;
|
|
107
|
-
width: min(300px, calc(100vw - 40px));
|
|
108
|
-
padding: 14px;
|
|
109
|
-
border-radius: 12px;
|
|
110
|
-
background: #fff;
|
|
111
|
-
color: #0f172a;
|
|
112
|
-
border: 1px solid #e2e8f0;
|
|
113
|
-
box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
|
|
114
|
-
}
|
|
115
|
-
.panel p { margin: 0 0 10px; line-height: 1.45; font-size: 13px; color: #475569; }
|
|
116
|
-
.panel button {
|
|
117
|
-
width: 100%;
|
|
118
|
-
border: none;
|
|
119
|
-
border-radius: 8px;
|
|
120
|
-
padding: 9px 12px;
|
|
121
|
-
cursor: pointer;
|
|
122
|
-
font: inherit;
|
|
123
|
-
font-weight: 600;
|
|
124
|
-
}
|
|
125
|
-
.panel .primary { background: #4338ca; color: #fff; }
|
|
126
|
-
.panel .primary:disabled { opacity: 0.6; cursor: wait; }
|
|
127
|
-
.panel .error { margin-top: 8px; color: #b91c1c; font-size: 12px; }
|
|
128
111
|
.marker { display: none; }
|
|
129
112
|
`;
|
|
130
113
|
const wrap = document.createElement("div");
|
|
@@ -149,95 +132,156 @@ function mountEditLauncher(context) {
|
|
|
149
132
|
fab.className = "fab";
|
|
150
133
|
fab.textContent = "Translate";
|
|
151
134
|
bar.append(left, fab);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
135
|
+
wrap.append(marker, bar);
|
|
136
|
+
shadow.append(style, wrap);
|
|
137
|
+
document.body.append(host);
|
|
138
|
+
const signInUrl = context.launcherOptions.signInUrl;
|
|
139
|
+
const signInMode = context.launcherOptions.signInMode ?? "popup";
|
|
140
|
+
let currentRequestId = null;
|
|
141
|
+
let grantPopup = null;
|
|
142
|
+
let stopPopupWatch = null;
|
|
143
|
+
const defaultHint = "Translate copy on this page";
|
|
158
144
|
const syncFabLabel = () => {
|
|
159
145
|
if (context.isEditModeActive()) {
|
|
160
146
|
fab.textContent = "Stop editing";
|
|
161
147
|
fab.classList.add("is-editing");
|
|
162
148
|
pill.hidden = false;
|
|
163
149
|
hint.hidden = true;
|
|
164
|
-
|
|
150
|
+
hint.classList.remove("is-error");
|
|
165
151
|
} else {
|
|
166
152
|
fab.textContent = "Translate";
|
|
167
153
|
fab.classList.remove("is-editing");
|
|
168
154
|
pill.hidden = true;
|
|
169
155
|
hint.hidden = false;
|
|
156
|
+
if (!hint.classList.contains("is-error")) {
|
|
157
|
+
hint.textContent = defaultHint;
|
|
158
|
+
}
|
|
170
159
|
}
|
|
171
160
|
};
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
161
|
+
const clearGrantAttempt = () => {
|
|
162
|
+
currentRequestId = null;
|
|
163
|
+
stopPopupWatch?.();
|
|
164
|
+
stopPopupWatch = null;
|
|
165
|
+
grantPopup = null;
|
|
175
166
|
};
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
const showInlineError = (message) => {
|
|
168
|
+
hint.hidden = false;
|
|
169
|
+
hint.textContent = message;
|
|
170
|
+
hint.classList.add("is-error");
|
|
171
|
+
};
|
|
172
|
+
const clearInlineStatus = () => {
|
|
173
|
+
hint.classList.remove("is-error");
|
|
174
|
+
hint.textContent = defaultHint;
|
|
175
|
+
};
|
|
176
|
+
const openGrantPopup = () => {
|
|
177
|
+
if (!signInUrl) {
|
|
178
|
+
showInlineError("Edit launcher auth is not configured.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (grantPopup && !grantPopup.closed) {
|
|
182
|
+
grantPopup.focus();
|
|
183
|
+
hint.hidden = false;
|
|
184
|
+
hint.textContent = "Complete sign-in in the popup.";
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const returnUrl = window.location.href.split("#")[0] ?? window.location.href;
|
|
188
|
+
currentRequestId = newRequestId();
|
|
189
|
+
const grantUrl = buildOverlayGrantUrl(signInUrl, {
|
|
190
|
+
returnUrl,
|
|
191
|
+
applicationId: context.initOptions.applicationId,
|
|
192
|
+
environment: context.initOptions.environment,
|
|
193
|
+
mode: signInMode,
|
|
194
|
+
requestId: currentRequestId
|
|
195
|
+
});
|
|
196
|
+
if (signInMode === "redirect") {
|
|
197
|
+
redirectToOverlayGrant(grantUrl);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const popup = openOverlayGrantPopup(grantUrl);
|
|
201
|
+
if (!popup) {
|
|
202
|
+
redirectToOverlayGrant(grantUrl);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
grantPopup = popup;
|
|
206
|
+
hint.hidden = false;
|
|
207
|
+
hint.textContent = "Complete sign-in in the popup.";
|
|
208
|
+
stopPopupWatch = watchPopupClosed(popup, () => {
|
|
209
|
+
if (currentRequestId) {
|
|
210
|
+
clearGrantAttempt();
|
|
211
|
+
if (!context.isEditModeActive()) {
|
|
212
|
+
showInlineError("Sign-in window closed before finishing.");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
179
216
|
};
|
|
217
|
+
let stopOverlayGrantListener = null;
|
|
218
|
+
if (signInUrl && signInMode === "popup") {
|
|
219
|
+
const adminOrigin = adminOriginFromSignInUrl(signInUrl);
|
|
220
|
+
stopOverlayGrantListener = listenForOverlayGrant(
|
|
221
|
+
adminOrigin,
|
|
222
|
+
() => currentRequestId,
|
|
223
|
+
{
|
|
224
|
+
onGranted: (token) => {
|
|
225
|
+
void (async () => {
|
|
226
|
+
clearInlineStatus();
|
|
227
|
+
persistEditToken(token);
|
|
228
|
+
try {
|
|
229
|
+
await context.enableEditMode();
|
|
230
|
+
clearGrantAttempt();
|
|
231
|
+
syncFabLabel();
|
|
232
|
+
} catch (err) {
|
|
233
|
+
clearEditToken();
|
|
234
|
+
showInlineError(err instanceof Error ? err.message : String(err));
|
|
235
|
+
openGrantPopup();
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
},
|
|
239
|
+
onError: (message) => {
|
|
240
|
+
clearGrantAttempt();
|
|
241
|
+
showInlineError(message);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
}
|
|
180
246
|
fab.addEventListener("click", () => {
|
|
181
247
|
void (async () => {
|
|
182
|
-
clearError();
|
|
183
248
|
if (context.isEditModeActive()) {
|
|
184
249
|
context.disableEditMode();
|
|
250
|
+
clearInlineStatus();
|
|
185
251
|
syncFabLabel();
|
|
186
252
|
return;
|
|
187
253
|
}
|
|
254
|
+
clearInlineStatus();
|
|
188
255
|
const existing = storedEditToken(context.initOptions);
|
|
189
256
|
if (existing) {
|
|
190
257
|
try {
|
|
191
258
|
await context.enableEditMode();
|
|
192
259
|
syncFabLabel();
|
|
193
|
-
|
|
194
|
-
|
|
260
|
+
return;
|
|
261
|
+
} catch {
|
|
262
|
+
clearEditToken();
|
|
195
263
|
}
|
|
196
|
-
return;
|
|
197
264
|
}
|
|
198
|
-
|
|
199
|
-
})();
|
|
200
|
-
});
|
|
201
|
-
signInBtn.addEventListener("click", () => {
|
|
202
|
-
void (async () => {
|
|
203
|
-
clearError();
|
|
204
|
-
const { signInUrl, requestEditToken } = context.launcherOptions;
|
|
265
|
+
const { requestEditToken } = context.launcherOptions;
|
|
205
266
|
if (requestEditToken) {
|
|
206
|
-
signInBtn.disabled = true;
|
|
207
267
|
try {
|
|
208
268
|
const token = await requestEditToken();
|
|
209
269
|
persistEditToken(token);
|
|
210
270
|
await context.enableEditMode();
|
|
211
|
-
panel.hidden = true;
|
|
212
271
|
syncFabLabel();
|
|
213
272
|
} catch (err) {
|
|
214
|
-
|
|
215
|
-
} finally {
|
|
216
|
-
signInBtn.disabled = false;
|
|
273
|
+
showInlineError(err instanceof Error ? err.message : String(err));
|
|
217
274
|
}
|
|
218
275
|
return;
|
|
219
276
|
}
|
|
220
|
-
|
|
221
|
-
const params = new URLSearchParams();
|
|
222
|
-
params.set(
|
|
223
|
-
"returnUrl",
|
|
224
|
-
window.location.href.split("#")[0] ?? window.location.href
|
|
225
|
-
);
|
|
226
|
-
params.set("applicationId", context.initOptions.applicationId);
|
|
227
|
-
params.set("environment", context.initOptions.environment);
|
|
228
|
-
const separator = signInUrl.includes("?") ? "&" : "?";
|
|
229
|
-
window.location.href = `${signInUrl}${separator}${params.toString()}`;
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
showError("Edit launcher auth is not configured.");
|
|
277
|
+
openGrantPopup();
|
|
233
278
|
})();
|
|
234
279
|
});
|
|
235
|
-
wrap.append(marker, bar, panel);
|
|
236
|
-
shadow.append(style, wrap);
|
|
237
|
-
document.body.append(host);
|
|
238
280
|
syncFabLabel();
|
|
239
281
|
return {
|
|
240
282
|
destroy: () => {
|
|
283
|
+
stopOverlayGrantListener?.();
|
|
284
|
+
clearGrantAttempt();
|
|
241
285
|
host.remove();
|
|
242
286
|
}
|
|
243
287
|
};
|
|
@@ -247,4 +291,4 @@ export {
|
|
|
247
291
|
LAUNCHER_ROOT_ID,
|
|
248
292
|
mountEditLauncher
|
|
249
293
|
};
|
|
250
|
-
//# sourceMappingURL=edit-launcher-
|
|
294
|
+
//# sourceMappingURL=edit-launcher-YJB2FBO7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/edit-launcher/constants.ts","../src/edit-launcher/index.ts"],"sourcesContent":["/**\n * DOM and bundle-split markers for the lazy-loaded edit launcher chunk (M2-SDK-05).\n *\n * Intent: stable ids/markers keep overlay UI out of the default SDK entry until edit mode activates.\n */\nexport const LAUNCHER_ROOT_ID = \"translation-edit-launcher-root\";\n\n/** Marker string used in bundle-split tests to keep launcher out of the main entry. */\nexport const LAUNCHER_CHUNK_MARKER = \"translation-edit-launcher-chunk-v1\";\n","/**\n * Lazy-loaded bottom bar launcher for staging overlay (M2-SDK-05, UI-09).\n *\n * Intent: `?translation_edit=1` arms the UI only; Translate opens popup grant or enables from stored token.\n */\nimport {\n clearEditToken,\n persistEditToken,\n readEditTokenFromStorage,\n} from \"../edit-token.js\";\nimport { decodeEditTokenClaims } from \"../edit-token-decode.js\";\nimport {\n adminOriginFromSignInUrl,\n buildOverlayGrantUrl,\n listenForOverlayGrant,\n newRequestId,\n openOverlayGrantPopup,\n redirectToOverlayGrant,\n watchPopupClosed,\n type OverlayGrantMode,\n} from \"./sign-in-popup.js\";\nimport type { EditLauncherOptions, InitOptions } from \"../types.js\";\nimport { LAUNCHER_CHUNK_MARKER, LAUNCHER_ROOT_ID } from \"./constants.js\";\n\nexport { LAUNCHER_CHUNK_MARKER, LAUNCHER_ROOT_ID } from \"./constants.js\";\n\nexport type EditLauncherMountContext = {\n initOptions: InitOptions;\n launcherOptions: EditLauncherOptions;\n isEditModeActive: () => boolean;\n enableEditMode: () => Promise<void>;\n disableEditMode: () => void;\n};\n\nexport type EditLauncherHandle = {\n destroy: () => void;\n};\n\nfunction tokenMatchesInit(token: string, options: InitOptions): boolean {\n const claims = decodeEditTokenClaims(token);\n if (!claims) {\n return false;\n }\n return (\n claims.applicationId === options.applicationId &&\n claims.environmentName === options.environment\n );\n}\n\nfunction storedEditToken(options: InitOptions): string | null {\n const token = readEditTokenFromStorage();\n if (!token || !tokenMatchesInit(token, options)) {\n return null;\n }\n return token;\n}\n\n/**\n * Mounts bottom edit bar in a shadow root; Translate is the single auth gesture.\n */\nexport function mountEditLauncher(context: EditLauncherMountContext): EditLauncherHandle {\n if (typeof document === \"undefined\") {\n return { destroy: () => {} };\n }\n\n document.getElementById(LAUNCHER_ROOT_ID)?.remove();\n\n const host = document.createElement(\"div\");\n host.id = LAUNCHER_ROOT_ID;\n host.setAttribute(\"data-translation-edit-launcher\", \"true\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n const style = document.createElement(\"style\");\n style.textContent = `\n :host { all: initial; }\n .wrap { font-family: system-ui, -apple-system, Segoe UI, sans-serif; font-size: 14px; }\n .edit-bar {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2147483645;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 20px;\n background: #fff;\n border-top: 1px solid #e2e8f0;\n box-shadow: 0 -4px 24px rgba(15, 23, 42, 0.08);\n }\n .edit-bar__left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n }\n .edit-mode-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n background: #d1fae5;\n color: #047857;\n font-size: 12px;\n font-weight: 600;\n white-space: nowrap;\n }\n .edit-mode-pill::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #10b981;\n }\n .edit-bar__hint {\n color: #64748b;\n font-size: 13px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .edit-bar__hint.is-error { color: #b91c1c; }\n .fab {\n flex-shrink: 0;\n border: none;\n border-radius: 8px;\n padding: 10px 18px;\n background: #4338ca;\n color: #fff;\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 600;\n box-shadow: 0 2px 8px rgba(67, 56, 202, 0.28);\n }\n .fab:hover { background: #3730a3; }\n .fab.is-editing { background: #0f766e; box-shadow: 0 2px 8px rgba(15, 118, 110, 0.28); }\n .marker { display: none; }\n `;\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n\n const marker = document.createElement(\"span\");\n marker.className = \"marker\";\n marker.textContent = LAUNCHER_CHUNK_MARKER;\n\n const bar = document.createElement(\"div\");\n bar.className = \"edit-bar\";\n\n const left = document.createElement(\"div\");\n left.className = \"edit-bar__left\";\n\n const pill = document.createElement(\"span\");\n pill.className = \"edit-mode-pill\";\n pill.textContent = \"Edit mode active\";\n pill.hidden = true;\n\n const hint = document.createElement(\"span\");\n hint.className = \"edit-bar__hint\";\n hint.textContent = \"Translate copy on this page\";\n\n left.append(pill, hint);\n\n const fab = document.createElement(\"button\");\n fab.type = \"button\";\n fab.className = \"fab\";\n fab.textContent = \"Translate\";\n\n bar.append(left, fab);\n wrap.append(marker, bar);\n shadow.append(style, wrap);\n document.body.append(host);\n\n const signInUrl = context.launcherOptions.signInUrl;\n const signInMode: OverlayGrantMode = context.launcherOptions.signInMode ?? \"popup\";\n\n let currentRequestId: string | null = null;\n let grantPopup: Window | null = null;\n let stopPopupWatch: (() => void) | null = null;\n\n const defaultHint = \"Translate copy on this page\";\n\n const syncFabLabel = (): void => {\n if (context.isEditModeActive()) {\n fab.textContent = \"Stop editing\";\n fab.classList.add(\"is-editing\");\n pill.hidden = false;\n hint.hidden = true;\n hint.classList.remove(\"is-error\");\n } else {\n fab.textContent = \"Translate\";\n fab.classList.remove(\"is-editing\");\n pill.hidden = true;\n hint.hidden = false;\n if (!hint.classList.contains(\"is-error\")) {\n hint.textContent = defaultHint;\n }\n }\n };\n\n const clearGrantAttempt = (): void => {\n currentRequestId = null;\n stopPopupWatch?.();\n stopPopupWatch = null;\n grantPopup = null;\n };\n\n const showInlineError = (message: string): void => {\n hint.hidden = false;\n hint.textContent = message;\n hint.classList.add(\"is-error\");\n };\n\n const clearInlineStatus = (): void => {\n hint.classList.remove(\"is-error\");\n hint.textContent = defaultHint;\n };\n\n const openGrantPopup = (): void => {\n if (!signInUrl) {\n showInlineError(\"Edit launcher auth is not configured.\");\n return;\n }\n\n if (grantPopup && !grantPopup.closed) {\n grantPopup.focus();\n hint.hidden = false;\n hint.textContent = \"Complete sign-in in the popup.\";\n return;\n }\n\n const returnUrl = window.location.href.split(\"#\")[0] ?? window.location.href;\n currentRequestId = newRequestId();\n const grantUrl = buildOverlayGrantUrl(signInUrl, {\n returnUrl,\n applicationId: context.initOptions.applicationId,\n environment: context.initOptions.environment,\n mode: signInMode,\n requestId: currentRequestId,\n });\n\n if (signInMode === \"redirect\") {\n redirectToOverlayGrant(grantUrl);\n return;\n }\n\n const popup = openOverlayGrantPopup(grantUrl);\n if (!popup) {\n redirectToOverlayGrant(grantUrl);\n return;\n }\n\n grantPopup = popup;\n hint.hidden = false;\n hint.textContent = \"Complete sign-in in the popup.\";\n stopPopupWatch = watchPopupClosed(popup, () => {\n if (currentRequestId) {\n clearGrantAttempt();\n if (!context.isEditModeActive()) {\n showInlineError(\"Sign-in window closed before finishing.\");\n }\n }\n });\n };\n\n let stopOverlayGrantListener: (() => void) | null = null;\n if (signInUrl && signInMode === \"popup\") {\n const adminOrigin = adminOriginFromSignInUrl(signInUrl);\n stopOverlayGrantListener = listenForOverlayGrant(\n adminOrigin,\n () => currentRequestId,\n {\n onGranted: (token) => {\n void (async () => {\n clearInlineStatus();\n persistEditToken(token);\n try {\n await context.enableEditMode();\n clearGrantAttempt();\n syncFabLabel();\n } catch (err) {\n clearEditToken();\n showInlineError(err instanceof Error ? err.message : String(err));\n openGrantPopup();\n }\n })();\n },\n onError: (message) => {\n clearGrantAttempt();\n showInlineError(message);\n },\n },\n );\n }\n\n fab.addEventListener(\"click\", () => {\n void (async () => {\n if (context.isEditModeActive()) {\n context.disableEditMode();\n clearInlineStatus();\n syncFabLabel();\n return;\n }\n\n clearInlineStatus();\n\n const existing = storedEditToken(context.initOptions);\n if (existing) {\n try {\n await context.enableEditMode();\n syncFabLabel();\n return;\n } catch {\n clearEditToken();\n }\n }\n\n const { requestEditToken } = context.launcherOptions;\n if (requestEditToken) {\n try {\n const token = await requestEditToken();\n persistEditToken(token);\n await context.enableEditMode();\n syncFabLabel();\n } catch (err) {\n showInlineError(err instanceof Error ? err.message : String(err));\n }\n return;\n }\n\n openGrantPopup();\n })();\n });\n\n syncFabLabel();\n\n return {\n destroy: () => {\n stopOverlayGrantListener?.();\n clearGrantAttempt();\n host.remove();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAKO,IAAM,mBAAmB;AAGzB,IAAM,wBAAwB;;;AC8BrC,SAAS,iBAAiB,OAAe,SAA+B;AACtE,QAAM,SAAS,sBAAsB,KAAK;AAC1C,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SACE,OAAO,kBAAkB,QAAQ,iBACjC,OAAO,oBAAoB,QAAQ;AAEvC;AAEA,SAAS,gBAAgB,SAAqC;AAC5D,QAAM,QAAQ,yBAAyB;AACvC,MAAI,CAAC,SAAS,CAAC,iBAAiB,OAAO,OAAO,GAAG;AAC/C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,kBAAkB,SAAuD;AACvF,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO,EAAE,SAAS,MAAM;AAAA,IAAC,EAAE;AAAA,EAC7B;AAEA,WAAS,eAAe,gBAAgB,GAAG,OAAO;AAElD,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,KAAK;AACV,OAAK,aAAa,kCAAkC,MAAM;AAE1D,QAAM,SAAS,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AACjD,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqEpB,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AAEjB,QAAM,SAAS,SAAS,cAAc,MAAM;AAC5C,SAAO,YAAY;AACnB,SAAO,cAAc;AAErB,QAAM,MAAM,SAAS,cAAc,KAAK;AACxC,MAAI,YAAY;AAEhB,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AAEjB,QAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,OAAK,YAAY;AACjB,OAAK,cAAc;AACnB,OAAK,SAAS;AAEd,QAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,OAAK,YAAY;AACjB,OAAK,cAAc;AAEnB,OAAK,OAAO,MAAM,IAAI;AAEtB,QAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,MAAI,cAAc;AAElB,MAAI,OAAO,MAAM,GAAG;AACpB,OAAK,OAAO,QAAQ,GAAG;AACvB,SAAO,OAAO,OAAO,IAAI;AACzB,WAAS,KAAK,OAAO,IAAI;AAEzB,QAAM,YAAY,QAAQ,gBAAgB;AAC1C,QAAM,aAA+B,QAAQ,gBAAgB,cAAc;AAE3E,MAAI,mBAAkC;AACtC,MAAI,aAA4B;AAChC,MAAI,iBAAsC;AAE1C,QAAM,cAAc;AAEpB,QAAM,eAAe,MAAY;AAC/B,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,UAAI,cAAc;AAClB,UAAI,UAAU,IAAI,YAAY;AAC9B,WAAK,SAAS;AACd,WAAK,SAAS;AACd,WAAK,UAAU,OAAO,UAAU;AAAA,IAClC,OAAO;AACL,UAAI,cAAc;AAClB,UAAI,UAAU,OAAO,YAAY;AACjC,WAAK,SAAS;AACd,WAAK,SAAS;AACd,UAAI,CAAC,KAAK,UAAU,SAAS,UAAU,GAAG;AACxC,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAY;AACpC,uBAAmB;AACnB,qBAAiB;AACjB,qBAAiB;AACjB,iBAAa;AAAA,EACf;AAEA,QAAM,kBAAkB,CAAC,YAA0B;AACjD,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,UAAU,IAAI,UAAU;AAAA,EAC/B;AAEA,QAAM,oBAAoB,MAAY;AACpC,SAAK,UAAU,OAAO,UAAU;AAChC,SAAK,cAAc;AAAA,EACrB;AAEA,QAAM,iBAAiB,MAAY;AACjC,QAAI,CAAC,WAAW;AACd,sBAAgB,uCAAuC;AACvD;AAAA,IACF;AAEA,QAAI,cAAc,CAAC,WAAW,QAAQ;AACpC,iBAAW,MAAM;AACjB,WAAK,SAAS;AACd,WAAK,cAAc;AACnB;AAAA,IACF;AAEA,UAAM,YAAY,OAAO,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,OAAO,SAAS;AACxE,uBAAmB,aAAa;AAChC,UAAM,WAAW,qBAAqB,WAAW;AAAA,MAC/C;AAAA,MACA,eAAe,QAAQ,YAAY;AAAA,MACnC,aAAa,QAAQ,YAAY;AAAA,MACjC,MAAM;AAAA,MACN,WAAW;AAAA,IACb,CAAC;AAED,QAAI,eAAe,YAAY;AAC7B,6BAAuB,QAAQ;AAC/B;AAAA,IACF;AAEA,UAAM,QAAQ,sBAAsB,QAAQ;AAC5C,QAAI,CAAC,OAAO;AACV,6BAAuB,QAAQ;AAC/B;AAAA,IACF;AAEA,iBAAa;AACb,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,qBAAiB,iBAAiB,OAAO,MAAM;AAC7C,UAAI,kBAAkB;AACpB,0BAAkB;AAClB,YAAI,CAAC,QAAQ,iBAAiB,GAAG;AAC/B,0BAAgB,yCAAyC;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,2BAAgD;AACpD,MAAI,aAAa,eAAe,SAAS;AACvC,UAAM,cAAc,yBAAyB,SAAS;AACtD,+BAA2B;AAAA,MACzB;AAAA,MACA,MAAM;AAAA,MACN;AAAA,QACE,WAAW,CAAC,UAAU;AACpB,gBAAM,YAAY;AAChB,8BAAkB;AAClB,6BAAiB,KAAK;AACtB,gBAAI;AACF,oBAAM,QAAQ,eAAe;AAC7B,gCAAkB;AAClB,2BAAa;AAAA,YACf,SAAS,KAAK;AACZ,6BAAe;AACf,8BAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAChE,6BAAe;AAAA,YACjB;AAAA,UACF,GAAG;AAAA,QACL;AAAA,QACA,SAAS,CAAC,YAAY;AACpB,4BAAkB;AAClB,0BAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAAiB,SAAS,MAAM;AAClC,UAAM,YAAY;AAChB,UAAI,QAAQ,iBAAiB,GAAG;AAC9B,gBAAQ,gBAAgB;AACxB,0BAAkB;AAClB,qBAAa;AACb;AAAA,MACF;AAEA,wBAAkB;AAElB,YAAM,WAAW,gBAAgB,QAAQ,WAAW;AACpD,UAAI,UAAU;AACZ,YAAI;AACF,gBAAM,QAAQ,eAAe;AAC7B,uBAAa;AACb;AAAA,QACF,QAAQ;AACN,yBAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,EAAE,iBAAiB,IAAI,QAAQ;AACrC,UAAI,kBAAkB;AACpB,YAAI;AACF,gBAAM,QAAQ,MAAM,iBAAiB;AACrC,2BAAiB,KAAK;AACtB,gBAAM,QAAQ,eAAe;AAC7B,uBAAa;AAAA,QACf,SAAS,KAAK;AACZ,0BAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAClE;AACA;AAAA,MACF;AAEA,qBAAe;AAAA,IACjB,GAAG;AAAA,EACL,CAAC;AAED,eAAa;AAEb,SAAO;AAAA,IACL,SAAS,MAAM;AACb,iCAA2B;AAC3B,wBAAkB;AAClB,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AACF;","names":[]}
|
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _chunkD2H2PTN2umdcjs = require('./chunk-D2H2PTN2.umd.cjs');
|
|
6
14
|
|
|
7
15
|
// src/edit-launcher/constants.ts
|
|
8
16
|
var LAUNCHER_ROOT_ID = "translation-edit-launcher-root";
|
|
@@ -10,14 +18,14 @@ var LAUNCHER_CHUNK_MARKER = "translation-edit-launcher-chunk-v1";
|
|
|
10
18
|
|
|
11
19
|
// src/edit-launcher/index.ts
|
|
12
20
|
function tokenMatchesInit(token, options) {
|
|
13
|
-
const claims =
|
|
21
|
+
const claims = _chunkD2H2PTN2umdcjs.decodeEditTokenClaims.call(void 0, token);
|
|
14
22
|
if (!claims) {
|
|
15
23
|
return false;
|
|
16
24
|
}
|
|
17
25
|
return claims.applicationId === options.applicationId && claims.environmentName === options.environment;
|
|
18
26
|
}
|
|
19
27
|
function storedEditToken(options) {
|
|
20
|
-
const token =
|
|
28
|
+
const token = _chunkD2H2PTN2umdcjs.readEditTokenFromStorage.call(void 0, );
|
|
21
29
|
if (!token || !tokenMatchesInit(token, options)) {
|
|
22
30
|
return null;
|
|
23
31
|
}
|
|
@@ -84,6 +92,7 @@ function mountEditLauncher(context) {
|
|
|
84
92
|
overflow: hidden;
|
|
85
93
|
text-overflow: ellipsis;
|
|
86
94
|
}
|
|
95
|
+
.edit-bar__hint.is-error { color: #b91c1c; }
|
|
87
96
|
.fab {
|
|
88
97
|
flex-shrink: 0;
|
|
89
98
|
border: none;
|
|
@@ -99,32 +108,6 @@ function mountEditLauncher(context) {
|
|
|
99
108
|
}
|
|
100
109
|
.fab:hover { background: #3730a3; }
|
|
101
110
|
.fab.is-editing { background: #0f766e; box-shadow: 0 2px 8px rgba(15, 118, 110, 0.28); }
|
|
102
|
-
.panel {
|
|
103
|
-
position: fixed;
|
|
104
|
-
bottom: 72px;
|
|
105
|
-
left: 20px;
|
|
106
|
-
z-index: 2147483645;
|
|
107
|
-
width: min(300px, calc(100vw - 40px));
|
|
108
|
-
padding: 14px;
|
|
109
|
-
border-radius: 12px;
|
|
110
|
-
background: #fff;
|
|
111
|
-
color: #0f172a;
|
|
112
|
-
border: 1px solid #e2e8f0;
|
|
113
|
-
box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
|
|
114
|
-
}
|
|
115
|
-
.panel p { margin: 0 0 10px; line-height: 1.45; font-size: 13px; color: #475569; }
|
|
116
|
-
.panel button {
|
|
117
|
-
width: 100%;
|
|
118
|
-
border: none;
|
|
119
|
-
border-radius: 8px;
|
|
120
|
-
padding: 9px 12px;
|
|
121
|
-
cursor: pointer;
|
|
122
|
-
font: inherit;
|
|
123
|
-
font-weight: 600;
|
|
124
|
-
}
|
|
125
|
-
.panel .primary { background: #4338ca; color: #fff; }
|
|
126
|
-
.panel .primary:disabled { opacity: 0.6; cursor: wait; }
|
|
127
|
-
.panel .error { margin-top: 8px; color: #b91c1c; font-size: 12px; }
|
|
128
111
|
.marker { display: none; }
|
|
129
112
|
`;
|
|
130
113
|
const wrap = document.createElement("div");
|
|
@@ -149,95 +132,156 @@ function mountEditLauncher(context) {
|
|
|
149
132
|
fab.className = "fab";
|
|
150
133
|
fab.textContent = "Translate";
|
|
151
134
|
bar.append(left, fab);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
135
|
+
wrap.append(marker, bar);
|
|
136
|
+
shadow.append(style, wrap);
|
|
137
|
+
document.body.append(host);
|
|
138
|
+
const signInUrl = context.launcherOptions.signInUrl;
|
|
139
|
+
const signInMode = _nullishCoalesce(context.launcherOptions.signInMode, () => ( "popup"));
|
|
140
|
+
let currentRequestId = null;
|
|
141
|
+
let grantPopup = null;
|
|
142
|
+
let stopPopupWatch = null;
|
|
143
|
+
const defaultHint = "Translate copy on this page";
|
|
158
144
|
const syncFabLabel = () => {
|
|
159
145
|
if (context.isEditModeActive()) {
|
|
160
146
|
fab.textContent = "Stop editing";
|
|
161
147
|
fab.classList.add("is-editing");
|
|
162
148
|
pill.hidden = false;
|
|
163
149
|
hint.hidden = true;
|
|
164
|
-
|
|
150
|
+
hint.classList.remove("is-error");
|
|
165
151
|
} else {
|
|
166
152
|
fab.textContent = "Translate";
|
|
167
153
|
fab.classList.remove("is-editing");
|
|
168
154
|
pill.hidden = true;
|
|
169
155
|
hint.hidden = false;
|
|
156
|
+
if (!hint.classList.contains("is-error")) {
|
|
157
|
+
hint.textContent = defaultHint;
|
|
158
|
+
}
|
|
170
159
|
}
|
|
171
160
|
};
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
161
|
+
const clearGrantAttempt = () => {
|
|
162
|
+
currentRequestId = null;
|
|
163
|
+
_optionalChain([stopPopupWatch, 'optionalCall', _5 => _5()]);
|
|
164
|
+
stopPopupWatch = null;
|
|
165
|
+
grantPopup = null;
|
|
175
166
|
};
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
167
|
+
const showInlineError = (message) => {
|
|
168
|
+
hint.hidden = false;
|
|
169
|
+
hint.textContent = message;
|
|
170
|
+
hint.classList.add("is-error");
|
|
179
171
|
};
|
|
172
|
+
const clearInlineStatus = () => {
|
|
173
|
+
hint.classList.remove("is-error");
|
|
174
|
+
hint.textContent = defaultHint;
|
|
175
|
+
};
|
|
176
|
+
const openGrantPopup = () => {
|
|
177
|
+
if (!signInUrl) {
|
|
178
|
+
showInlineError("Edit launcher auth is not configured.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (grantPopup && !grantPopup.closed) {
|
|
182
|
+
grantPopup.focus();
|
|
183
|
+
hint.hidden = false;
|
|
184
|
+
hint.textContent = "Complete sign-in in the popup.";
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const returnUrl = _nullishCoalesce(window.location.href.split("#")[0], () => ( window.location.href));
|
|
188
|
+
currentRequestId = _chunkD2H2PTN2umdcjs.newRequestId.call(void 0, );
|
|
189
|
+
const grantUrl = _chunkD2H2PTN2umdcjs.buildOverlayGrantUrl.call(void 0, signInUrl, {
|
|
190
|
+
returnUrl,
|
|
191
|
+
applicationId: context.initOptions.applicationId,
|
|
192
|
+
environment: context.initOptions.environment,
|
|
193
|
+
mode: signInMode,
|
|
194
|
+
requestId: currentRequestId
|
|
195
|
+
});
|
|
196
|
+
if (signInMode === "redirect") {
|
|
197
|
+
_chunkD2H2PTN2umdcjs.redirectToOverlayGrant.call(void 0, grantUrl);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const popup = _chunkD2H2PTN2umdcjs.openOverlayGrantPopup.call(void 0, grantUrl);
|
|
201
|
+
if (!popup) {
|
|
202
|
+
_chunkD2H2PTN2umdcjs.redirectToOverlayGrant.call(void 0, grantUrl);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
grantPopup = popup;
|
|
206
|
+
hint.hidden = false;
|
|
207
|
+
hint.textContent = "Complete sign-in in the popup.";
|
|
208
|
+
stopPopupWatch = _chunkD2H2PTN2umdcjs.watchPopupClosed.call(void 0, popup, () => {
|
|
209
|
+
if (currentRequestId) {
|
|
210
|
+
clearGrantAttempt();
|
|
211
|
+
if (!context.isEditModeActive()) {
|
|
212
|
+
showInlineError("Sign-in window closed before finishing.");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
let stopOverlayGrantListener = null;
|
|
218
|
+
if (signInUrl && signInMode === "popup") {
|
|
219
|
+
const adminOrigin = _chunkD2H2PTN2umdcjs.adminOriginFromSignInUrl.call(void 0, signInUrl);
|
|
220
|
+
stopOverlayGrantListener = _chunkD2H2PTN2umdcjs.listenForOverlayGrant.call(void 0,
|
|
221
|
+
adminOrigin,
|
|
222
|
+
() => currentRequestId,
|
|
223
|
+
{
|
|
224
|
+
onGranted: (token) => {
|
|
225
|
+
void (async () => {
|
|
226
|
+
clearInlineStatus();
|
|
227
|
+
_chunkD2H2PTN2umdcjs.persistEditToken.call(void 0, token);
|
|
228
|
+
try {
|
|
229
|
+
await context.enableEditMode();
|
|
230
|
+
clearGrantAttempt();
|
|
231
|
+
syncFabLabel();
|
|
232
|
+
} catch (err) {
|
|
233
|
+
_chunkD2H2PTN2umdcjs.clearEditToken.call(void 0, );
|
|
234
|
+
showInlineError(err instanceof Error ? err.message : String(err));
|
|
235
|
+
openGrantPopup();
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
},
|
|
239
|
+
onError: (message) => {
|
|
240
|
+
clearGrantAttempt();
|
|
241
|
+
showInlineError(message);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
}
|
|
180
246
|
fab.addEventListener("click", () => {
|
|
181
247
|
void (async () => {
|
|
182
|
-
clearError();
|
|
183
248
|
if (context.isEditModeActive()) {
|
|
184
249
|
context.disableEditMode();
|
|
250
|
+
clearInlineStatus();
|
|
185
251
|
syncFabLabel();
|
|
186
252
|
return;
|
|
187
253
|
}
|
|
254
|
+
clearInlineStatus();
|
|
188
255
|
const existing = storedEditToken(context.initOptions);
|
|
189
256
|
if (existing) {
|
|
190
257
|
try {
|
|
191
258
|
await context.enableEditMode();
|
|
192
259
|
syncFabLabel();
|
|
193
|
-
|
|
194
|
-
|
|
260
|
+
return;
|
|
261
|
+
} catch (e) {
|
|
262
|
+
_chunkD2H2PTN2umdcjs.clearEditToken.call(void 0, );
|
|
195
263
|
}
|
|
196
|
-
return;
|
|
197
264
|
}
|
|
198
|
-
|
|
199
|
-
})();
|
|
200
|
-
});
|
|
201
|
-
signInBtn.addEventListener("click", () => {
|
|
202
|
-
void (async () => {
|
|
203
|
-
clearError();
|
|
204
|
-
const { signInUrl, requestEditToken } = context.launcherOptions;
|
|
265
|
+
const { requestEditToken } = context.launcherOptions;
|
|
205
266
|
if (requestEditToken) {
|
|
206
|
-
signInBtn.disabled = true;
|
|
207
267
|
try {
|
|
208
268
|
const token = await requestEditToken();
|
|
209
|
-
|
|
269
|
+
_chunkD2H2PTN2umdcjs.persistEditToken.call(void 0, token);
|
|
210
270
|
await context.enableEditMode();
|
|
211
|
-
panel.hidden = true;
|
|
212
271
|
syncFabLabel();
|
|
213
272
|
} catch (err) {
|
|
214
|
-
|
|
215
|
-
} finally {
|
|
216
|
-
signInBtn.disabled = false;
|
|
273
|
+
showInlineError(err instanceof Error ? err.message : String(err));
|
|
217
274
|
}
|
|
218
275
|
return;
|
|
219
276
|
}
|
|
220
|
-
|
|
221
|
-
const params = new URLSearchParams();
|
|
222
|
-
params.set(
|
|
223
|
-
"returnUrl",
|
|
224
|
-
_nullishCoalesce(window.location.href.split("#")[0], () => ( window.location.href))
|
|
225
|
-
);
|
|
226
|
-
params.set("applicationId", context.initOptions.applicationId);
|
|
227
|
-
params.set("environment", context.initOptions.environment);
|
|
228
|
-
const separator = signInUrl.includes("?") ? "&" : "?";
|
|
229
|
-
window.location.href = `${signInUrl}${separator}${params.toString()}`;
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
showError("Edit launcher auth is not configured.");
|
|
277
|
+
openGrantPopup();
|
|
233
278
|
})();
|
|
234
279
|
});
|
|
235
|
-
wrap.append(marker, bar, panel);
|
|
236
|
-
shadow.append(style, wrap);
|
|
237
|
-
document.body.append(host);
|
|
238
280
|
syncFabLabel();
|
|
239
281
|
return {
|
|
240
282
|
destroy: () => {
|
|
283
|
+
_optionalChain([stopOverlayGrantListener, 'optionalCall', _6 => _6()]);
|
|
284
|
+
clearGrantAttempt();
|
|
241
285
|
host.remove();
|
|
242
286
|
}
|
|
243
287
|
};
|
|
@@ -247,4 +291,4 @@ function mountEditLauncher(context) {
|
|
|
247
291
|
|
|
248
292
|
|
|
249
293
|
exports.LAUNCHER_CHUNK_MARKER = LAUNCHER_CHUNK_MARKER; exports.LAUNCHER_ROOT_ID = LAUNCHER_ROOT_ID; exports.mountEditLauncher = mountEditLauncher;
|
|
250
|
-
//# sourceMappingURL=edit-launcher-
|
|
294
|
+
//# sourceMappingURL=edit-launcher-Z5AGCAQB.umd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/translations/translations/packages/sdk/dist/edit-launcher-Z5AGCAQB.umd.cjs","../src/edit-launcher/constants.ts","../src/edit-launcher/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/translations/translations/packages/sdk/dist/edit-launcher-Z5AGCAQB.umd.cjs","sourcesContent":[null,"/**\n * DOM and bundle-split markers for the lazy-loaded edit launcher chunk (M2-SDK-05).\n *\n * Intent: stable ids/markers keep overlay UI out of the default SDK entry until edit mode activates.\n */\nexport const LAUNCHER_ROOT_ID = \"translation-edit-launcher-root\";\n\n/** Marker string used in bundle-split tests to keep launcher out of the main entry. */\nexport const LAUNCHER_CHUNK_MARKER = \"translation-edit-launcher-chunk-v1\";\n","/**\n * Lazy-loaded bottom bar launcher for staging overlay (M2-SDK-05, UI-09).\n *\n * Intent: `?translation_edit=1` arms the UI only; Translate opens popup grant or enables from stored token.\n */\nimport {\n clearEditToken,\n persistEditToken,\n readEditTokenFromStorage,\n} from \"../edit-token.js\";\nimport { decodeEditTokenClaims } from \"../edit-token-decode.js\";\nimport {\n adminOriginFromSignInUrl,\n buildOverlayGrantUrl,\n listenForOverlayGrant,\n newRequestId,\n openOverlayGrantPopup,\n redirectToOverlayGrant,\n watchPopupClosed,\n type OverlayGrantMode,\n} from \"./sign-in-popup.js\";\nimport type { EditLauncherOptions, InitOptions } from \"../types.js\";\nimport { LAUNCHER_CHUNK_MARKER, LAUNCHER_ROOT_ID } from \"./constants.js\";\n\nexport { LAUNCHER_CHUNK_MARKER, LAUNCHER_ROOT_ID } from \"./constants.js\";\n\nexport type EditLauncherMountContext = {\n initOptions: InitOptions;\n launcherOptions: EditLauncherOptions;\n isEditModeActive: () => boolean;\n enableEditMode: () => Promise<void>;\n disableEditMode: () => void;\n};\n\nexport type EditLauncherHandle = {\n destroy: () => void;\n};\n\nfunction tokenMatchesInit(token: string, options: InitOptions): boolean {\n const claims = decodeEditTokenClaims(token);\n if (!claims) {\n return false;\n }\n return (\n claims.applicationId === options.applicationId &&\n claims.environmentName === options.environment\n );\n}\n\nfunction storedEditToken(options: InitOptions): string | null {\n const token = readEditTokenFromStorage();\n if (!token || !tokenMatchesInit(token, options)) {\n return null;\n }\n return token;\n}\n\n/**\n * Mounts bottom edit bar in a shadow root; Translate is the single auth gesture.\n */\nexport function mountEditLauncher(context: EditLauncherMountContext): EditLauncherHandle {\n if (typeof document === \"undefined\") {\n return { destroy: () => {} };\n }\n\n document.getElementById(LAUNCHER_ROOT_ID)?.remove();\n\n const host = document.createElement(\"div\");\n host.id = LAUNCHER_ROOT_ID;\n host.setAttribute(\"data-translation-edit-launcher\", \"true\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n const style = document.createElement(\"style\");\n style.textContent = `\n :host { all: initial; }\n .wrap { font-family: system-ui, -apple-system, Segoe UI, sans-serif; font-size: 14px; }\n .edit-bar {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2147483645;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 20px;\n background: #fff;\n border-top: 1px solid #e2e8f0;\n box-shadow: 0 -4px 24px rgba(15, 23, 42, 0.08);\n }\n .edit-bar__left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n }\n .edit-mode-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n background: #d1fae5;\n color: #047857;\n font-size: 12px;\n font-weight: 600;\n white-space: nowrap;\n }\n .edit-mode-pill::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #10b981;\n }\n .edit-bar__hint {\n color: #64748b;\n font-size: 13px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .edit-bar__hint.is-error { color: #b91c1c; }\n .fab {\n flex-shrink: 0;\n border: none;\n border-radius: 8px;\n padding: 10px 18px;\n background: #4338ca;\n color: #fff;\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 600;\n box-shadow: 0 2px 8px rgba(67, 56, 202, 0.28);\n }\n .fab:hover { background: #3730a3; }\n .fab.is-editing { background: #0f766e; box-shadow: 0 2px 8px rgba(15, 118, 110, 0.28); }\n .marker { display: none; }\n `;\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n\n const marker = document.createElement(\"span\");\n marker.className = \"marker\";\n marker.textContent = LAUNCHER_CHUNK_MARKER;\n\n const bar = document.createElement(\"div\");\n bar.className = \"edit-bar\";\n\n const left = document.createElement(\"div\");\n left.className = \"edit-bar__left\";\n\n const pill = document.createElement(\"span\");\n pill.className = \"edit-mode-pill\";\n pill.textContent = \"Edit mode active\";\n pill.hidden = true;\n\n const hint = document.createElement(\"span\");\n hint.className = \"edit-bar__hint\";\n hint.textContent = \"Translate copy on this page\";\n\n left.append(pill, hint);\n\n const fab = document.createElement(\"button\");\n fab.type = \"button\";\n fab.className = \"fab\";\n fab.textContent = \"Translate\";\n\n bar.append(left, fab);\n wrap.append(marker, bar);\n shadow.append(style, wrap);\n document.body.append(host);\n\n const signInUrl = context.launcherOptions.signInUrl;\n const signInMode: OverlayGrantMode = context.launcherOptions.signInMode ?? \"popup\";\n\n let currentRequestId: string | null = null;\n let grantPopup: Window | null = null;\n let stopPopupWatch: (() => void) | null = null;\n\n const defaultHint = \"Translate copy on this page\";\n\n const syncFabLabel = (): void => {\n if (context.isEditModeActive()) {\n fab.textContent = \"Stop editing\";\n fab.classList.add(\"is-editing\");\n pill.hidden = false;\n hint.hidden = true;\n hint.classList.remove(\"is-error\");\n } else {\n fab.textContent = \"Translate\";\n fab.classList.remove(\"is-editing\");\n pill.hidden = true;\n hint.hidden = false;\n if (!hint.classList.contains(\"is-error\")) {\n hint.textContent = defaultHint;\n }\n }\n };\n\n const clearGrantAttempt = (): void => {\n currentRequestId = null;\n stopPopupWatch?.();\n stopPopupWatch = null;\n grantPopup = null;\n };\n\n const showInlineError = (message: string): void => {\n hint.hidden = false;\n hint.textContent = message;\n hint.classList.add(\"is-error\");\n };\n\n const clearInlineStatus = (): void => {\n hint.classList.remove(\"is-error\");\n hint.textContent = defaultHint;\n };\n\n const openGrantPopup = (): void => {\n if (!signInUrl) {\n showInlineError(\"Edit launcher auth is not configured.\");\n return;\n }\n\n if (grantPopup && !grantPopup.closed) {\n grantPopup.focus();\n hint.hidden = false;\n hint.textContent = \"Complete sign-in in the popup.\";\n return;\n }\n\n const returnUrl = window.location.href.split(\"#\")[0] ?? window.location.href;\n currentRequestId = newRequestId();\n const grantUrl = buildOverlayGrantUrl(signInUrl, {\n returnUrl,\n applicationId: context.initOptions.applicationId,\n environment: context.initOptions.environment,\n mode: signInMode,\n requestId: currentRequestId,\n });\n\n if (signInMode === \"redirect\") {\n redirectToOverlayGrant(grantUrl);\n return;\n }\n\n const popup = openOverlayGrantPopup(grantUrl);\n if (!popup) {\n redirectToOverlayGrant(grantUrl);\n return;\n }\n\n grantPopup = popup;\n hint.hidden = false;\n hint.textContent = \"Complete sign-in in the popup.\";\n stopPopupWatch = watchPopupClosed(popup, () => {\n if (currentRequestId) {\n clearGrantAttempt();\n if (!context.isEditModeActive()) {\n showInlineError(\"Sign-in window closed before finishing.\");\n }\n }\n });\n };\n\n let stopOverlayGrantListener: (() => void) | null = null;\n if (signInUrl && signInMode === \"popup\") {\n const adminOrigin = adminOriginFromSignInUrl(signInUrl);\n stopOverlayGrantListener = listenForOverlayGrant(\n adminOrigin,\n () => currentRequestId,\n {\n onGranted: (token) => {\n void (async () => {\n clearInlineStatus();\n persistEditToken(token);\n try {\n await context.enableEditMode();\n clearGrantAttempt();\n syncFabLabel();\n } catch (err) {\n clearEditToken();\n showInlineError(err instanceof Error ? err.message : String(err));\n openGrantPopup();\n }\n })();\n },\n onError: (message) => {\n clearGrantAttempt();\n showInlineError(message);\n },\n },\n );\n }\n\n fab.addEventListener(\"click\", () => {\n void (async () => {\n if (context.isEditModeActive()) {\n context.disableEditMode();\n clearInlineStatus();\n syncFabLabel();\n return;\n }\n\n clearInlineStatus();\n\n const existing = storedEditToken(context.initOptions);\n if (existing) {\n try {\n await context.enableEditMode();\n syncFabLabel();\n return;\n } catch {\n clearEditToken();\n }\n }\n\n const { requestEditToken } = context.launcherOptions;\n if (requestEditToken) {\n try {\n const token = await requestEditToken();\n persistEditToken(token);\n await context.enableEditMode();\n syncFabLabel();\n } catch (err) {\n showInlineError(err instanceof Error ? err.message : String(err));\n }\n return;\n }\n\n openGrantPopup();\n })();\n });\n\n syncFabLabel();\n\n return {\n destroy: () => {\n stopOverlayGrantListener?.();\n clearGrantAttempt();\n host.remove();\n },\n };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -29,6 +29,11 @@ type EditLauncherOptions = {
|
|
|
29
29
|
armingKey?: string;
|
|
30
30
|
/** Redirect here to sign in; `returnUrl` is appended. */
|
|
31
31
|
signInUrl?: string;
|
|
32
|
+
/**
|
|
33
|
+
* `popup` opens admin overlay-grant in a new window (default); `redirect` navigates away from the app.
|
|
34
|
+
* Intent: popup keeps translators on the page they are editing.
|
|
35
|
+
*/
|
|
36
|
+
signInMode?: "popup" | "redirect";
|
|
32
37
|
/**
|
|
33
38
|
* Mint an edit JWT in-process (local demo only). Ignored when `signInUrl` is set.
|
|
34
39
|
* Intent: never ship admin/dev secrets in production customer bundles.
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,11 @@ type EditLauncherOptions = {
|
|
|
29
29
|
armingKey?: string;
|
|
30
30
|
/** Redirect here to sign in; `returnUrl` is appended. */
|
|
31
31
|
signInUrl?: string;
|
|
32
|
+
/**
|
|
33
|
+
* `popup` opens admin overlay-grant in a new window (default); `redirect` navigates away from the app.
|
|
34
|
+
* Intent: popup keeps translators on the page they are editing.
|
|
35
|
+
*/
|
|
36
|
+
signInMode?: "popup" | "redirect";
|
|
32
37
|
/**
|
|
33
38
|
* Mint an edit JWT in-process (local demo only). Ignored when `signInUrl` is set.
|
|
34
39
|
* Intent: never ship admin/dev secrets in production customer bundles.
|