1// ============================================================ 2// UI / AiDialog.js â AI æµ®å¨å¯¹è¯æ¡ï¼ææ½ä¸èªç±æä¼¸ï¼ 3// ============================================================ 4 5// ==================== AI æµ®çªææ½ä¸èªç±æä¼¸ ==================== 6export function initAIFloatingDialog() { 7 const dialog = document.getElementById('aiFloatingDialog'); 8 if (!dialog) return; 9 10 // ç¹å»æµ®çªä»»æä½ç½®æ¶ç½®é¡¶ï¼å§ç»å¨æä¸å±ï¼ 11 dialog.addEventListener('mousedown', function () { 12 if (!window._aiZIndex) window._aiZIndex = 100000; 13 window._aiZIndex++; 14 dialog.style.zIndex = window._aiZIndex; 15 }); 16 17 // ---------- ææ½ ---------- 18 const header = dialog.querySelector('.ai-drag-header'); 19 let dragX = 0, dragY = 0, dragL = 0, dragT = 0; 20 let isDragging = false; 21 22 header.addEventListener('mousedown', (e) => { 23 if (e.target.tagName === 'SELECT' || e.target.tagName === 'BUTTON') return; 24 e.preventDefault(); 25 isDragging = true; 26 dragL = dialog.offsetLeft; 27 dragT = dialog.offsetTop; 28 dragX = e.clientX; 29 dragY = e.clientY; 30 dialog.style.left = dragL + 'px'; 31 dialog.style.top = dragT + 'px'; 32 dialog.style.right = 'auto'; 33 dialog.style.bottom = 'auto'; 34 document.body.style.userSelect = 'none'; 35 }); 36 37 window.addEventListener('mousemove', (e) => { 38 if (!isDragging) return; 39 dialog.style.left = (dragL + e.clientX - dragX) + 'px'; 40 dialog.style.top = (dragT + e.clientY - dragY) + 'px'; 41 }); 42 43 window.addEventListener('mouseup', () => { 44 if (isDragging) { 45 isDragging = false; 46 document.body.style.userSelect = ''; 47 } 48 }); 49 50 // ---------- å «æ¹åæä¼¸ ---------- 51 const handles = dialog.querySelectorAll('.floating-resize-handle'); 52 let resizing = false; 53 let resizeHandle = ''; 54 let startX = 0, startY = 0; 55 let startW = 0, startH = 0; 56 let startL = 0, startT = 0; 57 58 handles.forEach(h => { 59 h.addEventListener('mousedown', (e) => { 60 e.preventDefault(); 61 e.stopPropagation(); 62 resizing = true; 63 resizeHandle = h.getAttribute('data-handle'); 64 startW = dialog.offsetWidth; 65 startH = dialog.offsetHeight; 66 startL = dialog.offsetLeft; 67 startT = dialog.offsetTop; 68 startX = e.clientX; 69 startY = e.clientY; 70 dialog.style.left = startL + 'px'; 71 dialog.style.top = startT + 'px'; 72 dialog.style.right = 'auto'; 73 dialog.style.bottom = 'auto'; 74 document.body.style.userSelect = 'none'; 75 document.body.style.cursor = getComputedStyle(h).cursor; 76 }); 77 }); 78 79 window.addEventListener('mousemove', (e) => { 80 if (!resizing) return; 81 const dx = e.clientX - startX; 82 const dy = e.clientY - startY; 83 let newL = startL, newT = startT, newW = startW, newH = startH; 84 85 if (resizeHandle.includes('e')) newW = Math.max(240, startW + dx); 86 if (resizeHandle.includes('w')) { newW = Math.max(240, startW - dx); newL = startL + startW - newW; } 87 if (resizeHandle.includes('s')) newH = Math.max(200, startH + dy); 88 if (resizeHandle.includes('n')) { newH = Math.max(200, startH - dy); newT = startT + startH - newH; } 89 90 dialog.style.left = newL + 'px'; 91 dialog.style.top = newT + 'px'; 92 dialog.style.width = newW + 'px'; 93 dialog.style.height = newH + 'px'; 94 }); 95 96 window.addEventListener('mouseup', () => { 97 if (resizing) { 98 resizing = false; 99 document.body.style.userSelect = ''; 100 document.body.style.cursor = ''; 101 } 102 }); 103}
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.