@mochabug/adapt-web 1.0.0-rc43 → 1.0.0-rc44
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/index.js +268 -117
- 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 +646 -223
- package/dist/umd/adapt-web.min.js +168 -72
- package/package.json +3 -3
package/dist/esm/index.js
CHANGED
|
@@ -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;
|
|
@@ -70,8 +75,12 @@ const DEFAULT_STYLES = `
|
|
|
70
75
|
--mb-adapt-dialog-bg: #1f2937;
|
|
71
76
|
--mb-adapt-banner-bg: #111827;
|
|
72
77
|
--mb-adapt-banner-border: #374151;
|
|
73
|
-
--mb-adapt-drag-handle-color: #
|
|
74
|
-
--mb-adapt-drag-handle-hover: #
|
|
78
|
+
--mb-adapt-drag-handle-color: #475569;
|
|
79
|
+
--mb-adapt-drag-handle-hover: #64748b;
|
|
80
|
+
--mb-adapt-toolbar-bg: rgba(17, 24, 39, 0.85);
|
|
81
|
+
--mb-adapt-toolbar-border: #374151;
|
|
82
|
+
--mb-adapt-toolbar-color: #9ca3af;
|
|
83
|
+
--mb-adapt-toolbar-btn-hover: #374151;
|
|
75
84
|
--mb-adapt-button-color: #e5e7eb;
|
|
76
85
|
--mb-adapt-button-hover-bg: #374151;
|
|
77
86
|
|
|
@@ -121,12 +130,6 @@ const DEFAULT_STYLES = `
|
|
|
121
130
|
transition: opacity 0.1s ease-out;
|
|
122
131
|
}
|
|
123
132
|
|
|
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
133
|
.mb-adapt__iframe--visible {
|
|
131
134
|
opacity: 1;
|
|
132
135
|
}
|
|
@@ -143,11 +146,32 @@ const DEFAULT_STYLES = `
|
|
|
143
146
|
background-color: var(--mb-adapt-drag-handle-color);
|
|
144
147
|
cursor: ew-resize;
|
|
145
148
|
z-index: 10;
|
|
146
|
-
transition: background-color 0.2s, left 0.15s ease-out;
|
|
149
|
+
transition: background-color 0.2s, left 0.15s ease-out, box-shadow 0.2s;
|
|
150
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.mb-adapt__drag-handle::after {
|
|
154
|
+
content: '';
|
|
155
|
+
position: absolute;
|
|
156
|
+
top: 50%;
|
|
157
|
+
left: 50%;
|
|
158
|
+
transform: translate(-50%, -50%);
|
|
159
|
+
width: 4px;
|
|
160
|
+
height: 24px;
|
|
161
|
+
background-image: radial-gradient(circle, currentColor 1px, transparent 1px);
|
|
162
|
+
background-size: 4px 6px;
|
|
163
|
+
background-position: center;
|
|
164
|
+
opacity: 0.5;
|
|
165
|
+
color: var(--mb-adapt-drag-handle-hover);
|
|
147
166
|
}
|
|
148
167
|
|
|
149
168
|
.mb-adapt__drag-handle:hover {
|
|
150
169
|
background-color: var(--mb-adapt-drag-handle-hover);
|
|
170
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.mb-adapt__drag-handle:hover::after {
|
|
174
|
+
opacity: 0.8;
|
|
151
175
|
}
|
|
152
176
|
|
|
153
177
|
.mb-adapt__drag-overlay {
|
|
@@ -228,43 +252,42 @@ const DEFAULT_STYLES = `
|
|
|
228
252
|
position: absolute;
|
|
229
253
|
top: 50%;
|
|
230
254
|
transform: translateY(-50%);
|
|
231
|
-
background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(
|
|
232
|
-
border:
|
|
233
|
-
color: #
|
|
255
|
+
background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(241,245,249,0.98) 100%);
|
|
256
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
257
|
+
color: #475569;
|
|
234
258
|
cursor: pointer;
|
|
235
|
-
width:
|
|
236
|
-
height:
|
|
259
|
+
width: 22px;
|
|
260
|
+
height: 64px;
|
|
237
261
|
display: none;
|
|
238
262
|
align-items: center;
|
|
239
263
|
justify-content: center;
|
|
240
264
|
z-index: 100;
|
|
241
265
|
transition: all 0.2s ease-out;
|
|
242
|
-
font-size:
|
|
266
|
+
font-size: 16px;
|
|
267
|
+
font-weight: 600;
|
|
243
268
|
line-height: 1;
|
|
244
269
|
padding: 0;
|
|
245
270
|
box-shadow:
|
|
246
|
-
0 2px
|
|
247
|
-
0 1px
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
backdrop-filter: blur(
|
|
251
|
-
-webkit-backdrop-filter: blur(8px);
|
|
271
|
+
0 2px 12px rgba(0, 0, 0, 0.14),
|
|
272
|
+
0 1px 4px rgba(0, 0, 0, 0.10);
|
|
273
|
+
border-radius: 6px;
|
|
274
|
+
backdrop-filter: blur(12px);
|
|
275
|
+
-webkit-backdrop-filter: blur(12px);
|
|
252
276
|
}
|
|
253
277
|
|
|
254
278
|
.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.
|
|
279
|
+
background: linear-gradient(180deg, rgba(255,255,255,1) 0%, rgba(226,232,240,1) 100%);
|
|
280
|
+
color: #1e293b;
|
|
281
|
+
transform: translateY(-50%) scale(1.04);
|
|
258
282
|
box-shadow:
|
|
259
|
-
0 4px
|
|
260
|
-
0 2px
|
|
261
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
283
|
+
0 4px 16px rgba(0, 0, 0, 0.18),
|
|
284
|
+
0 2px 6px rgba(0, 0, 0, 0.12);
|
|
262
285
|
}
|
|
263
286
|
|
|
264
287
|
.mb-adapt__expand-button:active {
|
|
265
|
-
transform: translateY(-50%) scale(0.
|
|
288
|
+
transform: translateY(-50%) scale(0.97);
|
|
266
289
|
box-shadow:
|
|
267
|
-
0 1px 4px rgba(0, 0, 0, 0.
|
|
290
|
+
0 1px 4px rgba(0, 0, 0, 0.10),
|
|
268
291
|
0 1px 2px rgba(0, 0, 0, 0.06);
|
|
269
292
|
}
|
|
270
293
|
|
|
@@ -276,83 +299,79 @@ const DEFAULT_STYLES = `
|
|
|
276
299
|
left: 0;
|
|
277
300
|
border-top-left-radius: 0;
|
|
278
301
|
border-bottom-left-radius: 0;
|
|
302
|
+
border-left: none;
|
|
279
303
|
box-shadow:
|
|
280
|
-
2px 2px
|
|
281
|
-
1px 1px
|
|
282
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
304
|
+
2px 2px 12px rgba(0, 0, 0, 0.14),
|
|
305
|
+
1px 1px 4px rgba(0, 0, 0, 0.10);
|
|
283
306
|
}
|
|
284
307
|
|
|
285
308
|
.mb-adapt__expand-button--left:hover {
|
|
286
309
|
box-shadow:
|
|
287
|
-
3px 4px
|
|
288
|
-
2px 2px
|
|
289
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
310
|
+
3px 4px 16px rgba(0, 0, 0, 0.18),
|
|
311
|
+
2px 2px 6px rgba(0, 0, 0, 0.12);
|
|
290
312
|
}
|
|
291
313
|
|
|
292
314
|
.mb-adapt__expand-button--right {
|
|
293
315
|
right: 0;
|
|
294
316
|
border-top-right-radius: 0;
|
|
295
317
|
border-bottom-right-radius: 0;
|
|
318
|
+
border-right: none;
|
|
296
319
|
box-shadow:
|
|
297
|
-
-2px 2px
|
|
298
|
-
-1px 1px
|
|
299
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
320
|
+
-2px 2px 12px rgba(0, 0, 0, 0.14),
|
|
321
|
+
-1px 1px 4px rgba(0, 0, 0, 0.10);
|
|
300
322
|
}
|
|
301
323
|
|
|
302
324
|
.mb-adapt__expand-button--right:hover {
|
|
303
325
|
box-shadow:
|
|
304
|
-
-3px 4px
|
|
305
|
-
-2px 2px
|
|
306
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
326
|
+
-3px 4px 16px rgba(0, 0, 0, 0.18),
|
|
327
|
+
-2px 2px 6px rgba(0, 0, 0, 0.12);
|
|
307
328
|
}
|
|
308
329
|
|
|
309
330
|
.mb-adapt__expand-button--dialog {
|
|
310
331
|
left: 50%;
|
|
311
332
|
top: 0;
|
|
312
333
|
transform: translateX(-50%);
|
|
313
|
-
width:
|
|
314
|
-
height:
|
|
334
|
+
width: 64px;
|
|
335
|
+
height: 24px;
|
|
315
336
|
font-size: 16px;
|
|
316
|
-
line-height:
|
|
337
|
+
line-height: 24px;
|
|
317
338
|
vertical-align: middle;
|
|
318
339
|
text-align: center;
|
|
319
|
-
border-radius:
|
|
340
|
+
border-radius: 8px;
|
|
320
341
|
border-top-left-radius: 0;
|
|
321
342
|
border-top-right-radius: 0;
|
|
343
|
+
border-top: none;
|
|
322
344
|
box-shadow:
|
|
323
|
-
0 3px
|
|
324
|
-
0 1px
|
|
325
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
345
|
+
0 3px 12px rgba(0, 0, 0, 0.14),
|
|
346
|
+
0 1px 4px rgba(0, 0, 0, 0.10);
|
|
326
347
|
}
|
|
327
348
|
|
|
328
349
|
.mb-adapt__expand-button--dialog:hover {
|
|
329
|
-
transform: translateX(-50%) scale(1.
|
|
350
|
+
transform: translateX(-50%) scale(1.04);
|
|
330
351
|
box-shadow:
|
|
331
|
-
0 5px
|
|
332
|
-
0 2px
|
|
333
|
-
inset 0 1px 0 rgba(255, 255, 255, 1);
|
|
352
|
+
0 5px 16px rgba(0, 0, 0, 0.18),
|
|
353
|
+
0 2px 6px rgba(0, 0, 0, 0.12);
|
|
334
354
|
}
|
|
335
355
|
|
|
336
356
|
.mb-adapt__expand-button--dialog:active {
|
|
337
|
-
transform: translateX(-50%) scale(0.
|
|
357
|
+
transform: translateX(-50%) scale(0.97);
|
|
338
358
|
}
|
|
339
359
|
|
|
340
360
|
.mb-adapt--dark .mb-adapt__expand-button {
|
|
341
|
-
background: linear-gradient(180deg, rgba(
|
|
342
|
-
color:
|
|
361
|
+
background: linear-gradient(180deg, rgba(51,65,85,0.98) 0%, rgba(30,41,59,0.98) 100%);
|
|
362
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
363
|
+
color: #cbd5e1;
|
|
343
364
|
box-shadow:
|
|
344
|
-
0 2px
|
|
345
|
-
0 1px
|
|
346
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
365
|
+
0 2px 12px rgba(0, 0, 0, 0.35),
|
|
366
|
+
0 1px 4px rgba(0, 0, 0, 0.25);
|
|
347
367
|
}
|
|
348
368
|
|
|
349
369
|
.mb-adapt--dark .mb-adapt__expand-button:hover {
|
|
350
|
-
background: linear-gradient(180deg, rgba(
|
|
351
|
-
color: #
|
|
370
|
+
background: linear-gradient(180deg, rgba(71,85,105,1) 0%, rgba(51,65,85,1) 100%);
|
|
371
|
+
color: #f1f5f9;
|
|
352
372
|
box-shadow:
|
|
353
|
-
0 4px
|
|
354
|
-
0 2px
|
|
355
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
|
373
|
+
0 4px 16px rgba(0, 0, 0, 0.45),
|
|
374
|
+
0 2px 6px rgba(0, 0, 0, 0.35);
|
|
356
375
|
}
|
|
357
376
|
|
|
358
377
|
.mb-adapt__drag-handle--disabled {
|
|
@@ -360,14 +379,90 @@ const DEFAULT_STYLES = `
|
|
|
360
379
|
opacity: 0.3;
|
|
361
380
|
}
|
|
362
381
|
|
|
382
|
+
.mb-adapt__frame--has-toolbar {
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-direction: column;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.mb-adapt__frame--has-toolbar.mb-adapt__frame--hidden {
|
|
388
|
+
display: none;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.mb-adapt__frame--has-toolbar .mb-adapt__iframe {
|
|
392
|
+
flex: 1;
|
|
393
|
+
height: auto;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.mb-adapt__toolbar {
|
|
397
|
+
display: flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
justify-content: flex-end;
|
|
400
|
+
height: var(--mb-adapt-toolbar-height);
|
|
401
|
+
background: var(--mb-adapt-toolbar-bg);
|
|
402
|
+
border-bottom: 1px solid var(--mb-adapt-toolbar-border);
|
|
403
|
+
padding: 0 4px;
|
|
404
|
+
flex-shrink: 0;
|
|
405
|
+
backdrop-filter: blur(12px);
|
|
406
|
+
-webkit-backdrop-filter: blur(12px);
|
|
407
|
+
gap: 2px;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.mb-adapt__toolbar-btn {
|
|
411
|
+
display: flex;
|
|
412
|
+
align-items: center;
|
|
413
|
+
justify-content: center;
|
|
414
|
+
width: 26px;
|
|
415
|
+
height: 26px;
|
|
416
|
+
border: none;
|
|
417
|
+
border-radius: 6px;
|
|
418
|
+
background: transparent;
|
|
419
|
+
color: var(--mb-adapt-toolbar-color);
|
|
420
|
+
cursor: pointer;
|
|
421
|
+
padding: 0;
|
|
422
|
+
transition: background-color 0.15s, color 0.15s;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.mb-adapt__toolbar-btn:hover {
|
|
426
|
+
background: var(--mb-adapt-toolbar-btn-hover);
|
|
427
|
+
color: var(--mb-adapt-button-color);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.mb-adapt__toolbar-btn svg {
|
|
431
|
+
width: 14px;
|
|
432
|
+
height: 14px;
|
|
433
|
+
stroke: currentColor;
|
|
434
|
+
stroke-width: 2;
|
|
435
|
+
fill: none;
|
|
436
|
+
stroke-linecap: round;
|
|
437
|
+
stroke-linejoin: round;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.mb-adapt__toolbar-btn--exit:hover {
|
|
441
|
+
background: #fecaca;
|
|
442
|
+
color: #dc2626;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.mb-adapt--dark .mb-adapt__toolbar-btn--exit:hover {
|
|
446
|
+
background: rgba(220, 38, 38, 0.2);
|
|
447
|
+
color: #fca5a5;
|
|
448
|
+
}
|
|
449
|
+
|
|
363
450
|
.mb-adapt__main-container {
|
|
364
451
|
position: relative;
|
|
452
|
+
display: flex;
|
|
453
|
+
flex-direction: column;
|
|
365
454
|
width: 100%;
|
|
366
|
-
flex:
|
|
455
|
+
flex: 1;
|
|
456
|
+
min-height: 0;
|
|
367
457
|
overflow: visible;
|
|
368
458
|
background: transparent;
|
|
369
459
|
}
|
|
370
460
|
|
|
461
|
+
.mb-adapt__main-container .mb-adapt__iframe {
|
|
462
|
+
flex: 1;
|
|
463
|
+
min-height: 0;
|
|
464
|
+
}
|
|
465
|
+
|
|
371
466
|
/* Responsive dialog - full screen on small viewports */
|
|
372
467
|
@media (max-width: 600px) {
|
|
373
468
|
.mb-adapt__dialog {
|
|
@@ -453,6 +548,7 @@ export class AdaptWebClient {
|
|
|
453
548
|
this.dragHandleElement = null;
|
|
454
549
|
this.mainExpandButton = null;
|
|
455
550
|
this.forkExpandButton = null;
|
|
551
|
+
this.forkToolbarElement = null;
|
|
456
552
|
// Dialog elements
|
|
457
553
|
this.mainContainer = null;
|
|
458
554
|
this.dialogBackdrop = null;
|
|
@@ -665,6 +761,7 @@ export class AdaptWebClient {
|
|
|
665
761
|
this.dragHandleElement = null;
|
|
666
762
|
this.mainExpandButton = null;
|
|
667
763
|
this.forkExpandButton = null;
|
|
764
|
+
this.forkToolbarElement = null;
|
|
668
765
|
this.mainContainer = null;
|
|
669
766
|
this.dialogBackdrop = null;
|
|
670
767
|
this.dialogElement = null;
|
|
@@ -720,14 +817,10 @@ export class AdaptWebClient {
|
|
|
720
817
|
this.dialogBackdrop.removeEventListener("click", this.backdropClickHandler);
|
|
721
818
|
this.backdropClickHandler = null;
|
|
722
819
|
}
|
|
723
|
-
// Add new handler if enabled
|
|
820
|
+
// Add new handler if enabled (acts as minimize)
|
|
724
821
|
if (enabled) {
|
|
725
822
|
this.backdropClickHandler = () => {
|
|
726
|
-
|
|
727
|
-
this.forkQueue.unshift(this.currentFork);
|
|
728
|
-
}
|
|
729
|
-
this.currentFork = null;
|
|
730
|
-
this.updateDialogVisibility();
|
|
823
|
+
this.handleForkMinimize();
|
|
731
824
|
};
|
|
732
825
|
this.dialogBackdrop.addEventListener("click", this.backdropClickHandler);
|
|
733
826
|
}
|
|
@@ -1021,6 +1114,7 @@ export class AdaptWebClient {
|
|
|
1021
1114
|
this.dragHandleElement = null;
|
|
1022
1115
|
this.mainExpandButton = null;
|
|
1023
1116
|
this.forkExpandButton = null;
|
|
1117
|
+
this.forkToolbarElement = null;
|
|
1024
1118
|
this.mainContainer = null;
|
|
1025
1119
|
this.dialogBackdrop = null;
|
|
1026
1120
|
this.dialogElement = null;
|
|
@@ -1070,23 +1164,19 @@ export class AdaptWebClient {
|
|
|
1070
1164
|
if (!fork) {
|
|
1071
1165
|
return;
|
|
1072
1166
|
}
|
|
1073
|
-
// Remove from queue
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
// Then check if there's another fork waiting
|
|
1167
|
+
// Remove from queue (but not the current fork — it's tracked separately).
|
|
1168
|
+
// Also discard any previously-completed (stale) forks from the queue.
|
|
1169
|
+
this.forkQueue = this.forkQueue.filter((item) => item.fork !== fork && !item.completed);
|
|
1077
1170
|
if (this.currentFork?.fork === fork) {
|
|
1078
|
-
this.currentFork = null;
|
|
1079
|
-
// Check if there's another fork in queue to display
|
|
1080
1171
|
if (this.forkQueue.length > 0) {
|
|
1172
|
+
// Another fork is waiting — advance to it
|
|
1173
|
+
this.currentFork = null;
|
|
1081
1174
|
this.activateNextFork();
|
|
1082
1175
|
}
|
|
1083
1176
|
else {
|
|
1084
|
-
// No
|
|
1085
|
-
//
|
|
1086
|
-
|
|
1087
|
-
this.updateSideBySideVisibility();
|
|
1088
|
-
}
|
|
1089
|
-
// For dialog mode: keep dialog open until user clicks close or backdrop
|
|
1177
|
+
// No active forks remain — keep this fork visible (graceful completion)
|
|
1178
|
+
// but mark it so it gets evicted when a new fork arrives.
|
|
1179
|
+
this.currentFork.completed = true;
|
|
1090
1180
|
}
|
|
1091
1181
|
}
|
|
1092
1182
|
}
|
|
@@ -1148,9 +1238,10 @@ export class AdaptWebClient {
|
|
|
1148
1238
|
this.mainToken = token;
|
|
1149
1239
|
this.updateMainIframe();
|
|
1150
1240
|
}
|
|
1151
|
-
// Add to queue and activate if no current fork
|
|
1241
|
+
// Add to queue and activate if no current fork or current fork is completed.
|
|
1152
1242
|
this.forkQueue.push(forkItem);
|
|
1153
|
-
if (!this.currentFork) {
|
|
1243
|
+
if (!this.currentFork || this.currentFork.completed) {
|
|
1244
|
+
this.currentFork = null;
|
|
1154
1245
|
this.activateNextFork();
|
|
1155
1246
|
}
|
|
1156
1247
|
}
|
|
@@ -1191,11 +1282,16 @@ export class AdaptWebClient {
|
|
|
1191
1282
|
updateForkIframe() {
|
|
1192
1283
|
if (!this.currentFork || !this.forkIframe)
|
|
1193
1284
|
return;
|
|
1194
|
-
// Update iframe src if changed
|
|
1195
1285
|
const newSrc = getIframeSrc(this.currentFork.url, this.currentFork.token);
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1286
|
+
// Replace iframe to force a fresh load — browsers don't reload when only
|
|
1287
|
+
// the hash fragment changes (same plugin URL, different fork token).
|
|
1288
|
+
const parent = this.forkIframe.parentElement;
|
|
1289
|
+
if (parent) {
|
|
1290
|
+
const fresh = this.createHiddenIframe();
|
|
1291
|
+
parent.replaceChild(fresh, this.forkIframe);
|
|
1292
|
+
this.forkIframe = fresh;
|
|
1293
|
+
}
|
|
1294
|
+
this.forkIframe.src = newSrc;
|
|
1199
1295
|
// Show the iframe with fade-in
|
|
1200
1296
|
this.showIframe(this.forkIframe);
|
|
1201
1297
|
}
|
|
@@ -1228,6 +1324,10 @@ export class AdaptWebClient {
|
|
|
1228
1324
|
// Reset border radius in case coming from dialog mode
|
|
1229
1325
|
this.forkIframe.style.borderRadius = "";
|
|
1230
1326
|
this.mainFrameElement.appendChild(this.mainIframe);
|
|
1327
|
+
// Fork toolbar with minimize + exit
|
|
1328
|
+
this.forkToolbarElement = this.createForkToolbar();
|
|
1329
|
+
this.forkFrameElement.classList.add("mb-adapt__frame--has-toolbar");
|
|
1330
|
+
this.forkFrameElement.appendChild(this.forkToolbarElement);
|
|
1231
1331
|
this.forkFrameElement.appendChild(this.forkIframe);
|
|
1232
1332
|
// Drag handle - initially hidden until fork arrives
|
|
1233
1333
|
this.dragHandleElement = document.createElement("div");
|
|
@@ -1374,6 +1474,76 @@ export class AdaptWebClient {
|
|
|
1374
1474
|
this.forkFrameElement.style.width = `${forkWidth}%`;
|
|
1375
1475
|
this.dragHandleElement.style.left = `${this.splitPercentage}%`;
|
|
1376
1476
|
}
|
|
1477
|
+
createForkToolbar() {
|
|
1478
|
+
const toolbar = document.createElement("div");
|
|
1479
|
+
toolbar.className =
|
|
1480
|
+
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();
|