adds keyboard shortcuts menu

I'm not set on the keybinding or the aesthetics of this. please change
them at will. The main goal here is to provide some method to list all
the keyboard shortcuts dynamically. I mean that when new shortcuts are
added they should automatically be put into this menu without anyone
writing any extra code. The menu provides a way for end users to easily
discover the many built in functions accessible through the keyboard.

Admittedly the current keybinding to display this menu is not very
convenient or easily guessed. I like the way that the textarea version
of ace presents a single clickable corner that is easily identified by
users. It would be cool to make this pretty and obvious.
This commit is contained in:
Matthew Kastor 2013-03-29 20:17:44 -04:00 committed by nightwing
commit d4f4758b17
2 changed files with 110 additions and 1 deletions

View file

@ -43,7 +43,7 @@ function bindKey(win, mac) {
exports.commands = [{
name: "showSettingsMenu",
bindKey: bindKey("Ctrl-q", "Command-q"),
bindKey: bindKey("Ctrl-,", "Command-,"),
exec: function (editor) {
config.loadModule("ace/ext/show_settings_menu", function (e) {
e(editor);

View file

@ -0,0 +1,109 @@
/*jslint
indent: 4,
maxerr: 50,
white: true,
browser: true,
vars: true
*/
/*global
define,
getComputedStyle
*/
define(function(require, exports, module) {
"use strict";
// this function makes an ugly div to display the contentElement
var overlayPage = function (contentElement, top, right, bottom, left) {
"use strict";
var div = document.createElement('div');
var contentContainer = document.createElement('div');
contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' +
'overflow: auto;';
contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;';
contentContainer.appendChild(contentElement);
var cl = document.createElement('img');
if (top) {
top = 'top: ' + top + ';';
} else {
top = '';
}
if (right) {
right = 'right: ' + right + ';';
} else {
right = '';
}
if (bottom) {
bottom = 'bottom: ' + bottom + ';';
} else {
bottom = '';
}
if (left) {
left = 'left: ' + left + ';';
} else {
left = '';
}
cl.src = '/BigRedX.png';
cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' +
'float: right; width: 25px; height: 25px; border: 1px solid black;';
div.style.cssText = 'margin:0; padding:0; position: absolute;' +
top + right + bottom + left +
'z-index:9999; background-color:white; color:black; overflow: auto;';
div.appendChild(cl);
div.appendChild(contentContainer);
document.body.appendChild(div);
cl.addEventListener('click', function (e) {
div.parentNode.removeChild(div);
div = null;
});
};
// this function grabs all of the editor commands that have keyboard shortcuts
function aceGetKeybordShortcuts (editor) {
"use strict";
var commands = editor.commands.byName;
var commandName;
var key;
var platform = editor.commands.platform;
var kb = [];
for (commandName in commands) {
try {
key = commands[commandName].bindKey[platform];
if (key) {
kb.push({
'command' : commandName,
'key' : key
});
}
} catch (e) {
// errors on properties without bindKey we don't want them
// so the errors don't need handling.
}
}
return kb;
}
// this function takes the keyboard shortcuts array and
// runs it through some template.
module.exports = function (editor) {
var kb = aceGetKeybordShortcuts(editor);
var el = document.createElement('div');
// untested. something like this could . . .
// var template = '<h1>Keyboard Shortcuts</h1><div>' +
// {{#kb}}
// {{{command}}} : {{{key}}}
// {{/kb}}
// '</div>';
// mustache.render({'kb' : kb}, template);
el.innerHTML = '<h1>Keyboard Shortcuts</h1><div>' +
JSON.stringify(kb, null, ' ') +
'</div>';
el.style.cssText = 'margin:0; padding:0; ' +
'background-color:white; color:black; ' +
'white-space: pre-wrap;';
overlayPage(el, '0', '0', '0', null);
}
});