1(function () { 2 function createFloatingButton(webPluginId, customer) { 3 // æ£æ¥æ¯å¦å·²åå¨æé® 4 const existingButton = document.querySelector('.floating-robot-button'); 5 if (existingButton) { 6 return existingButton; 7 } 8 9 const button = document.createElement('div'); 10 button.className = 'floating-robot-button udesk-client-btn'; 11 button.style.cssText = ` 12 position: fixed; 13 right: -20px; 14 bottom: 100px; 15 width: 80px; 16 height: 80px; 17 cursor: pointer; 18 background-image: url(/webfile/CnResource/images/robotHide.png); 19 background-size: contain; 20 background-repeat: no-repeat; 21 background-position: center; 22 transition: all 0.3s ease; 23 z-index: 1000; 24 `; 25 26 let mouseDownTime = 0; 27 // let isHovering = false; // isHovering is not strictly needed for other functions to know 28 29 button.addEventListener('mouseenter', () => { 30 // isHovering = true; 31 if (button.dataset.isDragging === 'true') return; // Don't interfere if dragging 32 33 button.style.backgroundImage = `url(/webfile/CnResource/images/robotShow.png)`; 34 if (button.style.left === '-20px') { 35 button.style.left = '0px'; 36 } else if (button.style.right === '-20px') { 37 button.style.right = '0px'; 38 } 39 }); 40 41 button.addEventListener('mouseleave', () => { 42 // isHovering = false; 43 if (button.dataset.isDragging === 'true') return; // Don't interfere if dragging 44 45 if (button.style.left === '0px') { 46 button.style.backgroundImage = `url(/webfile/CnResource/images/robotHide.png)`; 47 button.style.left = '-20px'; 48 } else if (button.style.right === '0px') { 49 button.style.backgroundImage = `url(/webfile/CnResource/images/robotHide.png)`; 50 button.style.right = '-20px'; 51 } 52 }); 53 54 button.addEventListener('mousedown', (e) => { // Pass event to draggable if needed, or just for mouseDownTime 55 mouseDownTime = Date.now(); 56 }); 57 58 button.addEventListener('click', e => { 59 if (Date.now() - mouseDownTime > 200) { 60 return; 61 } 62 window.open( 63 `https://intelcc-user.icsoc.net/?channelKey=d0c0d53a6a114f06a1dab1de8d91db9b&init=1`, 64 '_blank', 65 'width=1100,height=670' 66 ); 67 }); 68 69 document.body.appendChild(button); 70 return button; 71 } 72 73 function initializeUdeskChat() { 74 const existingButton = document.querySelector('.floating-robot-button'); 75 if (existingButton) { 76 draggable(existingButton); // Make existing button draggable if re-initializing 77 return; 78 } 79 80 const floatingButton = createFloatingButton(); // Parameters webPluginId, customer are unused here 81 82 // setTimeout is kept as in original, though often not necessary if DOM is ready 83 setTimeout(() => { 84 if (floatingButton) { // Ensure floatingButton was created 85 draggable(floatingButton); 86 } 87 }, 1000); 88 } 89 90 function draggable(element) { 91 let isDragging = false; 92 let offsetX, offsetY; // To store mouse offset within the element 93 94 const dragElement = element || document.querySelector('.udesk-client-btn'); 95 if (!dragElement) return; 96 97 dragElement.addEventListener('mousedown', dragStart); 98 // Mousemove and mouseup listeners are added to the document for broader event capture 99 document.addEventListener('mousemove', drag); 100 document.addEventListener('mouseup', dragEnd); 101 // Optional: touch events for mobile 102 // dragElement.addEventListener('touchstart', dragStart, { passive: false }); 103 // document.addEventListener('touchmove', drag, { passive: false }); 104 // document.addEventListener('touchend', dragEnd); 105 106 107 function dragStart(e) { 108 // Handle both mouse and touch events 109 const currentEvent = e.type.startsWith('touch') ? e.touches[0] : e; 110 111 // Prevent default actions (like text selection or page scroll on touch) 112 if (e.cancelable && !e.type.startsWith('touch')) { // Mouse events can be cancelled this way 113 e.preventDefault(); 114 } else if (e.cancelable && e.type.startsWith('touch')) { // Touch events might need passive: false on listener 115 e.preventDefault(); 116 } 117 118 119 const rect = dragElement.getBoundingClientRect(); 120 121 offsetX = currentEvent.clientX - rect.left; 122 offsetY = currentEvent.clientY - rect.top; 123 124 isDragging = true; 125 dragElement.dataset.isDragging = 'true'; // Communicate dragging state
126 dragElement.style.transition = 'none'; 127 128 // If the element is positioned by 'right' or 'bottom', switch to 'left'/'top' 129 // using its current visual position to avoid jumps. 130 const computedStyle = window.getComputedStyle(dragElement); 131 if (computedStyle.left === 'auto' || computedStyle.top === 'auto' || dragElement.style.right !== '' || dragElement.style.bottom !== '') { 132 dragElement.style.left = `${rect.left}px`; 133 dragElement.style.top = `${rect.top}px`; 134 dragElement.style.right = ''; 135 dragElement.style.bottom = ''; 136 } 137 } 138 139 function drag(e) { 140 if (!isDragging) return; 141 142 const currentEvent = e.type.startsWith('touch') ? e.touches[0] : e; 143 if (e.cancelable) e.preventDefault(); 144 145 146 let newLeft = currentEvent.clientX - offsetX; 147 let newTop = currentEvent.clientY - offsetY; 148 149 const viewportWidth = window.innerWidth; 150 const viewportHeight = window.innerHeight; 151 const elementWidth = dragElement.offsetWidth; 152 const elementHeight = dragElement.offsetHeight; 153 154 // Constrain to viewport 155 const updatedLeft = Math.max(0, Math.min(newLeft, viewportWidth - elementWidth)); 156 const updatedTop = Math.max(0, Math.min(newTop, viewportHeight - elementHeight)); 157 158 dragElement.style.left = `${updatedLeft}px`; 159 dragElement.style.top = `${updatedTop}px`; 160 } 161 162 function dragEnd() { 163 if (!isDragging) return; // Check if actually dragging 164 165 isDragging = false; 166 dragElement.dataset.isDragging = 'false'; // Clear dragging state 167 dragElement.style.transition = 'all 0.3s ease'; 168 169 const rect = dragElement.getBoundingClientRect(); 170 const currentElementLeft = rect.left; 171 const currentElementTop = rect.top; // Keep current top for snapping 172 173 const viewportWidth = window.innerWidth; 174 const elementWidth = dragElement.offsetWidth; 175 const threshold = 10; 176 177 if (currentElementLeft <= threshold) { // Snap to left 178 dragElement.style.left = '-20px'; 179 dragElement.style.right = ''; 180 dragElement.style.top = `${currentElementTop}px`; 181 dragElement.style.backgroundImage = `url(/webfile/CnResource/images/robotHide.png)`; 182 dragElement.style.transform = 'scaleX(-1)'; 183 } else if (currentElementLeft >= viewportWidth - elementWidth - threshold) { // Snap to right 184 dragElement.style.left = ''; 185 dragElement.style.right = '-20px'; 186 dragElement.style.top = `${currentElementTop}px`; 187 dragElement.style.backgroundImage = `url(/webfile/CnResource/images/robotHide.png)`; 188 dragElement.style.transform = 'scaleX(1)'; 189 } else { // In the middle 190 // Position is already set by drag function, ensure right is cleared 191 dragElement.style.right = ''; 192 dragElement.style.backgroundImage = `url(/webfile/CnResource/images/robotShow.png)`; 193 dragElement.style.transform = 'scaleX(1)'; 194 } 195 } 196 } 197 198 function jsonToUrlParams(json) { 199 const params = new URLSearchParams(); 200 for (const [key, value] of Object.entries(json)) { 201 if (Array.isArray(value)) { 202 value.forEach(item => params.append(key, item)); 203 } else { 204 params.append(key, value); 205 } 206 } 207 return params.toString(); 208 } 209 210 if (document.readyState === 'loading') { 211 document.addEventListener('DOMContentLoaded', initializeUdeskChat); 212 } else { 213 initializeUdeskChat(); 214 } 215 216})();
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.