const fs = require('fs'); let code = fs.readFileSync('src/components/TerminalPanel.vue', 'utf8'); // Replace standard touch handlers to heavily trace let newStart = ` onTouchKeyboardTouchStart = (event: TouchEvent) => { clearTouchScrollMomentum(); if (event.touches.length > 0) { touchScrollLastY = event.touches[0]?.clientY || 0; touchScrollLastTime = performance.now(); touchScrollVelocity = 0; } console.log("[Scroll Deep] 🟢 TOUCH START:", { touches: event.touches.length, isCancelable: event.cancelable, target: event.target?.nodeName, viewportScrollTop: viewportScroller?.scrollTop }); if (!helperTextarea) return; if (focusKeyboardTimerId !== null) { window.clearTimeout(focusKeyboardTimerId); focusKeyboardTimerId = null; clearFocusKeyboardBlurRecover(); focusKeyboardInProgress = false; } helperTextarea.readOnly = true; };`; let newMove = ` onTouchKeyboardTouchMove = (event: TouchEvent) => { console.log(\`[Scroll Deep] 🔵 TOUCH MOVE | cancelable: \${event.cancelable} | target: \${event.target?.nodeName}\`); const hasSelection = hasActiveNativeSelectionInTerminal(); if (hasSelection) { lastTouchAction = "PASS_NATIVE"; event.stopImmediatePropagation(); return; } const now = performance.now(); const dt = now - touchScrollLastTime; const currentY = event.touches[0]?.clientY || 0; const dy = currentY - touchScrollLastY; // Stop xterm from intercepting this manually event.stopImmediatePropagation(); if (viewportScroller && dt > 0) { const before = viewportScroller.scrollTop; if (dy !== 0) { // JS 强控滑动:完全跟手,零延迟 viewportScroller.scrollTop -= dy; } // 计算物理滑动速度,用于释放后的动量 const v = (-dy / dt) * 16; if (touchScrollVelocity * v > 0) { touchScrollVelocity = touchScrollVelocity * 0.5 + v * 0.5; } else { touchScrollVelocity = v; } const touchMaxSpeed = 120; if (touchScrollVelocity > touchMaxSpeed) touchScrollVelocity = touchMaxSpeed; else if (touchScrollVelocity < -touchMaxSpeed) touchScrollVelocity = -touchMaxSpeed; if (Math.abs(dy) > 2) { console.log(\`[Scroll Deep] ➡️ 手指位移真实触发生效,Δy=\${dy.toFixed(1)}px | 渲染视口=\${before}→\${viewportScroller.scrollTop} | v=\${v.toFixed(2)}\`); } } touchScrollLastY = currentY; touchScrollLastTime = now; };`; let newEnd = ` onTouchKeyboardTouchEnd = (event: TouchEvent) => { console.log(\`[Scroll Deep] 🔴 TOUCH END/CANCEL | cancelable: \${event.cancelable} | target: \${event.target?.nodeName} | 最终 scrollTop: \${viewportScroller?.scrollTop}\`); const threshold = 0.2; if (Math.abs(touchScrollVelocity) > threshold) { touchScrollVelocity *= 1.35; console.log(\`[Scroll Deep] 🚀 准备进行 JS 惯性滚动,起步速度=\${touchScrollVelocity.toFixed(2)}\`); runTouchScrollMomentum(); } else { console.log(\`[Scroll Deep] 🛑 静止释放,不触发惯性\`); } };`; code = code.replace(/onTouchKeyboardTouchStart = \(event: TouchEvent\) => \{[\s\S]*?\}\;\n onTouchKeyboardTouchMove = \(event: TouchEvent\) => \{[\s\S]*?\}\;\n onTouchKeyboardTouchEnd = \(\) => \{[\s\S]*?\}\;/m, newStart + '\n' + newMove + '\n' + newEnd); // Add pointer event logs code = code.replace(/onTouchKeyboardPointerDown = \(event: PointerEvent\) => \{/, `onTouchKeyboardPointerDown = (event: PointerEvent) => { console.log("[Scroll Deep] 🟡 POINTER DOWN: ", { pointerId: event.pointerId, type: event.pointerType, target: event.target?.nodeName });`); code = code.replace(/onTouchKeyboardPointerMove = \(event: PointerEvent\) => \{/, `onTouchKeyboardPointerMove = (event: PointerEvent) => { if (event.pointerType === "touch" && touchGatePointerId === event.pointerId) { // only log occasionally to avoid spam, we are heavily logging touchmove already }`); code = code.replace(/onTouchKeyboardPointerUp = \(event: PointerEvent\) => \{/, `onTouchKeyboardPointerUp = (event: PointerEvent) => { console.log("[Scroll Deep] 🟠 POINTER UP: ", { pointerId: event.pointerId, type: event.pointerType });`); code = code.replace(/onTouchKeyboardPointerCancel = \(event: PointerEvent\) => \{/, `onTouchKeyboardPointerCancel = (event: PointerEvent) => { console.log("[Scroll Deep] ⚫ POINTER CANCEL: ", { pointerId: event.pointerId, type: event.pointerType });`); fs.writeFileSync('src/components/TerminalPanel.vue', code);