bunnyquery 1.8.14 → 1.8.16
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/bunnyquery.js +251 -26
- package/dist/engine.cjs +189 -12
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.mts +73 -0
- package/dist/engine.d.ts +73 -0
- package/dist/engine.mjs +189 -12
- package/dist/engine.mjs.map +1 -1
- package/package.json +1 -1
- package/src/engine/host.ts +14 -0
- package/src/engine/scroll_anchor.ts +366 -11
- package/src/engine/session.ts +11 -1
package/bunnyquery.js
CHANGED
|
@@ -2438,6 +2438,9 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2438
2438
|
// src/engine/scroll_anchor.ts
|
|
2439
2439
|
var ROW_KEY_ATTR = "data-row-key";
|
|
2440
2440
|
var ROW_POS_ATTR = "data-row-pos";
|
|
2441
|
+
var MAX_ALTS = 2;
|
|
2442
|
+
var ALT_SCAN_LIMIT = 64;
|
|
2443
|
+
var MAX_RETURN_SETTLES = 3;
|
|
2441
2444
|
var UNKNOWN_ROW_POS = "\0?";
|
|
2442
2445
|
function createScrollAnchor(options) {
|
|
2443
2446
|
var held = null;
|
|
@@ -2448,6 +2451,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2448
2451
|
var boxTop = box.getBoundingClientRect().top;
|
|
2449
2452
|
var kids = box.children;
|
|
2450
2453
|
var fallback = null;
|
|
2454
|
+
var fallbackAt = -1;
|
|
2451
2455
|
for (var i = 0; i < kids.length; i++) {
|
|
2452
2456
|
var el = kids[i];
|
|
2453
2457
|
if (!el || typeof el.getAttribute !== "function") continue;
|
|
@@ -2466,10 +2470,20 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2466
2470
|
scrollHeight: box.scrollHeight,
|
|
2467
2471
|
el
|
|
2468
2472
|
};
|
|
2469
|
-
if (rawPos === null)
|
|
2470
|
-
|
|
2473
|
+
if (rawPos === null) {
|
|
2474
|
+
cand.alts = collectAlts(box, boxTop, i + 1);
|
|
2475
|
+
return cand;
|
|
2476
|
+
}
|
|
2477
|
+
if (!fallback) {
|
|
2478
|
+
fallback = cand;
|
|
2479
|
+
fallbackAt = i;
|
|
2480
|
+
}
|
|
2471
2481
|
}
|
|
2472
|
-
|
|
2482
|
+
if (fallback) {
|
|
2483
|
+
fallback.alts = collectAlts(box, boxTop, fallbackAt + 1, true);
|
|
2484
|
+
return fallback;
|
|
2485
|
+
}
|
|
2486
|
+
return {
|
|
2473
2487
|
key: null,
|
|
2474
2488
|
top: 0,
|
|
2475
2489
|
pos: null,
|
|
@@ -2478,6 +2492,26 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2478
2492
|
el: null
|
|
2479
2493
|
};
|
|
2480
2494
|
}
|
|
2495
|
+
function collectAlts(box, boxTop, from, ordinaryOnly) {
|
|
2496
|
+
var out = [];
|
|
2497
|
+
var kids = box.children;
|
|
2498
|
+
var stop = Math.min(kids.length, from + ALT_SCAN_LIMIT);
|
|
2499
|
+
for (var i = from; i < stop && out.length < MAX_ALTS; i++) {
|
|
2500
|
+
var el = kids[i];
|
|
2501
|
+
if (!el || typeof el.getAttribute !== "function") continue;
|
|
2502
|
+
var key = el.getAttribute(ROW_KEY_ATTR);
|
|
2503
|
+
if (!key) continue;
|
|
2504
|
+
var rawPos = el.getAttribute(ROW_POS_ATTR);
|
|
2505
|
+
if (ordinaryOnly && rawPos !== null) continue;
|
|
2506
|
+
out.push({
|
|
2507
|
+
key,
|
|
2508
|
+
top: el.getBoundingClientRect().top - boxTop,
|
|
2509
|
+
pos: rawPos === null ? null : rawPos || UNKNOWN_ROW_POS,
|
|
2510
|
+
el
|
|
2511
|
+
});
|
|
2512
|
+
}
|
|
2513
|
+
return out.length ? out : void 0;
|
|
2514
|
+
}
|
|
2481
2515
|
function findRow(box, anchor) {
|
|
2482
2516
|
var el = anchor.el;
|
|
2483
2517
|
if (el && el.parentNode === box) return el;
|
|
@@ -2490,31 +2524,80 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2490
2524
|
}
|
|
2491
2525
|
return null;
|
|
2492
2526
|
}
|
|
2493
|
-
|
|
2527
|
+
var sawFrozen = false;
|
|
2528
|
+
var parked = null;
|
|
2529
|
+
var parkedStuck = false;
|
|
2530
|
+
var returning = false;
|
|
2531
|
+
var returnBudget = 0;
|
|
2532
|
+
var wroteTop = -1;
|
|
2533
|
+
var restoreExact = true;
|
|
2534
|
+
var restorePinned = false;
|
|
2535
|
+
function frozen() {
|
|
2536
|
+
var f = !!options.isFrozen && options.isFrozen();
|
|
2537
|
+
if (f) sawFrozen = true;
|
|
2538
|
+
return f;
|
|
2539
|
+
}
|
|
2540
|
+
function restore(anchor, unbounded) {
|
|
2541
|
+
if (frozen()) return;
|
|
2494
2542
|
var box = options.getBox();
|
|
2495
2543
|
if (!box || !anchor || options.isStuck()) return;
|
|
2496
2544
|
var el = findRow(box, anchor);
|
|
2497
2545
|
if (el) {
|
|
2498
2546
|
var livePos = el.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
|
|
2499
|
-
if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos)
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
}
|
|
2547
|
+
if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos) el = null;
|
|
2548
|
+
}
|
|
2549
|
+
if (el) {
|
|
2503
2550
|
var boxTop = box.getBoundingClientRect().top;
|
|
2504
2551
|
var delta = el.getBoundingClientRect().top - boxTop - anchor.top;
|
|
2505
2552
|
var slack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
|
|
2506
|
-
if (delta > slack || delta < -slack) {
|
|
2553
|
+
if (!unbounded && (delta > slack || delta < -slack)) {
|
|
2507
2554
|
lost(box, anchor);
|
|
2508
2555
|
return;
|
|
2509
2556
|
}
|
|
2557
|
+
var want = box.scrollTop + delta;
|
|
2510
2558
|
if (delta >= 1 || delta <= -1) box.scrollTop += delta;
|
|
2559
|
+
wroteTop = box.scrollTop;
|
|
2560
|
+
restorePinned = true;
|
|
2561
|
+
restoreExact = box.scrollTop >= want - 1 && box.scrollTop <= want + 1;
|
|
2511
2562
|
held = {
|
|
2512
2563
|
key: anchor.key,
|
|
2513
2564
|
top: anchor.top,
|
|
2514
2565
|
pos: anchor.pos,
|
|
2515
2566
|
scrollTop: box.scrollTop,
|
|
2516
2567
|
scrollHeight: box.scrollHeight,
|
|
2517
|
-
el
|
|
2568
|
+
el,
|
|
2569
|
+
// Carried, not dropped: one successful restore used to disarm the
|
|
2570
|
+
// standbys for every later hold.
|
|
2571
|
+
alts: anchor.alts
|
|
2572
|
+
};
|
|
2573
|
+
return;
|
|
2574
|
+
}
|
|
2575
|
+
var alts = anchor.alts;
|
|
2576
|
+
for (var ai = 0; alts && ai < alts.length; ai++) {
|
|
2577
|
+
var alt = alts[ai];
|
|
2578
|
+
var ael = findRow(box, { key: alt.key, top: alt.top, pos: alt.pos, scrollTop: anchor.scrollTop, scrollHeight: anchor.scrollHeight, el: alt.el });
|
|
2579
|
+
if (!ael) continue;
|
|
2580
|
+
if (alt.pos !== null && alt.pos !== UNKNOWN_ROW_POS) {
|
|
2581
|
+
var altLive = ael.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
|
|
2582
|
+
if (altLive !== UNKNOWN_ROW_POS && altLive !== alt.pos) continue;
|
|
2583
|
+
}
|
|
2584
|
+
var aboxTop = box.getBoundingClientRect().top;
|
|
2585
|
+
var adelta = ael.getBoundingClientRect().top - aboxTop - alt.top;
|
|
2586
|
+
var aslack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
|
|
2587
|
+
if (!unbounded && (adelta > aslack || adelta < -aslack)) continue;
|
|
2588
|
+
var awant = box.scrollTop + adelta;
|
|
2589
|
+
if (adelta >= 1 || adelta <= -1) box.scrollTop += adelta;
|
|
2590
|
+
wroteTop = box.scrollTop;
|
|
2591
|
+
restorePinned = true;
|
|
2592
|
+
restoreExact = box.scrollTop >= awant - 1 && box.scrollTop <= awant + 1;
|
|
2593
|
+
held = {
|
|
2594
|
+
key: alt.key,
|
|
2595
|
+
top: alt.top,
|
|
2596
|
+
pos: alt.pos,
|
|
2597
|
+
scrollTop: box.scrollTop,
|
|
2598
|
+
scrollHeight: box.scrollHeight,
|
|
2599
|
+
el: ael,
|
|
2600
|
+
alts: alts.slice(ai + 1)
|
|
2518
2601
|
};
|
|
2519
2602
|
return;
|
|
2520
2603
|
}
|
|
@@ -2525,9 +2608,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2525
2608
|
var grew = box.scrollHeight - anchor.scrollHeight;
|
|
2526
2609
|
if (grew > 0) {
|
|
2527
2610
|
box.scrollTop = anchor.scrollTop + grew;
|
|
2611
|
+
wroteTop = box.scrollTop;
|
|
2528
2612
|
return;
|
|
2529
2613
|
}
|
|
2530
|
-
if (options.rawFallback)
|
|
2614
|
+
if (options.rawFallback) {
|
|
2615
|
+
box.scrollTop = anchor.scrollTop;
|
|
2616
|
+
wroteTop = box.scrollTop;
|
|
2617
|
+
}
|
|
2531
2618
|
}
|
|
2532
2619
|
function preserve(mutate) {
|
|
2533
2620
|
var anchor = capture();
|
|
@@ -2536,9 +2623,17 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2536
2623
|
return result;
|
|
2537
2624
|
}
|
|
2538
2625
|
function remember() {
|
|
2626
|
+
var b0 = options.getBox();
|
|
2627
|
+
if (returning && b0 && b0.scrollTop !== wroteTop) release();
|
|
2628
|
+
if (frozen()) return;
|
|
2539
2629
|
held = capture();
|
|
2540
2630
|
}
|
|
2541
2631
|
function hold() {
|
|
2632
|
+
if (frozen()) return;
|
|
2633
|
+
if (sawFrozen) {
|
|
2634
|
+
settleReturn();
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2542
2637
|
var box = options.getBox();
|
|
2543
2638
|
if (!box || options.isStuck()) {
|
|
2544
2639
|
held = null;
|
|
@@ -2565,12 +2660,86 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2565
2660
|
if (prev === void 0) prev = 0;
|
|
2566
2661
|
var delta = h - prev;
|
|
2567
2662
|
if (delta === 0) return;
|
|
2663
|
+
if (frozen()) {
|
|
2664
|
+
foldFrozenGrowth(box, el, delta);
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2568
2667
|
if (el.getBoundingClientRect().top >= box.getBoundingClientRect().top) return;
|
|
2569
2668
|
box.scrollTop += delta;
|
|
2669
|
+
wroteTop = box.scrollTop;
|
|
2570
2670
|
if (held) held = capture();
|
|
2571
2671
|
}
|
|
2672
|
+
function park() {
|
|
2673
|
+
parked = capture();
|
|
2674
|
+
parkedStuck = !!options.isStuck();
|
|
2675
|
+
returning = true;
|
|
2676
|
+
returnBudget = MAX_RETURN_SETTLES;
|
|
2677
|
+
}
|
|
2678
|
+
function release() {
|
|
2679
|
+
parked = null;
|
|
2680
|
+
parkedStuck = false;
|
|
2681
|
+
returning = false;
|
|
2682
|
+
returnBudget = 0;
|
|
2683
|
+
}
|
|
2684
|
+
function pinBottom() {
|
|
2685
|
+
var box = options.getBox();
|
|
2686
|
+
if (!box) return;
|
|
2687
|
+
box.scrollTop = box.scrollHeight;
|
|
2688
|
+
wroteTop = box.scrollTop;
|
|
2689
|
+
}
|
|
2690
|
+
function settleReturn() {
|
|
2691
|
+
if (frozen()) return false;
|
|
2692
|
+
var wasFrozen = sawFrozen;
|
|
2693
|
+
sawFrozen = false;
|
|
2694
|
+
if (!returning && !wasFrozen) return false;
|
|
2695
|
+
if (returning) {
|
|
2696
|
+
if (returnBudget <= 0) {
|
|
2697
|
+
release();
|
|
2698
|
+
return false;
|
|
2699
|
+
}
|
|
2700
|
+
returnBudget--;
|
|
2701
|
+
}
|
|
2702
|
+
if (parkedStuck) {
|
|
2703
|
+
pinBottom();
|
|
2704
|
+
return true;
|
|
2705
|
+
}
|
|
2706
|
+
var target = parked || held;
|
|
2707
|
+
restoreExact = true;
|
|
2708
|
+
restorePinned = false;
|
|
2709
|
+
restore(target, true);
|
|
2710
|
+
parked = !restorePinned || !restoreExact ? target : null;
|
|
2711
|
+
returning = !!parked && returnBudget > 0;
|
|
2712
|
+
if (!returning) {
|
|
2713
|
+
parked = null;
|
|
2714
|
+
parkedStuck = false;
|
|
2715
|
+
returnBudget = 0;
|
|
2716
|
+
}
|
|
2717
|
+
return false;
|
|
2718
|
+
}
|
|
2719
|
+
function isReturning() {
|
|
2720
|
+
return returning;
|
|
2721
|
+
}
|
|
2722
|
+
function thaw() {
|
|
2723
|
+
settleReturn();
|
|
2724
|
+
}
|
|
2725
|
+
function foldFrozenGrowth(box, el, delta) {
|
|
2726
|
+
var elTop = el.getBoundingClientRect().top;
|
|
2727
|
+
foldInto(box, held, elTop, delta);
|
|
2728
|
+
foldInto(box, parked, elTop, delta);
|
|
2729
|
+
}
|
|
2730
|
+
function foldInto(box, a, elTop, delta) {
|
|
2731
|
+
if (!a || a.top >= 0) return;
|
|
2732
|
+
var rowEl = findRow(box, a);
|
|
2733
|
+
if (!rowEl) return;
|
|
2734
|
+
var within = elTop - rowEl.getBoundingClientRect().top;
|
|
2735
|
+
if (within < 0 || within >= rowEl.offsetHeight) return;
|
|
2736
|
+
if (within >= -a.top) return;
|
|
2737
|
+
a.top -= delta;
|
|
2738
|
+
a.scrollHeight += delta;
|
|
2739
|
+
}
|
|
2572
2740
|
function forget() {
|
|
2573
2741
|
held = null;
|
|
2742
|
+
release();
|
|
2574
2743
|
}
|
|
2575
2744
|
return {
|
|
2576
2745
|
capture,
|
|
@@ -2578,6 +2747,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
2578
2747
|
preserve,
|
|
2579
2748
|
remember,
|
|
2580
2749
|
hold,
|
|
2750
|
+
park,
|
|
2751
|
+
settleReturn,
|
|
2752
|
+
isReturning,
|
|
2753
|
+
release,
|
|
2754
|
+
pinBottom,
|
|
2755
|
+
isFrozen: frozen,
|
|
2756
|
+
thaw,
|
|
2581
2757
|
absorb,
|
|
2582
2758
|
forget
|
|
2583
2759
|
};
|
|
@@ -5680,6 +5856,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
5680
5856
|
releaseBgFlag();
|
|
5681
5857
|
self.updateHistoryCache();
|
|
5682
5858
|
self.host.notify();
|
|
5859
|
+
if (self.host.settleScroll) self.host.settleScroll();
|
|
5683
5860
|
}, function() {
|
|
5684
5861
|
releaseBgFlag();
|
|
5685
5862
|
self.host.notify();
|
|
@@ -5761,7 +5938,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
5761
5938
|
self.drainBgTaskQueue();
|
|
5762
5939
|
}
|
|
5763
5940
|
if (!fetchMore) self.refreshLiveIndexState();
|
|
5764
|
-
if (!fetchMore) return self.host.scrollToBottomIfSticky();
|
|
5941
|
+
if (!fetchMore) return self.host.settleScroll ? self.host.settleScroll() : self.host.scrollToBottomIfSticky();
|
|
5765
5942
|
}).catch(function(err) {
|
|
5766
5943
|
console.warn("[chat-engine] getChatHistory failed", err);
|
|
5767
5944
|
}).then(function() {
|
|
@@ -6388,7 +6565,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
6388
6565
|
(function() {
|
|
6389
6566
|
var MCP_PROD = "https://mcp.broadwayinc.computer";
|
|
6390
6567
|
var MCP_DEV = "https://mcp-dev.broadwayinc.computer";
|
|
6391
|
-
var BQ_VERSION = "1.8.
|
|
6568
|
+
var BQ_VERSION = "1.8.16" ;
|
|
6392
6569
|
var ATTACHMENT_URL_EXPIRES_SECONDS = 600;
|
|
6393
6570
|
var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
6394
6571
|
var GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
@@ -8068,10 +8245,10 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
8068
8245
|
refreshMessageBubble(i);
|
|
8069
8246
|
},
|
|
8070
8247
|
scrollToBottom: function(smooth) {
|
|
8071
|
-
return scrollToBottom(
|
|
8248
|
+
return scrollToBottom();
|
|
8072
8249
|
},
|
|
8073
8250
|
scrollToBottomIfSticky: function(smooth) {
|
|
8074
|
-
return scrollToBottomIfSticky(
|
|
8251
|
+
return scrollToBottomIfSticky();
|
|
8075
8252
|
},
|
|
8076
8253
|
// A first page can render shorter than the box (a file's every indexing
|
|
8077
8254
|
// pass folds into ONE row), and a box that cannot scroll never fires the
|
|
@@ -8080,6 +8257,9 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
8080
8257
|
onHistoryLoaded: function(fetchMore, token) {
|
|
8081
8258
|
if (!fetchMore) ensureHistoryFillsViewport(token);
|
|
8082
8259
|
},
|
|
8260
|
+
settleScroll: function() {
|
|
8261
|
+
settleScrollAfterRefresh();
|
|
8262
|
+
},
|
|
8083
8263
|
cancelRequest: function(opts) {
|
|
8084
8264
|
return S.skapi.cancelClientSecretRequest(opts);
|
|
8085
8265
|
},
|
|
@@ -8271,7 +8451,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
8271
8451
|
if (job.stageId) session.settleStagedMessage(job.stageId);
|
|
8272
8452
|
CS.messages.push({ role: "assistant", content: "Something went wrong while uploading attachments. " + (err && err.message || ""), isError: true });
|
|
8273
8453
|
renderMessages();
|
|
8274
|
-
|
|
8454
|
+
scrollToBottomIfSticky();
|
|
8275
8455
|
return null;
|
|
8276
8456
|
});
|
|
8277
8457
|
}
|
|
@@ -8324,26 +8504,45 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
8324
8504
|
};
|
|
8325
8505
|
enqueueAttachmentSend({ text, batchId, stageId, pinned });
|
|
8326
8506
|
}
|
|
8327
|
-
function scrollToBottom(
|
|
8507
|
+
function scrollToBottom() {
|
|
8508
|
+
if (chatScrollAnchor.isFrozen()) {
|
|
8509
|
+
CS.stickToBottom = true;
|
|
8510
|
+
chatScrollAnchor.pinBottom();
|
|
8511
|
+
return Promise.resolve();
|
|
8512
|
+
}
|
|
8328
8513
|
return raf2().then(function() {
|
|
8329
8514
|
if (!CS.messagesBox) return;
|
|
8330
8515
|
CS.stickToBottom = true;
|
|
8331
|
-
|
|
8332
|
-
else CS.messagesBox.scrollTop = CS.messagesBox.scrollHeight;
|
|
8516
|
+
chatScrollAnchor.pinBottom();
|
|
8333
8517
|
});
|
|
8334
8518
|
}
|
|
8335
|
-
function scrollToBottomIfSticky(
|
|
8519
|
+
function scrollToBottomIfSticky() {
|
|
8336
8520
|
if (!CS.stickToBottom) return Promise.resolve();
|
|
8521
|
+
if (chatScrollAnchor.isFrozen()) {
|
|
8522
|
+
chatScrollAnchor.pinBottom();
|
|
8523
|
+
return Promise.resolve();
|
|
8524
|
+
}
|
|
8337
8525
|
return raf2().then(function() {
|
|
8338
8526
|
if (!CS.stickToBottom || !CS.messagesBox) return;
|
|
8339
|
-
|
|
8340
|
-
else CS.messagesBox.scrollTop = CS.messagesBox.scrollHeight;
|
|
8527
|
+
chatScrollAnchor.pinBottom();
|
|
8341
8528
|
});
|
|
8342
8529
|
}
|
|
8530
|
+
function settleScrollAfterRefresh(afterAbsence) {
|
|
8531
|
+
if (afterAbsence || chatScrollAnchor.isReturning()) {
|
|
8532
|
+
if (chatScrollAnchor.settleReturn()) CS.stickToBottom = true;
|
|
8533
|
+
return;
|
|
8534
|
+
}
|
|
8535
|
+
if (CS.stickToBottom) scrollToBottomIfSticky();
|
|
8536
|
+
else chatScrollAnchor.hold();
|
|
8537
|
+
}
|
|
8343
8538
|
var lastHistoryScrollTop = 0;
|
|
8344
8539
|
function onHistoryScroll() {
|
|
8345
8540
|
if (!CS.messagesBox || CS.chatSettingsOpen) return;
|
|
8346
8541
|
var el = CS.messagesBox;
|
|
8542
|
+
if (chatScrollAnchor.isFrozen()) {
|
|
8543
|
+
lastHistoryScrollTop = el.scrollTop;
|
|
8544
|
+
return;
|
|
8545
|
+
}
|
|
8347
8546
|
var atBottom = el.scrollHeight - el.scrollTop - el.clientHeight <= 16;
|
|
8348
8547
|
if (!atBottom) CS.stickToBottom = false;
|
|
8349
8548
|
else if (el.scrollTop >= lastHistoryScrollTop) CS.stickToBottom = true;
|
|
@@ -8361,12 +8560,21 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
8361
8560
|
}
|
|
8362
8561
|
var _touchStartY = 0;
|
|
8363
8562
|
function onMessagesWheel(e) {
|
|
8563
|
+
chatScrollAnchor.release();
|
|
8364
8564
|
if (e.deltaY < 0) CS.stickToBottom = false;
|
|
8365
8565
|
}
|
|
8366
8566
|
function onMessagesTouchStart(e) {
|
|
8567
|
+
chatScrollAnchor.release();
|
|
8367
8568
|
_touchStartY = e.touches && e.touches[0] ? e.touches[0].clientY : 0;
|
|
8368
8569
|
}
|
|
8570
|
+
function onMessagesKeyDown() {
|
|
8571
|
+
chatScrollAnchor.release();
|
|
8572
|
+
}
|
|
8573
|
+
function onMessagesPointerDown() {
|
|
8574
|
+
chatScrollAnchor.release();
|
|
8575
|
+
}
|
|
8369
8576
|
function onMessagesTouchMove(e) {
|
|
8577
|
+
chatScrollAnchor.release();
|
|
8370
8578
|
var y = e.touches && e.touches[0] ? e.touches[0].clientY : 0;
|
|
8371
8579
|
if (y > _touchStartY + 4) CS.stickToBottom = false;
|
|
8372
8580
|
}
|
|
@@ -9245,7 +9453,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
9245
9453
|
// earlier failure left on this file's chips.
|
|
9246
9454
|
onLoad: function(path) {
|
|
9247
9455
|
clearLinkUnavailable(linkUnavailableKeysForPath(path));
|
|
9248
|
-
scrollToBottomIfSticky(
|
|
9456
|
+
scrollToBottomIfSticky();
|
|
9249
9457
|
},
|
|
9250
9458
|
// The resizes an <img> makes with no event of its own to announce
|
|
9251
9459
|
// them: the src landing, and the src being dropped for a retry (which
|
|
@@ -10034,6 +10242,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
10034
10242
|
isStuck: function() {
|
|
10035
10243
|
return !!CS.stickToBottom;
|
|
10036
10244
|
},
|
|
10245
|
+
// A hidden tab keeps mutating this list - a resumed poll, the head refresh
|
|
10246
|
+
// and its deferred background batch, a settling request - and every one of
|
|
10247
|
+
// those would otherwise move a scroll position nobody is looking at. Freeze
|
|
10248
|
+
// instead, and put the reader back once they can see it (settleScroll).
|
|
10249
|
+
isFrozen: function() {
|
|
10250
|
+
return typeof document !== "undefined" && !!document.hidden;
|
|
10251
|
+
},
|
|
10037
10252
|
rawFallback: true
|
|
10038
10253
|
});
|
|
10039
10254
|
function captureScrollAnchor() {
|
|
@@ -10043,7 +10258,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
10043
10258
|
var box = CS.messagesBox;
|
|
10044
10259
|
if (!box) return;
|
|
10045
10260
|
if (CS.stickToBottom) {
|
|
10046
|
-
|
|
10261
|
+
chatScrollAnchor.pinBottom();
|
|
10047
10262
|
return;
|
|
10048
10263
|
}
|
|
10049
10264
|
chatScrollAnchor.restore(anchor);
|
|
@@ -10257,6 +10472,8 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
10257
10472
|
box.addEventListener("wheel", onMessagesWheel, { passive: true });
|
|
10258
10473
|
box.addEventListener("touchstart", onMessagesTouchStart, { passive: true });
|
|
10259
10474
|
box.addEventListener("touchmove", onMessagesTouchMove, { passive: true });
|
|
10475
|
+
box.addEventListener("keydown", onMessagesKeyDown, { passive: true });
|
|
10476
|
+
box.addEventListener("pointerdown", onMessagesPointerDown, { passive: true });
|
|
10260
10477
|
box.addEventListener("load", onMessagesImageSettled, true);
|
|
10261
10478
|
box.addEventListener("error", onMessagesImageSettled, true);
|
|
10262
10479
|
if (document.fonts && document.fonts.addEventListener) {
|
|
@@ -10285,7 +10502,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
10285
10502
|
if (drafting !== CS.drafting) {
|
|
10286
10503
|
CS.drafting = drafting;
|
|
10287
10504
|
syncDraftingIndicator();
|
|
10288
|
-
scrollToBottomIfSticky(
|
|
10505
|
+
scrollToBottomIfSticky();
|
|
10289
10506
|
}
|
|
10290
10507
|
});
|
|
10291
10508
|
input.addEventListener("keydown", function(e) {
|
|
@@ -10639,18 +10856,26 @@ Index the REMAINING windows - one record per row/item, looking at any page image
|
|
|
10639
10856
|
S._resizeBound = true;
|
|
10640
10857
|
window.addEventListener("resize", function() {
|
|
10641
10858
|
scheduleAttachmentOverflowRecompute();
|
|
10642
|
-
scrollToBottomIfSticky(
|
|
10859
|
+
scrollToBottomIfSticky();
|
|
10643
10860
|
ensureHistoryFillsViewport();
|
|
10644
10861
|
});
|
|
10645
10862
|
}
|
|
10646
10863
|
if (!S._visBound && typeof document !== "undefined" && document.addEventListener) {
|
|
10647
10864
|
S._visBound = true;
|
|
10865
|
+
window.addEventListener("blur", function() {
|
|
10866
|
+
chatScrollAnchor.park();
|
|
10867
|
+
});
|
|
10868
|
+
window.addEventListener("focus", function() {
|
|
10869
|
+
settleScrollAfterRefresh(true);
|
|
10870
|
+
});
|
|
10648
10871
|
document.addEventListener("visibilitychange", function() {
|
|
10649
10872
|
if (document.visibilityState === "hidden") {
|
|
10873
|
+
chatScrollAnchor.park();
|
|
10650
10874
|
if (session && session.pausePolling) session.pausePolling("hidden");
|
|
10651
10875
|
return;
|
|
10652
10876
|
}
|
|
10653
10877
|
if (document.visibilityState === "visible") {
|
|
10878
|
+
settleScrollAfterRefresh(true);
|
|
10654
10879
|
var refreshed = S.user ? ensureMcpGrantFresh() : null;
|
|
10655
10880
|
Promise.resolve(refreshed).catch(function() {
|
|
10656
10881
|
}).then(function() {
|