Enhanced Bing ChatAI

Improves Bing ChatAI user experience by preventing accidental scrolling and increasing input character limit

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Enhanced Bing ChatAI
// @namespace   EnhancedBingChatAI
// @description Improves Bing ChatAI user experience by preventing accidental scrolling and increasing input character limit
// @version     1.4.2
// @author      CriDos
// @grant       GM_setClipboard
// @match       https://*.bing.com/*
// @match       https://copilot.microsoft.com/*
// @license     MIT
// ==/UserScript==


// -------- Main code --------

// Prevent scrolling when hovering over cib-serp-main element
window.addEventListener('wheel', (event) => {
    if (event.target.className.includes('cib-serp-main')) {
        event.stopPropagation();
    }
});

// Increase input character limit to 100_000
var increaseCharacterLimit = async () => {
    const PAUSE_TASK = 1 * 1000;
    const MAX_LIMIT = 100_000;

    while (1) {
        try {
            const searchBox = queryElementsInShadowRoots(document.body, '#searchbox')
            for (let i = 0; i < searchBox.length; i++) {
                let sb = searchBox[i];
                if (sb.maxLength < MAX_LIMIT) {
                    console.log("Fixing input character limit to " + MAX_LIMIT);

                    sb.maxLength = MAX_LIMIT;
                    const letterCounter = queryElementsInShadowRoots(document.body, '.letter-counter');
                    if (letterCounter.length > 0) {
                        let letterCounterElement = letterCounter[0].children[0];
                        const currentCountSpan = letterCounterElement;
                        const limitTextNode = currentCountSpan.nextSibling.nextSibling;
                        limitTextNode.textContent = MAX_LIMIT;
                    }
                }
            }
        } catch (e) {
            console.error(e);
        } finally {
            await qWait(PAUSE_TASK);
        }
    }
}

increaseCharacterLimit();

// -------- Utility functions --------

// Query elements in shadow roots
function queryElementsInShadowRoots(node, className) {
    let results = [];

    function traverseShadowRoot(node) {
        if (node.shadowRoot) {
            const elements = node.shadowRoot.querySelectorAll(className);
            elements.forEach(element => {
                results.push(element);
            });

            node.shadowRoot.childNodes.forEach(child => {
                traverseShadowRoot(child);
            });
        } else {
            node.childNodes.forEach(child => {
                traverseShadowRoot(child);
            });
        }
    }

    traverseShadowRoot(node);

    return results;
}

// Wait for an element to appear
function waitForElement(selector, callback, timeout = 1000) {
    const interval = setInterval(() => {
        const element = document.querySelector(selector);
        if (element) {
            clearInterval(interval);
            callback();
        }
    }, timeout);
};


async function qWait(delay) {
    await new Promise((res) => setTimeout(res, delay));
}