Fix mobile selection toolbar#3
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Shared timer drops intended delays
- Selection reporting now tracks a pending deadline and ignores shorter reschedules so fast follow-up events cannot cut off longer intended waits.
- ✅ Fixed: Selectionchange ignores overlay chrome
- Selection reporting now detects ranges inside overlay chrome (
[data-jh-chip]/.jh-pop) and emitsjh:selectionClearedinstead of posting document selection payloads.
- Selection reporting now detects ranges inside overlay chrome (
Or push these changes by commenting:
@cursor push a664bef300
Preview (a664bef300)
diff --git a/lib/docs/overlay.ts b/lib/docs/overlay.ts
--- a/lib/docs/overlay.ts
+++ b/lib/docs/overlay.ts
@@ -570,13 +570,25 @@
return { exact: exact, prefix: tm.full.slice(Math.max(0, s-32), s), suffix: tm.full.slice(e, e+32) };
}
var selectionTimer = null;
+ var selectionTimerDueAt = 0;
function fromOverlayChrome(ev){
var t = ev && ev.target;
return !!(t && t.closest && (t.closest("[data-jh-chip]") || t.closest(".jh-pop")));
}
+ function isSelectionInOverlayChrome(sel){
+ if (!sel || !sel.rangeCount) return false;
+ var r = sel.getRangeAt(0);
+ function inChrome(node){
+ if (!node) return false;
+ var el = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
+ return !!(el && el.closest && (el.closest("[data-jh-chip]") || el.closest(".jh-pop")));
+ }
+ return inChrome(r.startContainer) || inChrome(r.endContainer) || inChrome(r.commonAncestorContainer);
+ }
function reportSelection(){
try {
var sel = window.getSelection();
+ if (isSelectionInOverlayChrome(sel)){ send({type:"jh:selectionCleared"}); return; }
if (!sel || !sel.rangeCount || sel.isCollapsed || !sel.toString().trim()){ send({type:"jh:selectionCleared"}); return; }
var anchor = anchorFromSelection(sel);
var rect = sel.getRangeAt(0).getBoundingClientRect();
@@ -589,11 +601,15 @@
}
}
function queueSelectionReport(delay){
+ var dueAt = Date.now() + delay;
+ if (selectionTimer && dueAt <= selectionTimerDueAt) return;
if (selectionTimer) clearTimeout(selectionTimer);
+ selectionTimerDueAt = dueAt;
selectionTimer = setTimeout(function(){
selectionTimer = null;
+ selectionTimerDueAt = 0;
reportSelection();
- }, delay);
+ }, Math.max(0, selectionTimerDueAt - Date.now()));
}
document.addEventListener("mouseup", function(ev){
if (fromOverlayChrome(ev)) return;You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit b511f84. Configure here.
| queueSelectionReport(30); | ||
| }); | ||
| document.addEventListener("selectionchange", function(){ | ||
| queueSelectionReport(120); |
There was a problem hiding this comment.
Shared timer drops intended delays
High Severity
The queueSelectionReport function's single shared timer means events with shorter delays can prematurely cancel and override pending selection reports from events with longer delays. This can cause selection to be read too early, particularly on touch devices where events are synthesized, leading to jh:selectionCleared or a stale selection rect before the selection fully settles.
Reviewed by Cursor Bugbot for commit b511f84. Configure here.
| queueSelectionReport(30); | ||
| }); | ||
| document.addEventListener("selectionchange", function(){ | ||
| queueSelectionReport(120); |
There was a problem hiding this comment.
Selectionchange ignores overlay chrome
Medium Severity
The new selectionchange listener always schedules reportSelection, but mouseup, touchend, and pointerup skip events from [data-jh-chip] and .jh-pop via fromOverlayChrome. Text selected inside a .jh-pop can still post jh:selection and show the parent comment/reaction toolbar for overlay UI, not document content.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit b511f84. Configure here.



Summary
Tests
Note
Low Risk
UI-only changes to selection event handling and toolbar positioning in the comments overlay; no API or auth impact.
Overview
Mobile browsers often finalize text selection without a reliable desktop-style
mouseup, so the comment/reaction toolbar never appeared. The iframe overlay now reports selection through a sharedreportSelectionpath debounced byqueueSelectionReport, listening tomouseup,keyup,touchend,pointerup, andselectionchange(with event-specific delays). Clicks on overlay chips/popovers are still ignored viafromOverlayChrome, and failures clear selection withjh:selectionCleared.In
CommentsShell, the floatingSelectionToolbarno longer uses a simple minimum top offset;topis a CSSmax/minexpression so the toolbar stays within the visible doc pane (roughly 84px from the bottom).Reviewed by Cursor Bugbot for commit b511f84. Bugbot is set up for automated code reviews on this repo. Configure here.