KMLibrary for interacting with Mac KM
ეს სკრიპტი არ უნდა იყოს პირდაპირ დაინსტალირებული. ეს ბიბლიოთეკაა, სხვა სკრიპტებისთვის უნდა ჩართეთ მეტა-დირექტივაში // @require https://update.greasyfork.org/scripts/571968/1787733/KMLibrary.js.
// ==UserScript==
// @name KMLibrary
// @namespace https://greasyfork.org/users/28298
// @version 0.6
// @description KMLibrary for interacting with Mac KM
// @author Jerry
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @license GNU GPLv3
// @noframes
// @require https://greasyfork.org/scripts/456410-gmlibrary/code/GMLibrary.js
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @connect localhost
// @run-at document-start
// ==/UserScript==
// KM -> Hotkey (Mousetrap.bindGlobal) -> UserScript -> KM (requestKM webserver)
// ── Shared KM helpers ─────────────────────────────────────────────────────
function isInEditbox() {
const activeEl = unsafeWindow.document.activeElement;
if (!activeEl) return false;
const tagName = activeEl.tagName.toLowerCase();
if (tagName === 'textarea') return true;
if (tagName === 'input') {
const type = (activeEl.type || '').toLowerCase();
return ['text', 'search', 'email', 'url', 'tel', 'password', 'number'].includes(type);
}
if (activeEl.isContentEditable) return true;
const contentEditable = activeEl.getAttribute('contenteditable');
return contentEditable === 'true' || contentEditable === '';
}
function getPageContext() {
const sel = unsafeWindow.getSelection();
return {
url: unsafeWindow.location.href,
title: unsafeWindow.document.title,
isInEditbox: isInEditbox(),
selectedText: sel ? sel.toString() : ''
};
}
function requestKM(macroId) {
GM_xmlhttpRequest({
method: 'GET',
url: 'https://localhost:3011/action.html?macro=' + macroId +
'&value=' + encodeURIComponent(JSON.stringify(getPageContext())),
timeout: 2000,
onerror: function() {},
ontimeout: function() {}
});
}
/**
* triggerKM(trigger, macroID, mode)
*
* @param {string|string[]} trigger - hotkey (e.g. 'mod+d') or hotstring (e.g. 'hello')
* @param {string} macroID - KM macro UUID
* @param {number} mode - 1 = outside editbox only
* 2 = inside editbox only
* 3 = anywhere
*/
function triggerKM(trigger, macroID, mode=3) {
Mousetrap.bindGlobal(trigger, function () {
const inBox = isInEditbox();
if (mode === 1 && inBox) return true; // pass through — let editbox handle it
if (mode === 2 && !inBox) return false; // swallow — not in an editbox
requestKM(macroID);
return false; // prevent default / stop propagation
});
}
function isAppleSilicon() {
try {
const canvas = document.createElement('canvas');
const gl =
canvas.getContext('webgl') ||
canvas.getContext('experimental-webgl');
if (!gl) return false;
const renderer = gl.getParameter(gl.RENDERER) || '';
const r = renderer.toLowerCase();
// "Apple M1, or similar"
if (r.includes('apple m1')) {
return true;
}
// Fallback: not confidently Apple Silicon
return false;
} catch (e) {
return false;
}
}