Skip to content

Instantly share code, notes, and snippets.

@prasoon2211
Last active September 20, 2024 08:49
Show Gist options
  • Save prasoon2211/681ed29d8224a09f0d0d6d63e57c071e to your computer and use it in GitHub Desktop.
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)
// ==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