1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-25 23:03:15 +00:00

Add support for global keyboard shortcuts (#3493)

* changes for global keyboardshortcuts

* add keyboard.js startup module

* remove not existing "th-opening-window" hook

* correct title

* use utils.addEventListeners

* define platform lookup-names on startup

* use the startup-lookup-names array

* use the platform-specific lookupNames only

* Update keyboard.js

* move initializations to the constructor

* move initializations to the constructor

* rename hasAnyTiddlerChanged

* don't explicitely create new RegExp

* use $tw.utils.hopArray

* match strings, no regex

* remove hopArray, move to boot.js

* add $tw.utils.hopArray to boot.js

* style update

* style updates

* move more to keyboardManager module

this could probably be moved to rootwidget.js

* move more to keyboardManager module

* add event listener for shortcuts in new windows

* prevent error when opening window is blocked

* add keydown listener on document in startup.js

* delete startup/keyboard.js

* add missing this.shortcutTiddlers

* Update keyboard.js

* Update boot.js

* add exports.hopArray to utils.js

* minor codingstyle tweak

* change how lookupnames get pushed to array

* Update windows.js

* re-add shortcuts-listener for new windows

I removed this before which I think was because I misunderstood what exactly should go to a separate PR
This commit is contained in:
BurningTreeC 2018-11-06 14:34:51 +01:00 committed by Jeremy Ruston
parent b584295831
commit 3592333cb8
4 changed files with 104 additions and 4 deletions

View File

@ -138,6 +138,17 @@ function KeyboardManager(options) {
}); });
// Save the platform-specific name of the "meta" key // Save the platform-specific name of the "meta" key
this.metaKeyName = $tw.platform.isMac ? "cmd-" : "win-"; this.metaKeyName = $tw.platform.isMac ? "cmd-" : "win-";
this.shortcutKeysList = [], // Stores the shortcut-key descriptors
this.shortcutActionList = [], // Stores the corresponding action strings
this.shortcutParsedList = []; // Stores the parsed key descriptors
this.lookupNames = ["shortcuts"];
this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac")
this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows");
this.lookupNames.push($tw.platform.isLinux ? "shortcuts-linux" : "shortcuts-not-linux");
this.updateShortcutLists(this.getShortcutTiddlerList());
$tw.wiki.addEventListener("change",function(changes) {
self.handleShortcutChanges(changes);
});
} }
/* /*
@ -229,10 +240,9 @@ KeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options)
result.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options)); result.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));
} }
}; };
lookupName("shortcuts"); $tw.utils.each(self.lookupNames,function(platformDescriptor) {
lookupName($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac"); lookupName(platformDescriptor);
lookupName($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows"); });
lookupName($tw.platform.isLinux ? "shortcuts-linux" : "shortcuts-not-linux");
} }
} else { } else {
result.push(self.parseKeyDescriptor(keyDescriptor)); result.push(self.parseKeyDescriptor(keyDescriptor));
@ -274,6 +284,70 @@ KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {
return false; return false;
}; };
KeyboardManager.prototype.getShortcutTiddlerList = function() {
return $tw.wiki.getTiddlersWithTag("$:/tags/KeyboardShortcut");
};
KeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {
this.shortcutTiddlers = tiddlerList;
for(var i=0; i<tiddlerList.length; i++) {
var title = tiddlerList[i],
tiddlerFields = $tw.wiki.getTiddler(title).fields;
this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;
this.shortcutActionList[i] = tiddlerFields.text;
this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;
}
};
KeyboardManager.prototype.handleKeydownEvent = function(event) {
var key, action;
for(var i=0; i<this.shortcutTiddlers.length; i++) {
if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {
key = this.shortcutParsedList[i];
action = this.shortcutActionList[i];
}
}
if(key !== undefined) {
event.preventDefault();
event.stopPropagation();
$tw.rootWidget.invokeActionString(action,$tw.rootWidget);
return true;
}
return false;
};
KeyboardManager.prototype.detectNewShortcuts = function(changedTiddlers) {
var shortcutConfigTiddlers = [],
handled = false;
$tw.utils.each(this.lookupNames,function(platformDescriptor) {
var descriptorString = "$:/config/" + platformDescriptor + "/";
Object.keys(changedTiddlers).forEach(function(configTiddler) {
var configString = configTiddler.substr(0, configTiddler.lastIndexOf("/") + 1);
if(configString === descriptorString) {
shortcutConfigTiddlers.push(configTiddler);
handled = true;
}
});
});
if(handled) {
return $tw.utils.hopArray(changedTiddlers,shortcutConfigTiddlers);
} else {
return false;
}
};
KeyboardManager.prototype.handleShortcutChanges = function(changedTiddlers) {
var newList = this.getShortcutTiddlerList();
var hasChanged = $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) ? true :
($tw.utils.hopArray(changedTiddlers,newList) ? true :
(this.detectNewShortcuts(changedTiddlers))
);
// Re-cache shortcuts if something changed
if(hasChanged) {
this.updateShortcutLists(newList);
}
};
exports.KeyboardManager = KeyboardManager; exports.KeyboardManager = KeyboardManager;
})(); })();

View File

@ -87,6 +87,14 @@ exports.startup = function() {
}); });
// Kick off the keyboard manager // Kick off the keyboard manager
$tw.keyboardManager = new $tw.KeyboardManager(); $tw.keyboardManager = new $tw.KeyboardManager();
// Listen for shortcuts
if($tw.browser) {
$tw.utils.addEventListeners(document,[{
name: "keydown",
handlerObject: $tw.keyboardManager,
handlerMethod: "handleKeydownEvent"
}]);
}
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers // Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
$tw.rootWidget = new widget.widget({ $tw.rootWidget = new widget.widget({
type: "widget", type: "widget",

View File

@ -70,6 +70,12 @@ exports.startup = function() {
widgetNode.refresh(changes); widgetNode.refresh(changes);
}; };
$tw.wiki.addEventListener("change",refreshHandler); $tw.wiki.addEventListener("change",refreshHandler);
// Listen for keyboard shortcuts
$tw.utils.addEventListeners(srcDocument,[{
name: "keydown",
handlerObject: $tw.keyboardManager,
handlerMethod: "handleKeydownEvent"
}]);
srcWindow.haveInitialisedWindow = true; srcWindow.haveInitialisedWindow = true;
}); });
// Close open windows when unloading main window // Close open windows when unloading main window

View File

@ -149,6 +149,18 @@ exports.isArrayEqual = function(array1,array2) {
}); });
}; };
/*
Determine whether an array-item is an object-property
*/
exports.hopArray = function(object,array) {
for(var i=0; i<array.length; i++) {
if($tw.utils.hop(object,array[i])) {
return true;
}
}
return false;
};
/* /*
Push entries onto an array, removing them first if they already exist in the array Push entries onto an array, removing them first if they already exist in the array
array: array to modify (assumed to be free of duplicates) array: array to modify (assumed to be free of duplicates)