Precision Text Drag Discrimination & Caret Selection Refinement

Precision Text Drag Discrimination & Caret Selection Refinement

Editing typography in desktop publishing software demands fluid, predictable mouse interactions. When text is highlighted inside a text box, clicking anywhere within the selection should instantly collapse the caret to that character position. However, Chromium-based browsers natively arm drag gestures on highlighted editable content, causing minor clicks or hand micro-jitter to trigger unwanted text moves. Version 5.4.8 refined Open Publisher's Canvas Text Drag Engine with precision discrimination algorithms, an intentional distance threshold, and robust caret collapse handling.

🎯
[Screenshot: Precision Text Drag Discrimination with Visual Caret & Ghost Badge (700 x 360)]

Clicks immediately position the editing caret, while intentional drags past 10px display insertion indicators.

Eliminating Native ContentEditable Drag Hijacking

By default, Chromium attempts to initiate native HTML5 drag-and-drop operations on highlighted text within [contenteditable="true"] containers. Version 5.4.8 installs a capture-phase listener on window for dragstart:

  • Native Drag Suppression: Calls e.preventDefault() whenever dragstart targets an active text selection, preventing unwanted native browser drag ghosts and conflicts.

  • Unified Pointer Pipeline: Consolidates text interaction into a dedicated pointer pipeline (mousedown to mousemove to mouseup) using window-level capture, ensuring events are never swallowed by descendant DOM elements.

Intentional Drag Distance Threshold (10px)

To distinguish between an ordinary click and a purposeful text relocation gesture, Open Publisher enforces an intentional movement threshold:

  • Click-to-Collapse (< 10px): If the mouse is released within 10 pixels of the initial mousedown coordinate, the gesture is treated as an ordinary click. The selection collapses instantly to the character under the cursor via document.caretRangeFromPoint() with zero document mutation.

  • Intentional Drag (>= 10px): Once mouse movement exceeds 10 pixels, the drag session activates, rendering the vertical insertion caret (#op-text-drag-caret) and floating preview badge (#op-text-drag-badge).

Boundary Verification & History Protection

Dragging text back into its source location or dropping inside the original highlight is handled cleanly without corrupting document state:

  • Source Boundary Check: isTargetInsideSource() checks boundary points (START_TO_START and END_TO_START). If the drop target lies within the active selection, indicators hide and the operation cancels cleanly upon release.

  • Deferred History Snapshots: Undo checkpoints are committed only when a valid drop completes to a new destination, avoiding phantom undo states during clicks or cancelled drags.

  • Post-Drop Click Shielding: A transient flag (window._justFinishedTextDrag) shields against trailing click events after dropping, preventing whole-element selection from interrupting text focus.

  • Ctrl-Key Duplication: Holding Ctrl (or Cmd on macOS) while dragging past 10 pixels duplicates the selected text cleanly at the destination while preserving the source phrase.

Tip: You can drag highlighted phrases not only within a single text box, but across separate text boxes on the canvas.