1import { 2 closestAtomeElement, 3 getAtomeIdFromElement, 4 getAtomeKindFromElement, 5 getAtomeRuntimeState 6} from '../atome_dom_id.js'; 7import { collectDragItems } from './drag_session_support.js'; 8 9const armDragSession = (ev, { 10 atomeId, 11 attachPointerTracking, 12 claimActiveDragSession, 13 clearDeferredSelectionReplace, 14 clearPendingTextEditOnRelease, 15 dragItemDeps, 16 dragOwnerToken, 17 getCurrentSelectionIds, 18 host, 19 isAtomeSelected, 20 isMysticContextSurfaceHoldCandidateActive, 21 isMysticPointerLocked, 22 isInteractiveTargetWithinHost, 23 isPrimaryPointerActivation, 24 isTextToolActive, 25 isToolHost, 26 logAtomeEvents, 27 logDragEvents, 28 markAtomeAsEditing, 29 normalizePointerId, 30 releaseActiveDragSession, 31 resolveResizeDirection, 32 resolveSnapTargets, 33 state, 34 generateGestureId, 35 generateTxId 36} = {}) => { 37 if (isToolHost(host)) return false; 38 if (!isPrimaryPointerActivation(ev)) return false; 39 if (isMysticPointerLocked(ev.pointerId)) return false; 40 if (isMysticContextSurfaceHoldCandidateActive(ev.pointerId)) return false; 41 clearDeferredSelectionReplace(); 42 const target = ev.target && ev.target.nodeType === 3 ? ev.target.parentElement : ev.target; 43 const closestAtomeHost = (target && typeof target.closest === 'function') 44 ? closestAtomeElement(target) 45 : null; 46 if (closestAtomeHost && closestAtomeHost !== host) return false; 47 if (isInteractiveTargetWithinHost(host, target)) return false; 48 const primaryId = getAtomeIdFromElement(host); 49 const selectedIdsSnapshot = Array.isArray(getCurrentSelectionIds()) 50 ? getCurrentSelectionIds().map((id) => String(id || '').trim()).filter(Boolean) 51 : []; 52 const multiSelectionActive = selectedIdsSnapshot.length > 1; 53 if (!multiSelectionActive && resolveResizeDirection(host, ev)) return false; 54 const primaryWasSelected = primaryId 55 ? (selectedIdsSnapshot.includes(String(primaryId)) || isAtomeSelected(primaryId, host)) 56 : false; 57 const textTarget = target?.closest?.('.eve-atome-text') || host.querySelector('.eve-atome-text') || null; 58 let shouldArmTextEditTap = false; 59 clearPendingTextEditOnRelease(); 60 if (textTarget) { 61 if (host.dataset?.eveTextEditing === 'true') return false; 62 if (!multiSelectionActive && isTextToolActive()) { 63 const enableHostTextEdit = (typeof host.__eveEnableTextEdit === 'function') 64 ? host.__eveEnableTextEdit 65 : null; 66 if (enableHostTextEdit) { 67 try { 68 enableHostTextEdit({ 69 force: true, 70 preserveSelection: true 71 }); 72 } catch (_) { } 73 } else { 74 markAtomeAsEditing(atomeId); 75 host.dataset.eveTextEditing = 'true'; 76 textTarget.contentEditable = 'true'; 77 textTarget.style.pointerEvents = 'auto'; 78 } 79 return false; 80 } 81 shouldArmTextEditTap = primaryWasSelected === true && !multiSelectionActive; 82 } 83 if (!claimActiveDragSession(primaryId, dragOwnerToken, ev.pointerId)) { 84 logDragEvents('gesture_armed_suppressed_duplicate_session', { 85 atomeId: String(primaryId || ''), 86 pointerId: ev.pointerId ?? null 87 }); 88 return false; 89 } 90 state.claimedDragAtomeIds = [String(primaryId || '').trim()].filter(Boolean); 91 logAtomeEvents('atome pointerdown', { 92 atomeId: primaryId || null, 93 role: String(getAtomeRuntimeState(host)?.role || ''), 94 kind: String(getAtomeKindFromElement(host) || ''), 95 pointerType: String(ev.pointerType || ''), 96 x: Number(ev.clientX), 97 y: Number(ev.clientY) 98 }); 99 if (primaryId && !primaryWasSelected) { 100 state.deferredSelectionReplace = { 101 atomeId: primaryId, 102 pointerId: normalizePointerId(ev.pointerId), 103 armedAt: Date.now() 104 }; 105 } 106 state.startX = ev.clientX; 107 state.startY = ev.clientY; 108 if (shouldArmTextEditTap && textTarget) { 109 state.pendingTextEditOnRelease = { 110 atomeId: String(primaryId || atomeId || '').trim(), 111 pointerId: normalizePointerId(ev.pointerId), 112 clientX: ev.clientX, 113 clientY: ev.clientY, 114 armedAt: Date.now() 115 }; 116 } 117 state.dragItems = collectDragItems(primaryId, dragItemDeps); 118 if (state.deferredSelectionReplace?.atomeId && primaryId) { 119 state.dragItems = state.dragItems.filter((item) =>
119 String(item?.id || '') === String(primaryId)); 120 } 121 if (state.dragItems.length > 1) { 122 const already = new Set(state.claimedDragAtomeIds); 123 for (const item of state.dragItems) { 124 const id = String(item?.id || '').trim(); 125 if (!id || already.has(id)) continue; 126 if (!claimActiveDragSession(id, dragOwnerToken, ev.pointerId)) { 127 logDragEvents('gesture_armed_suppressed_duplicate_session', { 128 atomeId: id, 129 pointerId: ev.pointerId ?? null, 130 reason: 'secondary_selected_item_already_claimed' 131 }); 132 state.claimedDragAtomeIds.forEach((claimedId) => releaseActiveDragSession(claimedId, dragOwnerToken)); 133 state.claimedDragAtomeIds = []; 134 state.dragItems = []; 135 clearDeferredSelectionReplace(); 136 return false; 137 } 138 state.claimedDragAtomeIds.push(id); 139 already.add(id); 140 } 141 } 142 state.snapTargets = resolveSnapTargets(primaryId, host); 143 state.activeSnap = null; 144 state.gestureId = generateGestureId(); 145 state.gestureTxId = generateTxId(); 146 state.activePointerId = ev.pointerId != null ? ev.pointerId : null; 147 logDragEvents('gesture_armed', { 148 atomeId: String(primaryId || ''), 149 gestureId: String(state.gestureId || ''), 150 pointerId: state.activePointerId, 151 pointerType: String(ev.pointerType || ''), 152 selectedIds: state.dragItems.map((item) => String(item.id || '')), 153 snapTargetCount: state.snapTargets.length 154 }); 155 attachPointerTracking(); 156 try { ev.preventDefault(); } catch (_) { } 157 return true; 158}; 159 160export { armDragSession };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.