|
16 | 16 |
|
17 | 17 | FrameTrail.defineModule('InteractionController', function(FrameTrail){ |
18 | 18 |
|
19 | | - // Prevent accidental drag-selection of text (one-time global setup). |
| 19 | + // Prevent accidental drag-selection of text within FrameTrail's own UI. |
20 | 20 | // Uses pointer events to cover both mouse and touch input. |
21 | 21 | // Double/triple-click word/line selection is still allowed via e.detail >= 2. |
| 22 | + // |
| 23 | + // Scope notes (important — this used to be a document-wide block): |
| 24 | + // - The block only applies inside this FrameTrail instance's root element, |
| 25 | + // so text on the surrounding host page (when FrameTrail is embedded) stays |
| 26 | + // selectable. |
| 27 | + // - Selectable content regions are exempted: the interactive transcript, |
| 28 | + // form fields, contenteditable areas, and anything opting in via the |
| 29 | + // .ft-selectable class. This lets users select transcript text while |
| 30 | + // overlay/timeline/slider dragging is still protected. |
22 | 31 | document.addEventListener('pointerdown', function(e) { |
23 | 32 | if (e.pointerType !== 'mouse') return; // touch/pen don't trigger selectstart |
24 | 33 | if (e.detail >= 2) return; |
25 | | - if (e.target.closest('[contenteditable]')) return; |
| 34 | + |
| 35 | + // Only guard within this instance's own UI; never touch host-page selection. |
| 36 | + var rootSelector = FrameTrail.getState('target'); |
| 37 | + if (!rootSelector || !e.target.closest(rootSelector)) return; |
| 38 | + |
| 39 | + // Leave genuinely selectable regions alone. |
| 40 | + if (e.target.closest('[contenteditable], input, textarea, .transcriptContainer, .customhtmlContainer, .ft-selectable')) return; |
| 41 | + |
26 | 42 | function onSelectStart(evt) { |
27 | 43 | evt.preventDefault(); |
28 | 44 | } |
|
0 commit comments