@mochabug/adapt-web 1.0.0-rc43 → 1.0.0-rc47
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/esm/AdaptCapWidget.js +1 -1
- package/dist/esm/index.js +270 -120
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/types.d.ts +6 -0
- package/dist/umd/adapt-web.js +654 -230
- package/dist/umd/adapt-web.min.js +171 -74
- package/package.json +3 -3
|
@@ -86,7 +86,7 @@ export class AdaptCapWidget {
|
|
|
86
86
|
--mb-cap-spinner-bg: #e5e7eb;
|
|
87
87
|
|
|
88
88
|
/* Typography */
|
|
89
|
-
--mb-cap-font:
|
|
89
|
+
--mb-cap-font: inherit;
|
|
90
90
|
--mb-cap-font-size: 15px;
|
|
91
91
|
--mb-cap-font-weight: 500;
|
|
92
92
|
|
package/dist/esm/index.js
CHANGED
|
@@ -6,8 +6,8 @@ if (typeof window !== "undefined" &&
|
|
|
6
6
|
}
|
|
7
7
|
import { configure, createAdaptClient, resetConfig, } from "@mochabug/adapt-core";
|
|
8
8
|
import { createConnectClient } from "@mochabug/adapt-core/connect";
|
|
9
|
-
import { getIframeSrc } from "./iframe-url.js";
|
|
10
9
|
import { AdaptCapWidget } from "./AdaptCapWidget.js";
|
|
10
|
+
import { getIframeSrc } from "./iframe-url.js";
|
|
11
11
|
// Re-export standalone Cap widget for independent use
|
|
12
12
|
export { AdaptCapWidget, } from "./AdaptCapWidget.js";
|
|
13
13
|
// Re-export challenge functions for direct use
|
|
@@ -36,9 +36,14 @@ const DEFAULT_STYLES = `
|
|
|
36
36
|
--mb-adapt-dialog-z: 1000;
|
|
37
37
|
--mb-adapt-dialog-width: 80%;
|
|
38
38
|
--mb-adapt-dialog-height: 80%;
|
|
39
|
-
--mb-adapt-drag-handle-width:
|
|
40
|
-
--mb-adapt-drag-handle-color: #
|
|
41
|
-
--mb-adapt-drag-handle-hover: #
|
|
39
|
+
--mb-adapt-drag-handle-width: 8px;
|
|
40
|
+
--mb-adapt-drag-handle-color: #cbd5e1;
|
|
41
|
+
--mb-adapt-drag-handle-hover: #94a3b8;
|
|
42
|
+
--mb-adapt-toolbar-height: 32px;
|
|
43
|
+
--mb-adapt-toolbar-bg: rgba(249, 250, 251, 0.85);
|
|
44
|
+
--mb-adapt-toolbar-border: #e5e7eb;
|
|
45
|
+
--mb-adapt-toolbar-color: #6b7280;
|
|
46
|
+
--mb-adapt-toolbar-btn-hover: #e5e7eb;
|
|
42
47
|
--mb-adapt-banner-height: 40px;
|
|
43
48
|
--mb-adapt-banner-bg: #f9fafb;
|
|
44
49
|
--mb-adapt-banner-border: #e5e7eb;
|
|
@@ -60,6 +65,7 @@ const DEFAULT_STYLES = `
|
|
|
60
65
|
--mb-adapt-cap-checkbox-background: #f8fafc;
|
|
61
66
|
--mb-adapt-cap-spinner-color: #6366f1;
|
|
62
67
|
--mb-adapt-cap-spinner-bg: #e2e8f0;
|
|
68
|
+
--mb-adapt-cap-font: inherit;
|
|
63
69
|
--mb-adapt-cap-spinner-thickness: 3px;
|
|
64
70
|
--mb-adapt-cap-shadow: 0 4px 20px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
65
71
|
--mb-adapt-cap-shadow-hover: 0 8px 30px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.06);
|
|
@@ -70,8 +76,12 @@ const DEFAULT_STYLES = `
|
|
|
70
76
|
--mb-adapt-dialog-bg: #1f2937;
|
|
71
77
|
--mb-adapt-banner-bg: #111827;
|
|
72
78
|
--mb-adapt-banner-border: #374151;
|
|
73
|
-
--mb-adapt-drag-handle-color: #
|
|
74
|
-
--mb-adapt-drag-handle-hover: #
|
|
79
|
+
--mb-adapt-drag-handle-color: #475569;
|
|
80
|
+
--mb-adapt-drag-handle-hover: #64748b;
|
|
81
|
+
--mb-adapt-toolbar-bg: rgba(17, 24, 39, 0.85);
|
|
82
|
+
--mb-adapt-toolbar-border: #374151;
|
|
83
|
+
--mb-adapt-toolbar-color: #9ca3af;
|
|
84
|
+
--mb-adapt-toolbar-btn-hover: #374151;
|
|
75
85
|
--mb-adapt-button-color: #e5e7eb;
|
|
76
86
|
--mb-adapt-button-hover-bg: #374151;
|
|
77
87
|
|
|
@@ -121,12 +131,6 @@ const DEFAULT_STYLES = `
|
|
|
121
131
|
transition: opacity 0.1s ease-out;
|
|
122
132
|
}
|
|
123
133
|
|
|
124
|
-
/* When inside main-container (dialog mode), allow iframe to size itself */
|
|
125
|
-
.mb-adapt__main-container .mb-adapt__iframe {
|
|
126
|
-
height: auto;
|
|
127
|
-
min-height: 300px;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
134
|
.mb-adapt__iframe--visible {
|
|
131
135
|
opacity: 1;
|
|
132
136
|
}
|
|
@@ -143,11 +147,32 @@ const DEFAULT_STYLES = `
|
|
|
143
147
|
background-color: var(--mb-adapt-drag-handle-color);
|
|
144
148
|
cursor: ew-resize;
|
|
145
149
|
z-index: 10;
|
|
146
|
-
transition: background-color 0.2s, left 0.15s ease-out;
|
|
150
|
+
transition: background-color 0.2s, left 0.15s ease-out, box-shadow 0.2s;
|
|
151
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.mb-adapt__drag-handle::after {
|
|
155
|
+
content: '';
|
|
156
|
+
position: absolute;
|
|
157
|
+
top: 50%;
|
|
158
|
+
left: 50%;
|
|
159
|
+
transform: translate(-50%, -50%);
|
|
160
|
+
width: 4px;
|
|
161
|
+
height: 24px;
|
|
162
|
+
background-image: radial-gradient(circle, currentColor 1px, transparent 1px);
|
|
163
|
+
background-size: 4px 6px;
|
|
164
|
+
background-position: center;
|
|
165
|
+
opacity: 0.5;
|
|
166
|
+
color: var(--mb-adapt-drag-handle-hover);
|
|
147
167
|
}
|
|
148
168
|
|
|
149
169
|
.mb-adapt__drag-handle:hover {
|
|
150
170
|
background-color: var(--mb-adapt-drag-handle-hover);
|
|
171
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.mb-adapt__drag-handle:hover::after {
|
|
175
|
+
opacity: 0.8;
|
|
151
176
|
}
|
|
152
177
|
|
|
153
178
|
.mb-adapt__drag-overlay {
|
|
@@ -228,43 +253,42 @@ const DEFAULT_STYLES = `
|
|
|
228
253
|
position: absolute;
|
|
229
254
|
top: 50%;
|
|
230
255
|
transform: translateY(-50%);
|
|
231
|
-
background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(
|
|
232
|
-
border:
|
|
233
|
-
color: #
|
|
256
|
+
background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(241,245,249,0.98) 100%);
|
|
257
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
258
|
+
color: #475569;
|
|
234
259
|
cursor: pointer;
|
|
235
|
-
width:
|
|
236
|
-
height:
|
|
260
|
+
width: 22px;
|
|
261
|
+
height: 64px;
|
|
237
262
|
display: none;
|
|
238
263
|
align-items: center;
|
|
239
264
|
justify-content: center;
|
|
240
265
|
z-index: 100;
|
|
241
266
|
transition: all 0.2s ease-out;
|
|
242
|
-
font-size:
|
|
267
|
+
font-size: 16px;
|
|
268
|
+
font-weight: 600;
|
|
243
269
|
line-height: 1;
|
|
244
270
|
padding: 0;
|
|
245
271
|
box-shadow:
|
|
246
|
-
0 2px
|
|
247
|
-
0 1px
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
backdrop-filter: blur(
|
|
251
|
-
-webkit-backdrop-filter: blur(8px);
|
|
272
|
+
0 2px 12px rgba(0, 0, 0, 0.14),
|
|
273
|
+
0 1px 4px rgba(0, 0, 0, 0.10);
|
|
274
|
+
border-radius: 6px;
|
|
275
|
+
backdrop-filter: blur(12px);
|
|
276
|
+
-webkit-backdrop-filter: blur(12px);
|
|
252
277
|
}
|
|
253
278
|
|
|
254
279
|
.mb-adapt__expand-button:hover {
|
|
255
|
-
background: linear-gradient(180deg, rgba(255,255,255,1) 0%, rgba(
|
|
256
|
-
color: #
|
|
257
|
-
transform: translateY(-50%) scale(1.
|
|
280
|
+
background: linear-gradient(180deg, rgba(255,255,255,1) 0%, rgba(226,232,240,1) 100%);
|
|
281
|
+
color: #1e293b;
|
|
282
|
+
transform: translateY(-50%) scale(1.04);
|
|
258
283
|
box-shadow:
|
|
259
|
-
0 4px
|
|
260
|
-
0 2px
|
|
261
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
284
|
+
0 4px 16px rgba(0, 0, 0, 0.18),
|
|
285
|
+
0 2px 6px rgba(0, 0, 0, 0.12);
|
|
262
286
|
}
|
|
263
287
|
|
|
264
288
|
.mb-adapt__expand-button:active {
|
|
265
|
-
transform: translateY(-50%) scale(0.
|
|
289
|
+
transform: translateY(-50%) scale(0.97);
|
|
266
290
|
box-shadow:
|
|
267
|
-
0 1px 4px rgba(0, 0, 0, 0.
|
|
291
|
+
0 1px 4px rgba(0, 0, 0, 0.10),
|
|
268
292
|
0 1px 2px rgba(0, 0, 0, 0.06);
|
|
269
293
|
}
|
|
270
294
|
|
|
@@ -276,83 +300,79 @@ const DEFAULT_STYLES = `
|
|
|
276
300
|
left: 0;
|
|
277
301
|
border-top-left-radius: 0;
|
|
278
302
|
border-bottom-left-radius: 0;
|
|
303
|
+
border-left: none;
|
|
279
304
|
box-shadow:
|
|
280
|
-
2px 2px
|
|
281
|
-
1px 1px
|
|
282
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
305
|
+
2px 2px 12px rgba(0, 0, 0, 0.14),
|
|
306
|
+
1px 1px 4px rgba(0, 0, 0, 0.10);
|
|
283
307
|
}
|
|
284
308
|
|
|
285
309
|
.mb-adapt__expand-button--left:hover {
|
|
286
310
|
box-shadow:
|
|
287
|
-
3px 4px
|
|
288
|
-
2px 2px
|
|
289
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
311
|
+
3px 4px 16px rgba(0, 0, 0, 0.18),
|
|
312
|
+
2px 2px 6px rgba(0, 0, 0, 0.12);
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
.mb-adapt__expand-button--right {
|
|
293
316
|
right: 0;
|
|
294
317
|
border-top-right-radius: 0;
|
|
295
318
|
border-bottom-right-radius: 0;
|
|
319
|
+
border-right: none;
|
|
296
320
|
box-shadow:
|
|
297
|
-
-2px 2px
|
|
298
|
-
-1px 1px
|
|
299
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
321
|
+
-2px 2px 12px rgba(0, 0, 0, 0.14),
|
|
322
|
+
-1px 1px 4px rgba(0, 0, 0, 0.10);
|
|
300
323
|
}
|
|
301
324
|
|
|
302
325
|
.mb-adapt__expand-button--right:hover {
|
|
303
326
|
box-shadow:
|
|
304
|
-
-3px 4px
|
|
305
|
-
-2px 2px
|
|
306
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
327
|
+
-3px 4px 16px rgba(0, 0, 0, 0.18),
|
|
328
|
+
-2px 2px 6px rgba(0, 0, 0, 0.12);
|
|
307
329
|
}
|
|
308
330
|
|
|
309
331
|
.mb-adapt__expand-button--dialog {
|
|
310
332
|
left: 50%;
|
|
311
333
|
top: 0;
|
|
312
334
|
transform: translateX(-50%);
|
|
313
|
-
width:
|
|
314
|
-
height:
|
|
335
|
+
width: 64px;
|
|
336
|
+
height: 24px;
|
|
315
337
|
font-size: 16px;
|
|
316
|
-
line-height:
|
|
338
|
+
line-height: 24px;
|
|
317
339
|
vertical-align: middle;
|
|
318
340
|
text-align: center;
|
|
319
|
-
border-radius:
|
|
341
|
+
border-radius: 8px;
|
|
320
342
|
border-top-left-radius: 0;
|
|
321
343
|
border-top-right-radius: 0;
|
|
344
|
+
border-top: none;
|
|
322
345
|
box-shadow:
|
|
323
|
-
0 3px
|
|
324
|
-
0 1px
|
|
325
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
346
|
+
0 3px 12px rgba(0, 0, 0, 0.14),
|
|
347
|
+
0 1px 4px rgba(0, 0, 0, 0.10);
|
|
326
348
|
}
|
|
327
349
|
|
|
328
350
|
.mb-adapt__expand-button--dialog:hover {
|
|
329
|
-
transform: translateX(-50%) scale(1.
|
|
351
|
+
transform: translateX(-50%) scale(1.04);
|
|
330
352
|
box-shadow:
|
|
331
|
-
0 5px
|
|
332
|
-
0 2px
|
|
333
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
353
|
+
0 5px 16px rgba(0, 0, 0, 0.18),
|
|
354
|
+
0 2px 6px rgba(0, 0, 0, 0.12);
|
|
334
355
|
}
|
|
335
356
|
|
|
336
357
|
.mb-adapt__expand-button--dialog:active {
|
|
337
|
-
transform: translateX(-50%) scale(0.
|
|
358
|
+
transform: translateX(-50%) scale(0.97);
|
|
338
359
|
}
|
|
339
360
|
|
|
340
361
|
.mb-adapt--dark .mb-adapt__expand-button {
|
|
341
|
-
background: linear-gradient(180deg, rgba(
|
|
342
|
-
color:
|
|
362
|
+
background: linear-gradient(180deg, rgba(51,65,85,0.98) 0%, rgba(30,41,59,0.98) 100%);
|
|
363
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
364
|
+
color: #cbd5e1;
|
|
343
365
|
box-shadow:
|
|
344
|
-
0 2px
|
|
345
|
-
0 1px
|
|
346
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
366
|
+
0 2px 12px rgba(0, 0, 0, 0.35),
|
|
367
|
+
0 1px 4px rgba(0, 0, 0, 0.25);
|
|
347
368
|
}
|
|
348
369
|
|
|
349
370
|
.mb-adapt--dark .mb-adapt__expand-button:hover {
|
|
350
|
-
background: linear-gradient(180deg, rgba(
|
|
351
|
-
color: #
|
|
371
|
+
background: linear-gradient(180deg, rgba(71,85,105,1) 0%, rgba(51,65,85,1) 100%);
|
|
372
|
+
color: #f1f5f9;
|
|
352
373
|
box-shadow:
|
|
353
|
-
0 4px
|
|
354
|
-
0 2px
|
|
355
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
|
374
|
+
0 4px 16px rgba(0, 0, 0, 0.45),
|
|
375
|
+
0 2px 6px rgba(0, 0, 0, 0.35);
|
|
356
376
|
}
|
|
357
377
|
|
|
358
378
|
.mb-adapt__drag-handle--disabled {
|
|
@@ -360,14 +380,90 @@ const DEFAULT_STYLES = `
|
|
|
360
380
|
opacity: 0.3;
|
|
361
381
|
}
|
|
362
382
|
|
|
383
|
+
.mb-adapt__frame--has-toolbar {
|
|
384
|
+
display: flex;
|
|
385
|
+
flex-direction: column;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.mb-adapt__frame--has-toolbar.mb-adapt__frame--hidden {
|
|
389
|
+
display: none;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.mb-adapt__frame--has-toolbar .mb-adapt__iframe {
|
|
393
|
+
flex: 1;
|
|
394
|
+
height: auto;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.mb-adapt__toolbar {
|
|
398
|
+
display: flex;
|
|
399
|
+
align-items: center;
|
|
400
|
+
justify-content: flex-end;
|
|
401
|
+
height: var(--mb-adapt-toolbar-height);
|
|
402
|
+
background: var(--mb-adapt-toolbar-bg);
|
|
403
|
+
border-bottom: 1px solid var(--mb-adapt-toolbar-border);
|
|
404
|
+
padding: 0 4px;
|
|
405
|
+
flex-shrink: 0;
|
|
406
|
+
backdrop-filter: blur(12px);
|
|
407
|
+
-webkit-backdrop-filter: blur(12px);
|
|
408
|
+
gap: 2px;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.mb-adapt__toolbar-btn {
|
|
412
|
+
display: flex;
|
|
413
|
+
align-items: center;
|
|
414
|
+
justify-content: center;
|
|
415
|
+
width: 26px;
|
|
416
|
+
height: 26px;
|
|
417
|
+
border: none;
|
|
418
|
+
border-radius: 6px;
|
|
419
|
+
background: transparent;
|
|
420
|
+
color: var(--mb-adapt-toolbar-color);
|
|
421
|
+
cursor: pointer;
|
|
422
|
+
padding: 0;
|
|
423
|
+
transition: background-color 0.15s, color 0.15s;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.mb-adapt__toolbar-btn:hover {
|
|
427
|
+
background: var(--mb-adapt-toolbar-btn-hover);
|
|
428
|
+
color: var(--mb-adapt-button-color);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.mb-adapt__toolbar-btn svg {
|
|
432
|
+
width: 14px;
|
|
433
|
+
height: 14px;
|
|
434
|
+
stroke: currentColor;
|
|
435
|
+
stroke-width: 2;
|
|
436
|
+
fill: none;
|
|
437
|
+
stroke-linecap: round;
|
|
438
|
+
stroke-linejoin: round;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.mb-adapt__toolbar-btn--exit:hover {
|
|
442
|
+
background: #fecaca;
|
|
443
|
+
color: #dc2626;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.mb-adapt--dark .mb-adapt__toolbar-btn--exit:hover {
|
|
447
|
+
background: rgba(220, 38, 38, 0.2);
|
|
448
|
+
color: #fca5a5;
|
|
449
|
+
}
|
|
450
|
+
|
|
363
451
|
.mb-adapt__main-container {
|
|
364
452
|
position: relative;
|
|
453
|
+
display: flex;
|
|
454
|
+
flex-direction: column;
|
|
365
455
|
width: 100%;
|
|
366
|
-
flex:
|
|
456
|
+
flex: 1;
|
|
457
|
+
min-height: 0;
|
|
367
458
|
overflow: visible;
|
|
368
459
|
background: transparent;
|
|
369
460
|
}
|
|
370
461
|
|
|
462
|
+
.mb-adapt__main-container .mb-adapt__iframe {
|
|
463
|
+
flex: 1;
|
|
464
|
+
min-height: 0;
|
|
465
|
+
}
|
|
466
|
+
|
|
371
467
|
/* Responsive dialog - full screen on small viewports */
|
|
372
468
|
@media (max-width: 600px) {
|
|
373
469
|
.mb-adapt__dialog {
|
|
@@ -395,7 +491,7 @@ const DEFAULT_STYLES = `
|
|
|
395
491
|
--cap-checkbox-border-radius: var(--mb-adapt-cap-checkbox-radius);
|
|
396
492
|
--cap-checkbox-background: var(--mb-adapt-cap-checkbox-background);
|
|
397
493
|
--cap-checkbox-margin: 0;
|
|
398
|
-
--cap-font:
|
|
494
|
+
--cap-font: var(--mb-adapt-cap-font);
|
|
399
495
|
--cap-spinner-color: var(--mb-adapt-cap-spinner-color);
|
|
400
496
|
--cap-spinner-background-color: var(--mb-adapt-cap-spinner-bg);
|
|
401
497
|
--cap-spinner-thickness: var(--mb-adapt-cap-spinner-thickness);
|
|
@@ -453,6 +549,7 @@ export class AdaptWebClient {
|
|
|
453
549
|
this.dragHandleElement = null;
|
|
454
550
|
this.mainExpandButton = null;
|
|
455
551
|
this.forkExpandButton = null;
|
|
552
|
+
this.forkToolbarElement = null;
|
|
456
553
|
// Dialog elements
|
|
457
554
|
this.mainContainer = null;
|
|
458
555
|
this.dialogBackdrop = null;
|
|
@@ -665,6 +762,7 @@ export class AdaptWebClient {
|
|
|
665
762
|
this.dragHandleElement = null;
|
|
666
763
|
this.mainExpandButton = null;
|
|
667
764
|
this.forkExpandButton = null;
|
|
765
|
+
this.forkToolbarElement = null;
|
|
668
766
|
this.mainContainer = null;
|
|
669
767
|
this.dialogBackdrop = null;
|
|
670
768
|
this.dialogElement = null;
|
|
@@ -720,14 +818,10 @@ export class AdaptWebClient {
|
|
|
720
818
|
this.dialogBackdrop.removeEventListener("click", this.backdropClickHandler);
|
|
721
819
|
this.backdropClickHandler = null;
|
|
722
820
|
}
|
|
723
|
-
// Add new handler if enabled
|
|
821
|
+
// Add new handler if enabled (acts as minimize)
|
|
724
822
|
if (enabled) {
|
|
725
823
|
this.backdropClickHandler = () => {
|
|
726
|
-
|
|
727
|
-
this.forkQueue.unshift(this.currentFork);
|
|
728
|
-
}
|
|
729
|
-
this.currentFork = null;
|
|
730
|
-
this.updateDialogVisibility();
|
|
824
|
+
this.handleForkMinimize();
|
|
731
825
|
};
|
|
732
826
|
this.dialogBackdrop.addEventListener("click", this.backdropClickHandler);
|
|
733
827
|
}
|
|
@@ -1021,6 +1115,7 @@ export class AdaptWebClient {
|
|
|
1021
1115
|
this.dragHandleElement = null;
|
|
1022
1116
|
this.mainExpandButton = null;
|
|
1023
1117
|
this.forkExpandButton = null;
|
|
1118
|
+
this.forkToolbarElement = null;
|
|
1024
1119
|
this.mainContainer = null;
|
|
1025
1120
|
this.dialogBackdrop = null;
|
|
1026
1121
|
this.dialogElement = null;
|
|
@@ -1070,23 +1165,19 @@ export class AdaptWebClient {
|
|
|
1070
1165
|
if (!fork) {
|
|
1071
1166
|
return;
|
|
1072
1167
|
}
|
|
1073
|
-
// Remove from queue
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
// Then check if there's another fork waiting
|
|
1168
|
+
// Remove from queue (but not the current fork — it's tracked separately).
|
|
1169
|
+
// Also discard any previously-completed (stale) forks from the queue.
|
|
1170
|
+
this.forkQueue = this.forkQueue.filter((item) => item.fork !== fork && !item.completed);
|
|
1077
1171
|
if (this.currentFork?.fork === fork) {
|
|
1078
|
-
this.currentFork = null;
|
|
1079
|
-
// Check if there's another fork in queue to display
|
|
1080
1172
|
if (this.forkQueue.length > 0) {
|
|
1173
|
+
// Another fork is waiting — advance to it
|
|
1174
|
+
this.currentFork = null;
|
|
1081
1175
|
this.activateNextFork();
|
|
1082
1176
|
}
|
|
1083
1177
|
else {
|
|
1084
|
-
// No
|
|
1085
|
-
//
|
|
1086
|
-
|
|
1087
|
-
this.updateSideBySideVisibility();
|
|
1088
|
-
}
|
|
1089
|
-
// For dialog mode: keep dialog open until user clicks close or backdrop
|
|
1178
|
+
// No active forks remain — keep this fork visible (graceful completion)
|
|
1179
|
+
// but mark it so it gets evicted when a new fork arrives.
|
|
1180
|
+
this.currentFork.completed = true;
|
|
1090
1181
|
}
|
|
1091
1182
|
}
|
|
1092
1183
|
}
|
|
@@ -1148,9 +1239,10 @@ export class AdaptWebClient {
|
|
|
1148
1239
|
this.mainToken = token;
|
|
1149
1240
|
this.updateMainIframe();
|
|
1150
1241
|
}
|
|
1151
|
-
// Add to queue and activate if no current fork
|
|
1242
|
+
// Add to queue and activate if no current fork or current fork is completed.
|
|
1152
1243
|
this.forkQueue.push(forkItem);
|
|
1153
|
-
if (!this.currentFork) {
|
|
1244
|
+
if (!this.currentFork || this.currentFork.completed) {
|
|
1245
|
+
this.currentFork = null;
|
|
1154
1246
|
this.activateNextFork();
|
|
1155
1247
|
}
|
|
1156
1248
|
}
|
|
@@ -1191,11 +1283,16 @@ export class AdaptWebClient {
|
|
|
1191
1283
|
updateForkIframe() {
|
|
1192
1284
|
if (!this.currentFork || !this.forkIframe)
|
|
1193
1285
|
return;
|
|
1194
|
-
// Update iframe src if changed
|
|
1195
1286
|
const newSrc = getIframeSrc(this.currentFork.url, this.currentFork.token);
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1287
|
+
// Replace iframe to force a fresh load — browsers don't reload when only
|
|
1288
|
+
// the hash fragment changes (same plugin URL, different fork token).
|
|
1289
|
+
const parent = this.forkIframe.parentElement;
|
|
1290
|
+
if (parent) {
|
|
1291
|
+
const fresh = this.createHiddenIframe();
|
|
1292
|
+
parent.replaceChild(fresh, this.forkIframe);
|
|
1293
|
+
this.forkIframe = fresh;
|
|
1294
|
+
}
|
|
1295
|
+
this.forkIframe.src = newSrc;
|
|
1199
1296
|
// Show the iframe with fade-in
|
|
1200
1297
|
this.showIframe(this.forkIframe);
|
|
1201
1298
|
}
|
|
@@ -1228,6 +1325,10 @@ export class AdaptWebClient {
|
|
|
1228
1325
|
// Reset border radius in case coming from dialog mode
|
|
1229
1326
|
this.forkIframe.style.borderRadius = "";
|
|
1230
1327
|
this.mainFrameElement.appendChild(this.mainIframe);
|
|
1328
|
+
// Fork toolbar with minimize + exit
|
|
1329
|
+
this.forkToolbarElement = this.createForkToolbar();
|
|
1330
|
+
this.forkFrameElement.classList.add("mb-adapt__frame--has-toolbar");
|
|
1331
|
+
this.forkFrameElement.appendChild(this.forkToolbarElement);
|
|
1231
1332
|
this.forkFrameElement.appendChild(this.forkIframe);
|
|
1232
1333
|
// Drag handle - initially hidden until fork arrives
|
|
1233
1334
|
this.dragHandleElement = document.createElement("div");
|
|
@@ -1374,6 +1475,75 @@ export class AdaptWebClient {
|
|
|
1374
1475
|
this.forkFrameElement.style.width = `${forkWidth}%`;
|
|
1375
1476
|
this.dragHandleElement.style.left = `${this.splitPercentage}%`;
|
|
1376
1477
|
}
|
|
1478
|
+
createForkToolbar() {
|
|
1479
|
+
const toolbar = document.createElement("div");
|
|
1480
|
+
toolbar.className = this.options.classNames?.toolbar || "mb-adapt__toolbar";
|
|
1481
|
+
// Minimize button (horizontal line icon)
|
|
1482
|
+
const minimizeBtn = document.createElement("button");
|
|
1483
|
+
minimizeBtn.className =
|
|
1484
|
+
this.options.classNames?.toolbarButton || "mb-adapt__toolbar-btn";
|
|
1485
|
+
minimizeBtn.setAttribute("aria-label", "Minimize fork");
|
|
1486
|
+
minimizeBtn.setAttribute("title", "Minimize");
|
|
1487
|
+
minimizeBtn.innerHTML = `<svg viewBox="0 0 16 16"><line x1="3" y1="8" x2="13" y2="8"/></svg>`;
|
|
1488
|
+
minimizeBtn.addEventListener("click", () => {
|
|
1489
|
+
this.handleForkMinimize();
|
|
1490
|
+
});
|
|
1491
|
+
// Exit button (X icon) — stops the fork via the API
|
|
1492
|
+
const exitBtn = document.createElement("button");
|
|
1493
|
+
exitBtn.className = `${this.options.classNames?.toolbarButton || "mb-adapt__toolbar-btn"} mb-adapt__toolbar-btn--exit`;
|
|
1494
|
+
exitBtn.setAttribute("aria-label", "Close fork");
|
|
1495
|
+
exitBtn.setAttribute("title", "Close");
|
|
1496
|
+
exitBtn.innerHTML = `<svg viewBox="0 0 16 16"><line x1="4" y1="4" x2="12" y2="12"/><line x1="12" y1="4" x2="4" y2="12"/></svg>`;
|
|
1497
|
+
exitBtn.addEventListener("click", () => {
|
|
1498
|
+
this.handleForkExit();
|
|
1499
|
+
});
|
|
1500
|
+
toolbar.appendChild(minimizeBtn);
|
|
1501
|
+
toolbar.appendChild(exitBtn);
|
|
1502
|
+
return toolbar;
|
|
1503
|
+
}
|
|
1504
|
+
handleForkMinimize() {
|
|
1505
|
+
if (!this.currentFork)
|
|
1506
|
+
return;
|
|
1507
|
+
if (this.options.forkDisplayMode === "side-by-side") {
|
|
1508
|
+
this.splitPercentage = 100;
|
|
1509
|
+
this.updateSideBySideVisibility();
|
|
1510
|
+
}
|
|
1511
|
+
else {
|
|
1512
|
+
// Dialog mode: hide dialog, put fork back in queue so expand button shows
|
|
1513
|
+
this.forkQueue.unshift(this.currentFork);
|
|
1514
|
+
this.currentFork = null;
|
|
1515
|
+
this.updateDialogVisibility();
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
handleForkExit() {
|
|
1519
|
+
if (!this.currentFork)
|
|
1520
|
+
return;
|
|
1521
|
+
const fork = this.currentFork.fork;
|
|
1522
|
+
// Stop the fork via the API (best-effort, just like Run.tsx/ClientWindow.tsx)
|
|
1523
|
+
if (this.sessionToken) {
|
|
1524
|
+
this.client.stop(this.sessionToken, fork).catch(() => { });
|
|
1525
|
+
}
|
|
1526
|
+
// Remove from queue immediately (user-dismissable, same as ClientWindow.tsx)
|
|
1527
|
+
this.forkQueue = this.forkQueue.filter((item) => item.fork !== fork);
|
|
1528
|
+
this.currentFork = null;
|
|
1529
|
+
if (this.forkQueue.length > 0) {
|
|
1530
|
+
this.activateNextFork();
|
|
1531
|
+
}
|
|
1532
|
+
else {
|
|
1533
|
+
// Clear the fork iframe
|
|
1534
|
+
if (this.forkIframe) {
|
|
1535
|
+
this.forkIframe.src = "about:blank";
|
|
1536
|
+
this.forkIframe.classList.remove("mb-adapt__iframe--visible");
|
|
1537
|
+
this.forkIframe.classList.add("mb-adapt__iframe--hidden");
|
|
1538
|
+
}
|
|
1539
|
+
if (this.options.forkDisplayMode === "side-by-side") {
|
|
1540
|
+
this.updateSideBySideVisibility();
|
|
1541
|
+
}
|
|
1542
|
+
else {
|
|
1543
|
+
this.updateDialogVisibility();
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1377
1547
|
createDialogStructure() {
|
|
1378
1548
|
if (this.mainContainer)
|
|
1379
1549
|
return;
|
|
@@ -1401,14 +1571,10 @@ export class AdaptWebClient {
|
|
|
1401
1571
|
this.dialogBackdrop = document.createElement("div");
|
|
1402
1572
|
this.dialogBackdrop.className =
|
|
1403
1573
|
this.options.classNames?.dialogBackdrop || "mb-adapt__dialog-backdrop";
|
|
1404
|
-
// Set up backdrop click handler if enabled
|
|
1574
|
+
// Set up backdrop click handler if enabled (acts as minimize)
|
|
1405
1575
|
if (this.options.dialogBackdropClose) {
|
|
1406
1576
|
this.backdropClickHandler = () => {
|
|
1407
|
-
|
|
1408
|
-
this.forkQueue.unshift(this.currentFork);
|
|
1409
|
-
}
|
|
1410
|
-
this.currentFork = null;
|
|
1411
|
-
this.updateDialogVisibility();
|
|
1577
|
+
this.handleForkMinimize();
|
|
1412
1578
|
};
|
|
1413
1579
|
this.dialogBackdrop.addEventListener("click", this.backdropClickHandler);
|
|
1414
1580
|
}
|
|
@@ -1416,28 +1582,13 @@ export class AdaptWebClient {
|
|
|
1416
1582
|
this.dialogElement = document.createElement("div");
|
|
1417
1583
|
this.dialogElement.className =
|
|
1418
1584
|
this.options.classNames?.dialog || "mb-adapt__dialog";
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
const closeBtn = document.createElement("button");
|
|
1423
|
-
closeBtn.className =
|
|
1424
|
-
this.options.classNames?.dialogClose || "mb-adapt__dialog-close";
|
|
1425
|
-
closeBtn.innerHTML = "×";
|
|
1426
|
-
closeBtn.setAttribute("aria-label", "Close dialog");
|
|
1427
|
-
closeBtn.setAttribute("title", "Close dialog");
|
|
1428
|
-
closeBtn.addEventListener("click", () => {
|
|
1429
|
-
// Put current fork back in queue before closing
|
|
1430
|
-
if (this.currentFork) {
|
|
1431
|
-
this.forkQueue.unshift(this.currentFork);
|
|
1432
|
-
}
|
|
1433
|
-
this.currentFork = null;
|
|
1434
|
-
this.updateDialogVisibility();
|
|
1435
|
-
});
|
|
1436
|
-
banner.appendChild(closeBtn);
|
|
1437
|
-
this.dialogElement.appendChild(banner);
|
|
1585
|
+
// Same toolbar as side-by-side (minimize + exit)
|
|
1586
|
+
this.forkToolbarElement = this.createForkToolbar();
|
|
1587
|
+
this.dialogElement.appendChild(this.forkToolbarElement);
|
|
1438
1588
|
const iframeContainer = document.createElement("div");
|
|
1439
1589
|
iframeContainer.style.flex = "1";
|
|
1440
|
-
iframeContainer.style.overflow = "
|
|
1590
|
+
iframeContainer.style.overflow = "auto";
|
|
1591
|
+
iframeContainer.style.minHeight = "0";
|
|
1441
1592
|
// Reuse existing fork iframe or create new one
|
|
1442
1593
|
if (!this.forkIframe) {
|
|
1443
1594
|
this.forkIframe = this.createHiddenIframe();
|
|
@@ -1508,7 +1659,6 @@ export class AdaptWebClient {
|
|
|
1508
1659
|
}
|
|
1509
1660
|
showIframe(iframe) {
|
|
1510
1661
|
iframe.classList.remove("mb-adapt__iframe--hidden");
|
|
1511
|
-
// Trigger reflow to ensure transition works
|
|
1512
1662
|
void iframe.offsetHeight;
|
|
1513
1663
|
iframe.classList.add("mb-adapt__iframe--visible");
|
|
1514
1664
|
}
|