JS Helper UI (TamperMonkey Adapted)

Набір допоміжних UI-функцій для юзерскриптів (копіювання, завантаження файлів, керування меню, шортенери)

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greatest.deepsurf.us/scripts/575419/1808366/JS%20Helper%20UI%20%20%28TamperMonkey%20Adapted%29.js을(를) 사용하여 포함하는 라이브러리입니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

/* jshint esversion: 8 */

const jsHelperUi = (function() {
    const lib = {
        const: {
            corsProxyUrl: 'https://corsproxy.io/?url=',
            shorteners: {
                'clck.ru': 'https://clck.ru/--?url=',
                'is.gd': 'https://corsproxy.io/?url=' + encodeURIComponent('https://is.gd/create.php?format=simple&url='),
                'v.gd': 'https://corsproxy.io/?url=' + encodeURIComponent('https://v.gd/create.php?format=simple&url='),
            }
        }
    };

    /**
     * Копіювання тексту в буфер (з фолбеком для старих браузерів)
     */
    lib.copyTextToClipboard = async text => {
        try {
            if (window.isSecureContext && navigator.clipboard) {
                await navigator.clipboard.writeText(text);
            } else {
                const textarea = document.createElement('textarea');
                textarea.style.opacity = '0';
                textarea.style.position = 'absolute';
                textarea.value = text;
                document.body.appendChild(textarea);
                textarea.select();
                document.execCommand('copy');
                document.body.removeChild(textarea);
            }
        } catch (e) { console.error('2xGeMINI Lib Error:', e); }
    };

    /**
     * Завантаження даних як файлу
     */
    lib.downloadDataAsFile = (data, filename = 'download.txt', contentType = 'text/plain') => {
        const blob = new Blob(data, {type: contentType});
        const fileURL = URL.createObjectURL(blob);
        const downloadLink = document.createElement('a');
        downloadLink.href = fileURL;
        downloadLink.download = filename;
        document.body.appendChild(downloadLink);
        downloadLink.click();
        downloadLink.remove();
        URL.revokeObjectURL(fileURL);
    };

    /**
     * Секретні послідовності клавіш (Коди: https://toptal.com/developers/keycode)
     */
    lib.onKeyCodeSequence = (keyCodeSequence, callback, once = false) => {
        keyCodeSequence = keyCodeSequence.replace(/ /g, '');
        let inputKeySequence = [];
        function listener(keyboardEvent) {
            if (keyboardEvent.code === 'Escape') {
                inputKeySequence = [];
            } else {
                inputKeySequence.push(keyboardEvent.code);
                if (inputKeySequence.toString().includes(keyCodeSequence)) {
                    if (once) window.removeEventListener('keyup', listener);
                    inputKeySequence = [];
                    callback();
                }
            }
        }
        window.addEventListener('keyup', listener);
    };

    /**
     * Скорочення URL
     */
    lib.shortUrl = async (urlForShortening, shortenerUrl = 'clck.ru', corsProxy = false) => {
        let finalUrl = lib.const.shorteners[shortenerUrl] || shortenerUrl;
        if (corsProxy && !lib.const.shorteners[shortenerUrl]) {
            finalUrl = lib.const.corsProxyUrl + encodeURIComponent(finalUrl);
        }
        try {
            const response = await fetch(finalUrl + encodeURIComponent(urlForShortening));
            if (response.ok) return await response.text();
        } catch (e) { console.error('2xGeMINI Lib Error:', e); }
    };

    // Блокування контекстного меню
    lib.disableContextMenu = () => window.addEventListener('contextmenu', lib._cmL);
    lib.enableContextMenu = () => window.removeEventListener('contextmenu', lib._cmL);
    lib._cmL = e => e.preventDefault();

    return lib;
})();

// Експорт для різних середовищ
if (typeof module !== 'undefined' && module.exports) {
    module.exports = jsHelperUi; // Для Node.js/CommonJS
} else if (typeof define === 'function' && define.amd) {
    define(() => jsHelperUi); // Для AMD
} else {
    window.jsHelperUi = jsHelperUi; // Для браузера та Tampermonkey
}