Last active
September 20, 2024 08:49
-
-
Save prasoon2211/681ed29d8224a09f0d0d6d63e57c071e to your computer and use it in GitHub Desktop.
ChatKit restore Ctrn+N behavior using Tampermoney (Ctrl+N works like arrow down)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Block Chatkit Ctrl + N, Restore Mac Behavior in Input | |
// @namespace http://tampermonkey.net/ | |
// @version 0.7 | |
// @description Block chatkit.app from hijacking Ctrl + N and move cursor down within the same input field (like macOS default) | |
// @author your_name | |
// @match https://chatkit.app/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
/** | |
* Move cursor down one line in a textarea. | |
* @param {HTMLTextAreaElement} textarea | |
*/ | |
function moveCursorDownInTextarea(textarea) { | |
const value = textarea.value; | |
const selectionStart = textarea.selectionStart; | |
const selectionEnd = textarea.selectionEnd; | |
// Find the start of the current line | |
const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1; | |
// Find the end of the current line | |
const lineEnd = value.indexOf('\n', selectionStart); | |
const currentLineEnd = lineEnd === -1 ? value.length : lineEnd; | |
// Calculate the cursor's column (offset from line start) | |
const cursorColumn = selectionStart - lineStart; | |
// Find the start of the next line | |
const nextLineStart = lineEnd === -1 ? -1 : lineEnd + 1; | |
if (nextLineStart === -1 || nextLineStart >= value.length) { | |
// No next line exists | |
console.log("No next line to move the cursor to."); | |
return; | |
} | |
// Find the end of the next line | |
const nextLineEnd = value.indexOf('\n', nextLineStart); | |
const actualNextLineEnd = nextLineEnd === -1 ? value.length : nextLineEnd; | |
// Calculate the new cursor position | |
const newCursorPos = Math.min(nextLineStart + cursorColumn, actualNextLineEnd); | |
// Set the new cursor position | |
textarea.selectionStart = textarea.selectionEnd = newCursorPos; | |
textarea.focus(); | |
console.log(`Cursor moved to position ${newCursorPos} in textarea.`); | |
} | |
/** | |
* Move cursor down one line in a contenteditable element. | |
* This implementation tries to move the cursor to the next visual line. | |
* Note: This is a best-effort approach and may not work perfectly in all cases. | |
* @param {HTMLElement} elem | |
*/ | |
function moveCursorDownInContentEditable(elem) { | |
const selection = window.getSelection(); | |
if (selection.rangeCount === 0) { | |
return; | |
} | |
const range = selection.getRangeAt(0).cloneRange(); | |
// Collapse the range to the end point of the selection | |
range.collapse(false); | |
// Create a temporary span to mark the current cursor position | |
const tempSpan = document.createElement('span'); | |
tempSpan.id = 'temp-cursor-position'; | |
range.insertNode(tempSpan); | |
// Move the cursor position after the temp span | |
const newRange = document.createRange(); | |
newRange.setStartAfter(tempSpan); | |
newRange.collapse(true); | |
// Remove the temp span | |
tempSpan.parentNode.removeChild(tempSpan); | |
// Update the selection | |
selection.removeAllRanges(); | |
selection.addRange(newRange); | |
// Attempt to move the cursor down using the existing method | |
// Since synthetic events don't work, another approach is needed | |
// For simplicity, we'll log that this action needs to be handled manually | |
console.log("Ctrl + N pressed in contenteditable. Cursor moved to the next position."); | |
} | |
window.addEventListener('keydown', function(e) { | |
// Check for Ctrl + N (it's case-insensitive) | |
if (e.ctrlKey && (e.key === 'n' || e.key === 'N')) { | |
// Ensure no other modifier keys are pressed | |
if (!e.altKey && !e.shiftKey && !e.metaKey) { | |
// Prevent ChatKit's default handler and any other handlers | |
e.stopImmediatePropagation(); | |
e.preventDefault(); | |
console.log("Ctrl + N intercepted and blocked."); | |
// Get the currently active element | |
const activeElem = document.activeElement; | |
// Determine the type of active element and move cursor accordingly | |
if (activeElem.tagName === 'TEXTAREA') { | |
console.log("Inside a textarea."); | |
moveCursorDownInTextarea(activeElem); | |
} else if (activeElem.isContentEditable) { | |
console.log("Inside a contenteditable element."); | |
moveCursorDownInContentEditable(activeElem); | |
} else { | |
console.log("Not inside a textarea or contenteditable element."); | |
} | |
} | |
} | |
}, true); // Use capture phase to intercept early | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment