Issue #287 : Edit shortcuts from cheatsheet window (WIP)

This commit is contained in:
jdescottes 2015-10-11 23:51:50 +02:00
parent 2e3558ef08
commit 676cbd17ea
16 changed files with 331 additions and 178 deletions

3
src/css/animations.css Normal file
View File

@ -0,0 +1,3 @@
@keyframes fade {
50% { opacity: 0.5; }
}

View File

@ -14,6 +14,7 @@
background-image:url('../img/keyboard.png');
background-size:35px 20px;
background-repeat:no-repeat;
opacity: 0.5;
z-index: 11000;
transition : opacity 0.3s;
@ -25,68 +26,78 @@
.cheatsheet-container {
box-sizing: border-box;
-moz-box-sizing : border-box;
padding: 20px 3%;
border-radius: 3px;
background: rgba(0,0,0,0.9);
background-color: rgba(0,0,0,0.9);
overflow: auto;
}
.cheatsheet-container .cheatsheet-title {
font-size:24px;
margin-top: 0;
}
.cheatsheet-container .cheatsheet-title:nth-of-type(2) {
margin-top: 30px;
}
.cheatsheet-container .cheatsheet-title:nth-of-type(1) {
margin-top: 0;
}
.cheatsheet-section {
float: left;
width : 33%;
display: inline-block;
vertical-align: top;
padding : 0 20px;
}
.cheatsheet-shortcut {
overflow: hidden;
margin: 10px 0;
cursor : pointer;
}
.cheatsheet-icon.tool-icon {
float: left;
display: inline-block;
height: 30px;
width: 30px;
margin: 0 20px 0 0;
margin: 0 10px 0 0;
background-size: 20px 20px;
background-position: 5px 5px;
}
.cheatsheet-description {
font-family:Courier;
color: white;
font-size : 13px;
margin-left: 20px;
font-size : 14px;
margin-left: 10px;
line-height : 30px;
}
.cheatsheet-key {
box-sizing: border-box;
display : inline-block;
height: 30px;
line-height: 30px;
line-height: 26px;
padding: 0 10px;
border : 1px solid gold;
border : 2px solid gold;
border-radius: 2px;
box-sizing: border-box;
-moz-box-sizing : border-box;
text-align: center;
font-family:Courier;
font-weight: bold;
font-size : 18px;
color: gold;
}
.cheatsheet-shorcut-conflict .cheatsheet-key {
border-color: red;
color: red;
}
.cheatsheet-shortcut-editing .cheatsheet-key{
animation: fade .5s infinite;
}
.cheatsheet-shortcut-undefined .cheatsheet-key{
border-color: red;
color: red;
}

View File

@ -38,6 +38,7 @@
$('#tool-section').mousedown($.proxy(this.onToolIconClicked_, this));
$.subscribe(Events.SELECT_TOOL, this.onSelectToolEvent_.bind(this));
$.subscribe(Events.SHORTCUTS_CHANGED, this.createToolsDom_.bind(this));
};
/**

View File

@ -1,94 +1,96 @@
(function () {
var ns = $.namespace('pskl.controller.dialogs');
ns.CheatsheetController = function () {
this.shortcuts = pskl.service.keyboard.Shortcuts;
};
ns.CheatsheetController = function () {};
pskl.utils.inherit(ns.CheatsheetController, ns.AbstractDialogController);
ns.CheatsheetController.prototype.init = function () {
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
if (!this.cheatsheetEl) {
throw 'cheatsheetEl DOM element could not be retrieved';
}
this.superclass.init.call(this);
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
this.eventTrapInput = document.getElementById('cheatsheet-event-trap');
pskl.utils.Event.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_, this);
pskl.utils.Event.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_, this);
pskl.utils.Event.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_, this);
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_.bind(this));
this.initMarkup_();
};
ns.CheatsheetController.prototype.destroy = function () {
this.eventTrapInput.blur();
pskl.utils.Event.removeAllEventListeners();
this.cheatsheetEl = null;
};
ns.CheatsheetController.prototype.onRestoreDefaultsClick_ = function () {
pskl.service.keyboard.Shortcuts.restoreDefaultShortcuts();
};
ns.CheatsheetController.prototype.onShortcutsChanged_ = function () {
this.initMarkup_();
};
ns.CheatsheetController.prototype.onCheatsheetClick_ = function (evt) {
var shortcutId = pskl.utils.Dom.getData(evt.target, 'shortcutId');
if (!shortcutId) {
pskl.utils.Dom.removeClass('cheatsheet-shortcut-editing');
var shortcutEl = pskl.utils.Dom.getParentWithData(evt.target, 'shortcutId');
if (!shortcutEl) {
return;
}
shortcutEl.classList.add('cheatsheet-shortcut-editing');
this.eventTrapInput.focus();
};
ns.CheatsheetController.prototype.onEventTrapKeydown_ = function (evt) {
var editedShortcutEl = document.querySelector('.cheatsheet-shortcut-editing');
if (!editedShortcutEl) {
return;
}
var shortcutKeyObject = pskl.service.keyboard.KeyUtils.createKeyFromEvent(evt);
var shortcutKeyString = pskl.service.keyboard.KeyUtils.stringify(shortcutKeyObject);
var shortcutId = editedShortcutEl.dataset.shortcutId;
var shortcut = pskl.service.keyboard.Shortcuts.getShortcutById(shortcutId);
var newKeys = window.prompt('Please enter the new key', shortcut.getKeys().join(', '));
shortcut.updateKeys(newKeys);
pskl.service.keyboard.Shortcuts.updateShortcut(shortcut, shortcutKeyString);
this.eventTrapInput.blur();
evt.preventDefault();
};
ns.CheatsheetController.prototype.initMarkup_ = function () {
this.initMarkupForTools_();
this.initMarkupForMisc_();
this.initMarkupForColors_();
this.initMarkupForSelection_();
this.initMarkupForCategory_('TOOL', '.cheatsheet-tool-shortcuts', this.getToolIconClass_);
this.initMarkupForCategory_('MISC', '.cheatsheet-misc-shortcuts');
this.initMarkupForCategory_('COLOR', '.cheatsheet-color-shortcuts');
this.initMarkupForCategory_('SELECTION', '.cheatsheet-selection-shortcuts');
this.initMarkupForCategory_('STORAGE', '.cheatsheet-storage-shortcuts');
};
ns.CheatsheetController.prototype.initMarkupForTools_ = function () {
var descriptors = this.createShortcutDescriptors_(this.shortcuts.TOOL, this.getToolShortcutClassname_);
this.initMarkupForDescriptors_(descriptors, '.cheatsheet-tool-shortcuts');
};
ns.CheatsheetController.prototype.getToolShortcutClassname_ = function (shortcut) {
ns.CheatsheetController.prototype.getToolIconClass_ = function (shortcut) {
return 'tool-icon ' + shortcut.getId();
};
ns.CheatsheetController.prototype.initMarkupForMisc_ = function () {
var descriptors = this.createShortcutDescriptors_(this.shortcuts.MISC);
this.initMarkupForDescriptors_(descriptors, '.cheatsheet-misc-shortcuts');
};
ns.CheatsheetController.prototype.initMarkupForCategory_ = function (category, container, iconClassProvider) {
var shortcutMap = pskl.service.keyboard.Shortcuts[category];
ns.CheatsheetController.prototype.initMarkupForColors_ = function () {
var descriptors = this.createShortcutDescriptors_(this.shortcuts.COLOR);
this.initMarkupForDescriptors_(descriptors, '.cheatsheet-colors-shortcuts');
};
ns.CheatsheetController.prototype.initMarkupForSelection_ = function () {
var descriptors = this.createShortcutDescriptors_(this.shortcuts.SELECTION);
this.initMarkupForDescriptors_(descriptors, '.cheatsheet-selection-shortcuts');
};
ns.CheatsheetController.prototype.createShortcutDescriptors_ = function (shortcutMap, classnameProvider) {
return Object.keys(shortcutMap).map(function (shortcutKey) {
var shortcut = shortcutMap[shortcutKey];
var classname = typeof classnameProvider == 'function' ? classnameProvider(shortcut) : '';
return this.toDescriptor_(shortcut, classname);
var descriptors = Object.keys(shortcutMap).map(function (shortcutKey) {
return this.toDescriptor_(shortcutMap[shortcutKey], iconClassProvider);
}.bind(this));
this.initMarkupForDescriptors_(descriptors, container);
};
ns.CheatsheetController.prototype.toDescriptor_ = function (shortcut, icon) {
var key = shortcut.getKey();
if (pskl.utils.UserAgent.isMac) {
key = key.replace('ctrl', 'cmd');
}
key = key.replace('up', '↑');
key = key.replace('down', '↓');
key = key.replace(/>/g, '>');
key = key.replace(/</g, '&lt;');
key = key.replace(/^(.*[^ ])\+([^ ].*)$/g, '$1 + $2');
ns.CheatsheetController.prototype.toDescriptor_ = function (shortcut, iconClassProvider) {
var iconClass = typeof iconClassProvider == 'function' ? iconClassProvider(shortcut) : '';
return {
'key' : key,
'id' : shortcut.getId(),
'description' : shortcut.getDescription(),
'icon' : icon
'shortcut' : shortcut,
'iconClass' : iconClass
};
};
@ -97,19 +99,37 @@
if (!container) {
return;
}
var markupArray = descriptors.map(this.getMarkupForDescriptor_);
var markupArray = descriptors.map(this.getMarkupForDescriptor_.bind(this));
container.innerHTML = markupArray.join('');
};
ns.CheatsheetController.prototype.getMarkupForDescriptor_ = function (descriptor) {
var shortcutTemplate = pskl.utils.Template.get('cheatsheet-shortcut-template');
var shortcut = descriptor.shortcut;
var description = shortcut.isCustom() ? shortcut.getDescription() + ' *' : shortcut.getDescription();
var shortcutClass = shortcut.isUndefined() ? 'cheatsheet-shortcut-undefined' : '';
var markup = pskl.utils.Template.replace(shortcutTemplate, {
shortcutId : descriptor.id,
shortcutIcon : descriptor.icon,
shortcutDescription : descriptor.description,
shortcutKey : descriptor.key
shortcutId : shortcut.getId(),
shortcutIcon : descriptor.iconClass,
shortcutDescription : description,
shortcutKey : this.formatKey_(shortcut.getDisplayKey()),
shortcutClass : shortcutClass
});
return markup;
};
ns.CheatsheetController.prototype.formatKey_ = function (key) {
if (pskl.utils.UserAgent.isMac) {
key = key.replace('ctrl', 'cmd');
}
key = key.replace(/up/i, '&#65514;');
key = key.replace(/down/i, '&#65516;');
key = key.replace(/>/g, '&gt;');
key = key.replace(/</g, '&lt;');
// add spaces around '+' delimiters
key = key.replace(/([^ ])\+([^ ])/g, '$1 + $2');
return key;
};
})();

View File

@ -129,7 +129,7 @@
}
event.preventDefault = function () {};
pskl.app.shortcutService.onKeyUp_(event);
pskl.app.shortcutService.onKeyDown_(event);
};
ns.DrawingTestPlayer.prototype.playColorEvent_ = function (recordEvent) {

View File

@ -0,0 +1,80 @@
(function () {
var ns = $.namespace('pskl.service.keyboard');
ns.KeyUtils = {
createKeyFromString : function (shortcutKeyString) {
shortcutKeyString = shortcutKeyString.toLowerCase();
var modifiers = {
alt : shortcutKeyString.indexOf('alt+') != -1,
shift : shortcutKeyString.indexOf('shift+') != -1,
ctrl : shortcutKeyString.indexOf('ctrl+') != -1
};
var parts = shortcutKeyString.split(/\+(?!$)/);
var key = parts[parts.length - 1];
return {
key : key.toUpperCase(),
modifiers : modifiers
};
},
createKeyFromEvent : function (evt) {
var keycode = evt.which;
var key = ns.KeycodeTranslator.toChar(keycode);
if (!key) {
return null;
}
return {
key : key.toUpperCase(),
modifiers : {
alt : evt.altKey,
shift : evt.shiftKey,
ctrl : ns.KeyUtils.isCtrlKeyPressed_(evt)
}
};
},
equals : function (key1, key2) {
key1 = typeof key1 === 'string' ? ns.KeyUtils.createKeyFromString(key1) : key1;
key2 = typeof key2 === 'string' ? ns.KeyUtils.createKeyFromString(key2) : key2;
var isKeyMatching = key1.key === key2.key &&
key1.modifiers.alt === key2.modifiers.alt &&
key1.modifiers.shift === key2.modifiers.shift &&
key1.modifiers.ctrl === key2.modifiers.ctrl;
return isKeyMatching;
},
stringify : function (shortcutKeyObject) {
var modifierString = ns.KeyUtils.getModifiersString(shortcutKeyObject.modifiers);
if (modifierString) {
return modifierString + '+' + shortcutKeyObject.key;
}
return shortcutKeyObject.key;
},
getModifiersString : function (modifiers) {
var keyBuffer = [];
if (modifiers.alt) {
keyBuffer.push('alt');
}
if (modifiers.ctrl) {
keyBuffer.push('ctrl');
}
if (modifiers.shift) {
keyBuffer.push('shift');
}
return keyBuffer.join('+');
},
isCtrlKeyPressed_ : function (evt) {
return pskl.utils.UserAgent.isMac ? evt.metaKey : evt.ctrlKey;
}
};
})();

View File

@ -6,14 +6,17 @@
*
* @param {String} id Shortcut identifier
* @param {String} description Shortcut description
* @param {String|Array<String>} defaultKey combination of modifiers + ([a-z0-9] or a special key)
* @param {String|Array<String>} defaultKeys combination of modifiers + ([a-z0-9] or a special key)
* Special keys are defined in KeycodeTranslator. If the shortcut supports several keys,
* use an array of String keys
*/
ns.Shortcut = function (id, description, defaultKey, displayKey) {
ns.Shortcut = function (id, description, defaultKeys, displayKey) {
this.id_ = id;
this.description_ = description;
this.defaultKey_ = defaultKey;
if (typeof defaultKeys === 'string') {
defaultKeys = [defaultKeys];
}
this.defaultKeys_ = defaultKeys;
this.displayKey_ = displayKey;
};
@ -32,34 +35,75 @@
* @return {Array<String>} array of keys
*/
ns.Shortcut.prototype.getKeys = function () {
var keys = pskl.UserSettings.get(this.getLocalStorageKey_()) || this.defaultKey_;
var keys = pskl.UserSettings.get(this.getLocalStorageKey_()) || this.defaultKeys_;
if (typeof keys === 'string') {
keys = [keys];
return [keys];
}
if (!Array.isArray(keys)) {
return [];
}
return keys;
};
ns.Shortcut.prototype.isCustom = function () {
var keys = this.getKeys();
if (keys.length !== this.defaultKeys_.length) {
return true;
}
// for some default keys
return this.defaultKeys_.some(function (defaultKey) {
// no match can be found in the current keys
return !keys.some(function (key) {
return ns.KeyUtils.equals(key, defaultKey);
});
});
};
ns.Shortcut.prototype.isUndefined = function () {
return this.getKeys().length === 0;
};
/**
* Get the key to be displayed for this shortcut, if
* @return {[type]} [description]
*/
ns.Shortcut.prototype.getKey = function () {
ns.Shortcut.prototype.getDisplayKey = function () {
if (this.isUndefined()) {
return '???';
}
if (this.displayKey_) {
return this.displayKey_;
}
var keys = this.getKeys();
if (Array.isArray(keys) && keys.length > 0) {
return keys[0];
}
return this.getKeys()[0];
};
return '';
ns.Shortcut.prototype.restoreDefault = function (keys) {
pskl.UserSettings.set(this.getLocalStorageKey_(), '');
};
ns.Shortcut.prototype.updateKeys = function (keys) {
pskl.UserSettings.set(this.getLocalStorageKey_(), keys.split(', '));
$.publish(Events.SHORTCUTS_CHANGED);
pskl.UserSettings.set(this.getLocalStorageKey_(), keys);
};
ns.Shortcut.prototype.removeKeys = function (keysToRemove) {
var keys = this.getKeys();
var updatedKeys = keys.filter(function (key) {
return !keysToRemove.some(function (keyToRemove) {
return ns.KeyUtils.equals(key, keyToRemove);
});
});
if (updatedKeys.length !== keys.length) {
this.updateKeys(updatedKeys);
return true;
}
return false;
};
ns.Shortcut.prototype.getLocalStorageKey_ = function () {

View File

@ -9,7 +9,7 @@
* @public
*/
ns.ShortcutService.prototype.init = function() {
$(document.body).keydown($.proxy(this.onKeyUp_, this));
$(document.body).keydown($.proxy(this.onKeyDown_, this));
};
/**
@ -44,61 +44,22 @@
}
};
ns.ShortcutService.prototype.parseKey_ = function (key) {
var meta = this.getMetaKey_({
alt : key.indexOf('alt+') != -1,
shift : key.indexOf('shift+') != -1,
ctrl : key.indexOf('ctrl+') != -1
});
var parts = key.split(/\+(?!$)/);
key = parts[parts.length - 1];
return {meta : meta, key : key.toLowerCase()};
};
/**
* Retrieve a comparable representation of a meta information for a key
* 'alt' 'ctrl' and 'shift' will always be in the same order for the same meta
*/
ns.ShortcutService.prototype.getMetaKey_ = function (meta) {
var keyBuffer = [];
if (meta.alt) {
keyBuffer.push('alt');
}
if (meta.ctrl) {
keyBuffer.push('ctrl');
}
if (meta.shift) {
keyBuffer.push('shift');
}
return keyBuffer.join('+') || 'normal';
};
/**
* @private
*/
ns.ShortcutService.prototype.onKeyUp_ = function(evt) {
if (this.isInInput_(evt)) {
ns.ShortcutService.prototype.onKeyDown_ = function(evt) {
var eventKey = ns.KeyUtils.createKeyFromEvent(evt);
if (this.isInInput_(evt) || !eventKey) {
return;
}
var keycode = evt.which;
var eventKey = pskl.service.keyboard.KeycodeTranslator.toChar(keycode);
var eventMeta = this.getMetaKey_({
alt : evt.altKey,
shift : evt.shiftKey,
ctrl : this.isCtrlKeyPressed_(evt)
});
this.shortcuts_.forEach(function (shortcutInfo) {
shortcutInfo.shortcut.getKeys().forEach(function (key) {
if (!this.isKeyMatching_(key, eventKey, eventMeta)) {
shortcutInfo.shortcut.getKeys().forEach(function (shortcutKey) {
if (!ns.KeyUtils.equals(shortcutKey, eventKey)) {
return;
}
var bubble = shortcutInfo.callback(eventKey);
var bubble = shortcutInfo.callback(eventKey.key);
if (bubble !== true) {
evt.preventDefault();
}
@ -111,13 +72,4 @@
var targetTagName = evt.target.nodeName.toUpperCase();
return targetTagName === 'INPUT' || targetTagName === 'TEXTAREA';
};
ns.ShortcutService.prototype.isKeyMatching_ = function (key, eventKey, eventMeta) {
var parsedKey = this.parseKey_(key);
return parsedKey.key === eventKey && parsedKey.meta === eventMeta;
};
ns.ShortcutService.prototype.isCtrlKeyPressed_ = function (evt) {
return pskl.utils.UserAgent.isMac ? evt.metaKey : evt.ctrlKey;
};
})();

View File

@ -30,7 +30,7 @@
SELECTION : {
CUT : createShortcut('selection-cut', 'Cut selection', 'ctrl+X'),
COPY : createShortcut('selection-copy', 'Copy selection', 'ctrl+C'),
PASTE : createShortcut('selection-cut', 'Paste selection', 'ctrl+V'),
PASTE : createShortcut('selection-paste', 'Paste selection', 'ctrl+V'),
DELETE : createShortcut('selection-delete', 'Delete selection', ['del', 'back'])
},
@ -52,9 +52,9 @@
},
STORAGE : {
OPEN : createShortcut('open', '(Desktop only) Open a .piskel file', 'ctrl+O'),
SAVE : createShortcut('save', 'Save the current sprite', 'ctrl+S'),
SAVE_AS : createShortcut('save-as', '(Desktop only) Save as a new .piskel file', 'ctrl+shift+S')
OPEN : createShortcut('open', '(desktop) Open a .piskel file', 'ctrl+O'),
SAVE_AS : createShortcut('save-as', '(desktop) Save as new', 'ctrl+shift+S')
},
COLOR : {
@ -70,18 +70,43 @@
CATEGORIES : ['TOOL', 'SELECTION', 'MISC', 'STORAGE', 'COLOR'],
getShortcutById : function (id) {
var shortcut = null;
return pskl.utils.Array.find(ns.Shortcuts.getShortcuts(), function (shortcut) {
return shortcut.getId() === id;
});
},
getShortcuts : function () {
var shortcuts = [];
ns.Shortcuts.CATEGORIES.forEach(function (category) {
var shortcuts = ns.Shortcuts[category];
Object.keys(shortcuts).forEach(function (shortcutKey) {
if (shortcuts[shortcutKey].getId() === id) {
shortcut = shortcuts[shortcutKey];
}
var shortcutMap = ns.Shortcuts[category];
Object.keys(shortcutMap).forEach(function (shortcutKey) {
shortcuts.push(shortcutMap[shortcutKey]);
});
});
return shortcuts;
},
return shortcut;
updateShortcut : function (shortcut, keysString) {
keysString = keysString.replace(/\s/g, '');
var keys = keysString.split(',');
ns.Shortcuts.getShortcuts().forEach(function (s) {
if (s === shortcut) {
return;
}
if (s.removeKeys(keys)) {
$.publish(Events.SHOW_NOTIFICATION, [{'content': 'Shortcut key removed for ' + s.getId()}]);
}
});
shortcut.updateKeys(keys);
$.publish(Events.SHORTCUTS_CHANGED);
},
restoreDefaultShortcuts : function () {
ns.Shortcuts.getShortcuts().forEach(function (shortcut) {
shortcut.restoreDefault();
});
$.publish(Events.SHORTCUTS_CHANGED);
}
};
})();

View File

@ -41,6 +41,14 @@
if (parent !== null) {
return parent.dataset[dataName];
}
},
removeClass : function (className, container) {
container = container || document;
var elements = container.querySelectorAll('.' + className);
for (var i = 0 ; i < elements.length ; i++) {
elements[i].classList.remove(className);
}
}
};
})();

View File

@ -5,7 +5,7 @@
ns.TooltipFormatter.format = function(helpText, shortcut, descriptors) {
var tpl = pskl.utils.Template.get('tooltip-container-template');
shortcut = shortcut ? '(' + shortcut.getKey() + ')' : '';
shortcut = shortcut ? '(' + shortcut.getDisplayKey() + ')' : '';
return pskl.utils.Template.replace(tpl, {
helptext : helpText,
shortcut : shortcut,

View File

@ -28,8 +28,8 @@
"js/utils/FileUtils.js",
"js/utils/FileUtilsDesktop.js",
"js/utils/FrameUtils.js",
"js/utils/LayerUtils.js",
"js/utils/ImageResizer.js",
"js/utils/LayerUtils.js",
"js/utils/PixelUtils.js",
"js/utils/PiskelFileUtils.js",
"js/utils/Template.js",
@ -158,10 +158,11 @@
"js/service/palette/reader/PaletteTxtReader.js",
"js/service/palette/PaletteImportService.js",
"js/service/SavedStatusService.js",
"js/service/keyboard/KeycodeTranslator.js",
"js/service/keyboard/KeyUtils.js",
"js/service/keyboard/Shortcut.js",
"js/service/keyboard/Shortcuts.js",
"js/service/keyboard/ShortcutService.js",
"js/service/keyboard/KeycodeTranslator.js",
"js/service/ImageUploadService.js",
"js/service/CurrentColorsService.js",
"js/service/FileDropperService.js",

View File

@ -3,6 +3,7 @@
(typeof exports != "undefined" ? exports : pskl_exports).styles = [
"css/reset.css",
"css/style.css",
"css/animations.css",
"css/layout.css",
"css/font-icon.css",
"css/forms.css",

View File

@ -16,12 +16,20 @@
<h3 class="cheatsheet-title">Selection shortcuts</h3>
<ul class="cheatsheet-selection-shortcuts"></ul>
<h3 class="cheatsheet-title">Color shortcuts</h3>
<ul class="cheatsheet-colors-shortcuts"></ul>
<ul class="cheatsheet-color-shortcuts"></ul>
<h3 class="cheatsheet-title">Storage shortcuts</h3>
<ul class="cheatsheet-storage-shortcuts"></ul>
</div>
<div class="cheatsheet-actions">
<button type="button" name="cheatsheet-restore-defaults" data-action="restore-defaults" class="button cheatsheet-restore-defaults">Restore default shortcuts</button>
</div>
<div style="position:relative;overflow:hidden; width:1px; height:1px">
<input type="text" id="cheatsheet-event-trap" style="position:absolute; top:-1000px;" />
</div>
</div>
</div>
<script type="text/template" id="cheatsheet-shortcut-template">
<li class="cheatsheet-shortcut" data-shortcut-id="{{shortcutId}}">
<li class="cheatsheet-shortcut {{shortcutClass}}" data-shortcut-id="{{shortcutId}}">
<div class="cheatsheet-icon {{shortcutIcon}}"></div>
<span class="cheatsheet-key">{{shortcutKey}}</span>
<span class="cheatsheet-description">{{shortcutDescription}}</span>

View File

@ -94,7 +94,7 @@ describe("ShortcutService test suite", function() {
});
console.log('[ShortcutService] ... verify shortcut is called');
service.onKeyUp_(createEvent(A_KEYCODE));
service.onKeyDown_(createEvent(A_KEYCODE));
expect(callbackCalled).toBe(true);
});
@ -123,13 +123,13 @@ describe("ShortcutService test suite", function() {
});
console.log('[ShortcutService] ... trigger A, expect counter A at 1, B at 0, A_B at 1');
service.onKeyUp_(createEvent(A_KEYCODE));
service.onKeyDown_(createEvent(A_KEYCODE));
expect(counters.a).toBe(1);
expect(counters.b).toBe(0);
expect(counters.a_b).toBe(1);
console.log('[ShortcutService] ... trigger A, expect counter A at 1, B at 1, A_B at 2');
service.onKeyUp_(createEvent(B_KEYCODE));
service.onKeyDown_(createEvent(B_KEYCODE));
expect(counters.a).toBe(1);
expect(counters.b).toBe(1);
expect(counters.a_b).toBe(2);
@ -149,7 +149,7 @@ describe("ShortcutService test suite", function() {
service.unregisterShortcut(shortcutA);
console.log('[ShortcutService] ... verify shortcut callback is not called');
service.onKeyUp_(createEvent(A_KEYCODE));
service.onKeyDown_(createEvent(A_KEYCODE));
expect(callbackCalled).toBe(false);
});
@ -169,7 +169,7 @@ describe("ShortcutService test suite", function() {
service.unregisterShortcut(shortcutA);
console.log('[ShortcutService] ... verify shortcut callback for B can still be called');
service.onKeyUp_(createEvent(B_KEYCODE));
service.onKeyDown_(createEvent(B_KEYCODE));
expect(callbackCalled).toBe(true);
});
@ -189,7 +189,7 @@ describe("ShortcutService test suite", function() {
console.log('[ShortcutService] ... verify shortcut callback for A can still be called');
callbackCalled = false;
service.onKeyUp_(createEvent(A_KEYCODE));
service.onKeyDown_(createEvent(A_KEYCODE));
expect(callbackCalled).toBe(true);
});
@ -204,15 +204,15 @@ describe("ShortcutService test suite", function() {
});
console.log('[ShortcutService] ... verify shortcut is not called from event on INPUT');
service.onKeyUp_(createEvent(A_KEYCODE).setNodeName('INPUT'));
service.onKeyDown_(createEvent(A_KEYCODE).setNodeName('INPUT'));
expect(callbackCalled).toBe(false);
console.log('[ShortcutService] ... verify shortcut is not called from event on TEXTAREA');
service.onKeyUp_(createEvent(A_KEYCODE).setNodeName('TEXTAREA'));
service.onKeyDown_(createEvent(A_KEYCODE).setNodeName('TEXTAREA'));
expect(callbackCalled).toBe(false);
console.log('[ShortcutService] ... verify shortcut is called from event on LINK');
service.onKeyUp_(createEvent(A_KEYCODE).setNodeName('A'));
service.onKeyDown_(createEvent(A_KEYCODE).setNodeName('A'));
expect(callbackCalled).toBe(true);
});
@ -252,23 +252,23 @@ describe("ShortcutService test suite", function() {
};
console.log('[ShortcutService] ... trigger A, expect counters CTRL+A, CTRL+SHIFT+A, CTRL+SHIFT+ALT+A, ALT+A to remain at 0');
service.onKeyUp_(createEvent(A_KEYCODE));
service.onKeyDown_(createEvent(A_KEYCODE));
verifyCounters(1,0,0,0,0);
console.log('[ShortcutService] ... trigger CTRL+A, expect counters CTRL+SHIFT+A, CTRL+SHIFT+ALT+A, ALT+A to remain at 0');
service.onKeyUp_(createEvent(A_KEYCODE).withCtrlKey());
service.onKeyDown_(createEvent(A_KEYCODE).withCtrlKey());
verifyCounters(1,1,0,0,0);
console.log('[ShortcutService] ... trigger CTRL+A, expect counters CTRL+SHIFT+ALT+A, ALT+A to remain at 0');
service.onKeyUp_(createEvent(A_KEYCODE).withCtrlKey().withShiftKey());
service.onKeyDown_(createEvent(A_KEYCODE).withCtrlKey().withShiftKey());
verifyCounters(1,1,1,0,0);
console.log('[ShortcutService] ... trigger CTRL+A, expect counter ALT+A to remain at 0');
service.onKeyUp_(createEvent(A_KEYCODE).withCtrlKey().withShiftKey().withAltKey());
service.onKeyDown_(createEvent(A_KEYCODE).withCtrlKey().withShiftKey().withAltKey());
verifyCounters(1,1,1,1,0);
console.log('[ShortcutService] ... trigger CTRL+A, expect all counters at 1');
service.onKeyUp_(createEvent(A_KEYCODE).withAltKey());
service.onKeyDown_(createEvent(A_KEYCODE).withAltKey());
verifyCounters(1,1,1,1,1);
});