Add experimental keyboard shortcut widget

It’s not cool that we have to use a separate keyboard widget for each
keyboard shortcut.

Fixes #386
print-window-tiddler
Jermolene 2014-01-30 13:40:36 +00:00
rodzic 9acb10f781
commit e3a05625b2
3 zmienionych plików z 154 dodań i 1 usunięć

Wyświetl plik

@ -0,0 +1,60 @@
/*\
title: $:/core/modules/utils/dom/keyboard.js
type: application/javascript
module-type: utils
Keyboard utilities
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var namedKeys = {
"backspace": 8,
"tab": 9,
"enter": 13,
"escape": 27
};
/*
Parses a key descriptor into the structure:
{
keyCode: numeric keycode
shiftKey: boolean
altKey: boolean
ctrlKey: boolean
}
Key descriptors have the following format:
ctrl+enter
ctrl+A
*/
exports.parseKeyDescriptor = function(keyDescriptor) {
var components = keyDescriptor.split("+"),
info = {
keyCode: 0,
shiftKey: false,
altKey: false,
ctrlKey: false
};
for(var t=0; t<components.length; t++) {
var s = components[t].toLowerCase();
// Look for modifier keys
if(s === "ctrl") {
info.ctrlKey = true;
} else if(s === "shift") {
info.shiftKey = true;
} else if(s === "alt") {
info.altKey = true;
}
// Replace named keys with their code
if(namedKeys[s]) {
info.keyCode = namedKeys[s];
}
}
return info;
};
})();

Wyświetl plik

@ -0,0 +1,93 @@
/*\
title: $:/core/modules/widgets/keyboard.js
type: application/javascript
module-type: widget
Keyboard shortcut widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var KeyboardWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
KeyboardWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
KeyboardWidget.prototype.render = function(parent,nextSibling) {
var self = this;
// Remember parent
this.parentDomNode = parent;
// Compute attributes and execute state
this.computeAttributes();
this.execute();
// Create element
var domNode = this.document.createElement("div");
// Assign classes
var classes = (this["class"] || "").split(" ");
classes.push("tw-keyboard");
domNode.className = classes.join(" ");
// Add a keyboard event handler
domNode.addEventListener("keydown",function (event) {
if(event.keyCode === self.keyInfo.keyCode &&
event.shiftKey === self.keyInfo.shiftKey &&
event.altKey === self.keyInfo.altKey &&
event.ctrlKey === self.keyInfo.ctrlKey) {
self.dispatchMessage(event);
event.preventDefault();
event.stopPropagation();
return true;
}
return false;
},false);
// Insert element
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
KeyboardWidget.prototype.dispatchMessage = function(event) {
this.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable("currentTiddler")});
};
/*
Compute the internal state of the widget
*/
KeyboardWidget.prototype.execute = function() {
// Get attributes
this.message = this.getAttribute("message");
this.param = this.getAttribute("param");
this.key = this.getAttribute("key");
this.keyInfo = $tw.utils.parseKeyDescriptor(this.key);
this["class"] = this.getAttribute("class");
// Make child widgets
this.makeChildWidgets();
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
KeyboardWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes["class"]) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports.keyboard = KeyboardWidget;
})();

Wyświetl plik

@ -3,4 +3,4 @@ title: $:/core/ui/EditTemplate
\define frame-classes()
tw-tiddler-frame tw-tiddler-edit-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$
\end
<$set name="storyTiddler" value=<<currentTiddler>>><div class=<<frame-classes>>><$list filter="[is[shadow]!has[draft.of]tag[$:/tags/EditTemplate]] [!is[shadow]!has[draft.of]tag[$:/tags/EditTemplate]] +[tag[$:/tags/EditTemplate]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list></div></$set>
<$set name="storyTiddler" value=<<currentTiddler>>><div class=<<frame-classes>>><$keyboard key="escape" message="tw-cancel-tiddler"><$keyboard key="ctrl+enter" message="tw-save-tiddler"><$list filter="[is[shadow]!has[draft.of]tag[$:/tags/EditTemplate]] [!is[shadow]!has[draft.of]tag[$:/tags/EditTemplate]] +[tag[$:/tags/EditTemplate]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list></$keyboard></$keyboard></div></$set>