oscar.plaisant@icloud.com 03ecc4a65b update
2023-10-23 23:30:51 +02:00

583 lines
18 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// main.ts
__export(exports, {
default: () => SequenceHotkeysPlugin
});
var import_obsidian2 = __toModule(require("obsidian"));
// keys.ts
var import_obsidian = __toModule(require("obsidian"));
var CODE_STR_MAP = new Map([
["Control", "Ctrl-"],
["ControlLeft", "Ctrl-"],
["ControlRight", "Ctrl-"],
["Alt", "Alt-"],
["AltLeft", "Alt-"],
["AltRight", "Alt-"],
["Shift", "Shift-"],
["ShiftLeft", "Shift-"],
["ShiftRight", "Shift-"],
["Meta", "Meta-"],
["MetaLeft", "Meta-"],
["MetaRight", "Meta-"],
["Escape", "Esc"],
["Enter", "Enter"],
["CapsLock", "CapsLock"],
["KeyA", "A"],
["KeyB", "B"],
["KeyC", "C"],
["KeyD", "D"],
["KeyE", "E"],
["KeyF", "F"],
["KeyG", "G"],
["KeyH", "H"],
["KeyI", "I"],
["KeyJ", "J"],
["KeyK", "K"],
["KeyL", "L"],
["KeyM", "M"],
["KeyN", "N"],
["KeyO", "O"],
["KeyP", "P"],
["KeyQ", "Q"],
["KeyR", "R"],
["KeyS", "S"],
["KeyT", "T"],
["KeyU", "U"],
["KeyV", "V"],
["KeyW", "W"],
["KeyX", "X"],
["KeyY", "Y"],
["KeyZ", "Z"],
["Digit0", "0"],
["Digit1", "1"],
["Digit2", "2"],
["Digit3", "3"],
["Digit4", "4"],
["Digit5", "5"],
["Digit6", "6"],
["Digit7", "7"],
["Digit8", "8"],
["Digit9", "9"],
["Minus", "-"],
["Equal", "="],
["BracketLeft", "["],
["BracketRight", "]"],
["Semicolon", ";"],
["Quote", "'"],
["Comma", ","],
["Period", "."],
["Slash", "/"],
["ArrowLeft", "Left"],
["ArrowRight", "Right"],
["ArrowUp", "Up"],
["ArrowDown", "Down"],
["Backquote", "`"]
]);
if (import_obsidian.Platform.isMacOS) {
CODE_STR_MAP.set("Control", "\u2303");
CODE_STR_MAP.set("ControlLeft", "\u2303");
CODE_STR_MAP.set("ControlRight", "\u2303");
CODE_STR_MAP.set("Alt", "\u2325");
CODE_STR_MAP.set("AltLeft", "\u2325");
CODE_STR_MAP.set("AltRight", "\u2325");
CODE_STR_MAP.set("Shift", "\u21E7");
CODE_STR_MAP.set("ShiftLeft", "\u21E7");
CODE_STR_MAP.set("ShiftRight", "\u21E7");
CODE_STR_MAP.set("Meta", "\u2318");
CODE_STR_MAP.set("MetaLeft", "\u2318");
CODE_STR_MAP.set("MetaRight", "\u2318");
CODE_STR_MAP.set("Escape", "\u238B");
CODE_STR_MAP.set("Enter", "\u23CE");
CODE_STR_MAP.set("CapsLock", "\u21EA");
}
var codeToString = (e) => CODE_STR_MAP.get(e) || e;
var isModifier = (key) => {
switch (key) {
case "Control":
case "Alt":
case "Shift":
case "Meta":
case "ControlLeft":
case "AltLeft":
case "ShiftLeft":
case "MetaLeft":
case "ControlRight":
case "AltRight":
case "ShiftRight":
case "MetaRight":
return true;
default:
return false;
}
};
var keySequenceEqual = (a, b) => a.length === b.length && a.every((c, i) => c.equals(b[i]));
var keySequencePartiallyEqual = (a, b) => {
if (a.length === 0 || b.length === 0) {
return false;
}
if (a.length > b.length) {
return b.every((c, i) => c.equals(a[i]));
}
return a.every((c, i) => c.equals(b[i]));
};
var KeyChord = class {
constructor(input) {
this.meta = false;
this.ctrl = false;
this.alt = false;
this.shift = false;
this.key = "";
this.equals = (other) => {
return !!other && this.key === other.key && this.meta === other.meta && this.ctrl === other.ctrl && this.alt === other.alt && this.shift === other.shift;
};
this.serialize = () => {
const parts = new Array();
if (this.meta) {
parts.push("M");
}
if (this.ctrl) {
parts.push("C");
}
if (this.alt) {
parts.push("A");
}
if (this.shift) {
parts.push("S");
}
parts.push(this.key);
return parts.join("-");
};
this.toString = () => {
const keys = new Array();
if (this.meta) {
keys.push("Meta");
}
if (this.ctrl) {
keys.push("Control");
}
if (this.alt) {
keys.push("Alt");
}
if (this.shift) {
keys.push("Shift");
}
keys.push(codeToString(this.key));
return keys.map(codeToString).join("");
};
if (typeof input === "string") {
const parts = input.split("-");
this.key = parts.pop();
parts.map((p) => {
switch (p) {
case "M":
this.meta = true;
break;
case "C":
this.ctrl = true;
break;
case "A":
this.alt = true;
break;
case "S":
this.shift = true;
break;
}
});
} else {
if (!isModifier(input.code)) {
this.key = input.code;
}
this.meta = input.metaKey;
this.ctrl = input.ctrlKey;
this.alt = input.altKey;
this.shift = input.shiftKey;
}
}
};
// hotkey-manager.ts
function arrayStartsWith(arr, start) {
if (start.length > arr.length) {
return false;
}
return start.every((_, i) => arr[i] === start[i]);
}
var HotkeyManager = class {
constructor(triggerHandler) {
this._matchingHotheys = () => {
const css = this.currentSequence.map((c) => c.toString());
return this.registeredHotkeys.filter((r) => {
const rcs = r.chords.map((c) => c.toString());
return arrayStartsWith(rcs, css);
});
};
this.handleChordPress = (chord) => {
this.currentSequence.push(chord);
let hotkeys = this._matchingHotheys();
if (hotkeys.length === 0 && this.currentSequence.length > 1) {
this.currentSequence = [chord];
hotkeys = this._matchingHotheys();
}
if (hotkeys.length === 0) {
this.currentSequence = [];
return false;
}
let exactMatch = hotkeys.find((r) => {
return this.currentSequence.length === r.chords.length;
});
if (exactMatch) {
this.currentSequence = [];
this.triggerHandler(hotkeys[0].id);
}
return true;
};
this.reset = () => {
this.registeredHotkeys = [];
};
this.addHotkey = (id, chords) => {
this.registeredHotkeys.push({ id, chords });
};
this.removeHotkey = (id) => {
this.registeredHotkeys = this.registeredHotkeys.filter((r) => r.id !== id);
};
this.triggerHandler = triggerHandler;
this.registeredHotkeys = [];
this.currentSequence = [];
}
};
// src/chord_listener.ts
var ChordListener = class {
constructor(onChord) {
this.chordPress = (event) => {
if (!!this._lastKeydown) {
if (this.onChord(new KeyChord(this._lastKeydown))) {
event.preventDefault();
event.stopPropagation();
}
this._lastKeydown = void 0;
}
};
this.destruct = () => {
document.removeEventListener("keydown", this.handleKeydown, { capture: true });
document.removeEventListener("keyup", this.handleKeyup, { capture: true });
};
this.onChord = onChord;
this.handleKeydown = (event) => {
this._lastKeydown = event;
if (isModifier(event.code)) {
return;
}
this.chordPress(event);
};
this.handleKeyup = (event) => {
this.chordPress(event);
};
document.addEventListener("keydown", this.handleKeydown, { capture: true });
document.addEventListener("keyup", this.handleKeyup, { capture: true });
}
};
// main.ts
var hotkeysEqual = (a, b) => a.command === b.command && keySequenceEqual(a.chords, b.chords);
var DEFAULT_SETTINGS = {
hotkeys: Array()
};
var SerializeSettings = (settings) => {
return {
hotkeys: settings.hotkeys.map((h) => ({
command: h.command,
chords: h.chords.map((c) => c.serialize())
}))
};
};
var DeserializeSettings = (data) => {
let settings = DEFAULT_SETTINGS;
if (data == null ? void 0 : data.hotkeys) {
settings.hotkeys = data.hotkeys.map((h) => ({
command: h.command,
chords: h.chords.map((c) => new KeyChord(c))
}));
}
return settings;
};
function allCommands(app) {
const commands = Object.values(app.commands.commands);
commands.sort((a, b) => a.name.localeCompare(b.name));
return commands;
}
var commandName = (app, id) => {
var _a;
return (_a = allCommands(app).find((c) => c.id === id)) == null ? void 0 : _a.name;
};
var hotkeysForCommand = (s, id) => s.hotkeys.filter((h) => h.command === id);
var SequenceHotkeysPlugin = class extends import_obsidian2.Plugin {
constructor() {
super(...arguments);
this._settingsUpdated = () => {
var _a;
this.saveSettings();
this.hotkeyManager.reset();
this.settings.hotkeys.map((h) => this.hotkeyManager.addHotkey(h.command, h.chords));
(_a = this.saveListener) == null ? void 0 : _a.call(this, this.settings);
};
this.setSaveListener = (fn) => {
this.saveListener = fn;
};
this.addHotkey = (commandId, chords) => {
if (chords == null ? void 0 : chords.length) {
this.settings.hotkeys = [
...this.settings.hotkeys,
{
command: commandId,
chords
}
];
}
this._settingsUpdated();
};
this.deleteHotkey = (commandId, chords) => {
this.settings.hotkeys = this.settings.hotkeys.filter((h) => h.command != commandId || !keySequenceEqual(h.chords, chords));
this._settingsUpdated();
};
}
onload() {
return __async(this, null, function* () {
this.hotkeyManager = new HotkeyManager((id) => this.app.commands.executeCommandById(id));
yield this.loadSettings();
this.addSettingTab(new SequenceHotkeysSettingTab(this.app, this));
this.chordListener = new ChordListener((chord) => {
if (!!this.app.setting.activeTab) {
return false;
}
return this.hotkeyManager.handleChordPress(chord);
});
});
}
onunload() {
this.chordListener.destruct();
}
loadSettings() {
return __async(this, null, function* () {
this.settings = Object.assign({}, DeserializeSettings(yield this.loadData()));
this._settingsUpdated();
});
}
saveSettings() {
return __async(this, null, function* () {
yield this.saveData(SerializeSettings(this.settings));
});
}
};
var SequenceHotkeysSettingTab = class extends import_obsidian2.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.setFilter = (s) => {
this.filter = s;
const filterParts = this.filter.toLowerCase().split(" ");
this.commandSettingEls.map((cs) => cs.settingEl.toggle(filterParts.every((part) => cs.getCommand().name.toLowerCase().contains(part))));
};
this.plugin = plugin;
this.filter = "";
this.commandSettingEls = new Array();
}
hide() {
this.commandSettingEls.map((s) => s.hide());
}
display() {
const { containerEl } = this;
containerEl.empty();
let searchEl;
new import_obsidian2.Setting(containerEl).addSearch((s) => {
searchEl = s;
s.setPlaceholder("Filter...");
});
searchEl.onChange(this.setFilter);
const commandsContainer = containerEl.createDiv();
this.commandSettingEls = allCommands(this.app).map((command) => new CommandSetting(commandsContainer, command, this.plugin.addHotkey, this.plugin.deleteHotkey));
const updateCommands = (s) => {
this.commandSettingEls.map((cs) => {
const hotkeys = hotkeysForCommand(s, cs.getCommand().id).map((h) => {
const conflict = s.hotkeys.find((shc) => !hotkeysEqual(shc, h) && keySequencePartiallyEqual(shc.chords, h.chords));
return {
chords: h.chords,
warning: !!conflict ? `This hotkey conflicts with "${commandName(this.app, conflict.command)}"` : ""
};
});
cs.display(hotkeys);
});
};
this.plugin.setSaveListener(updateCommands);
updateCommands(this.plugin.settings);
searchEl.inputEl.focus();
}
};
var CommandSetting = class extends import_obsidian2.Setting {
constructor(containerEl, command, onCreated, onDelete) {
super(containerEl);
this.getCommand = () => this.command;
this.hide = () => {
this.setCancelCapture(void 0);
};
this.setCancelCapture = (cb) => {
var _a;
(_a = this.cancelCapture) == null ? void 0 : _a.call(this);
this.cancelCapture = cb;
};
this.display = (hotkeys) => {
this.clear();
this.setName(this.command.name);
const hotkeyDiv = this.controlEl.createDiv({
cls: "setting-command-hotkeys"
});
for (const hotkey of hotkeys) {
const warnClass = !!hotkey.warning ? " has-conflict" : "";
const hotkeySpan = hotkeyDiv.createSpan({
cls: "setting-hotkey" + warnClass,
attr: { "aria-label": hotkey.warning }
});
const hotkeySpanText = hotkeySpan.createSpan({
text: hotkey.chords.map((c) => c.toString()).join(" ") + " "
});
const deleteBtn = hotkeySpanText.createSpan({
cls: "setting-hotkey-icon setting-delete-hotkey",
attr: { "aria-label": "Delete hotkey" }
});
(0, import_obsidian2.setIcon)(deleteBtn, "cross", 8);
deleteBtn.onClickEvent(() => {
this.onDelete(this.command.id, hotkey.chords);
});
}
const addBtn = this.controlEl.createSpan({
cls: "setting-add-hotkey-button",
attr: { "aria-label": "Customize this command" }
});
(0, import_obsidian2.setIcon)(addBtn, "any-key", 22);
addBtn.onClickEvent(() => {
const newHotkeySpan = hotkeyDiv.createSpan({
cls: "setting-hotkey"
});
const newHotkeySpanText = newHotkeySpan.createSpan({
text: "Press hotkey..."
});
const onUpdate = (chords) => {
newHotkeySpanText.setText(chords.map((c) => c.toString()).join(" "));
};
const onComplete = (chords) => {
var _a;
this.setCancelCapture(void 0);
(_a = this.onCreated) == null ? void 0 : _a.call(this, this.command.id, chords);
};
const chordCapturer = new CaptureChord(onUpdate, onComplete);
this.setCancelCapture(chordCapturer.destruct);
newHotkeySpan.addClass("mod-active");
addBtn.hide();
const menuBtn = this.controlEl.createSpan({
cls: "setting-add-hotkey-button",
attr: {
"aria-label": `Add ${codeToString("Enter")} or ${codeToString("Escape")} key to sequence`
}
});
(0, import_obsidian2.setIcon)(menuBtn, "plus", 22);
const menu = new import_obsidian2.Menu(menuBtn).setNoIcon();
menu.addItem((item) => item.setTitle("Add " + codeToString("Enter")).onClick(() => {
chordCapturer.pushChord(new KeyChord("Enter"));
}));
menu.addItem((item) => item.setTitle("Add " + codeToString("Escape")).onClick(() => {
chordCapturer.pushChord(new KeyChord("Escape"));
}));
menuBtn.onClickEvent((event) => {
menu.showAtMouseEvent(event);
});
const doneBtn = this.controlEl.createSpan({
cls: "setting-add-hotkey-button",
attr: {
"aria-label": "Accept hotkey sequence"
}
});
(0, import_obsidian2.setIcon)(doneBtn, "checkbox-glyph", 22);
doneBtn.onClickEvent(() => {
onComplete(chordCapturer.chords);
});
});
};
this.command = command;
this.onCreated = onCreated;
this.onDelete = onDelete;
}
};
var CaptureChord = class {
constructor(onUpdate, onComplete) {
this.pushChord = (c) => {
this.chords.push(c);
this.onUpdate(this.chords);
};
this.destruct = () => {
this.chordListener.destruct();
};
this.chords = new Array();
this.onUpdate = onUpdate;
this.onComplete = onComplete;
this.chordListener = new ChordListener((c) => {
if (!c.alt && !c.ctrl && !c.shift && !c.meta && (c.key === "Enter" || c.key === "Escape")) {
this.destruct();
if (c.key === "Enter") {
this.onComplete(this.chords);
}
return true;
}
this.pushChord(c);
return true;
});
}
};