Page MenuHomestyx hydra

KeyboardShortcutManager.js
No OneTemporary

KeyboardShortcutManager.js

/**
* @provides phabricator-keyboard-shortcut-manager
* @requires javelin-install
* javelin-util
* javelin-stratcom
* javelin-dom
* javelin-vector
* @javelin
*/
JX.install('KeyboardShortcutManager', {
construct : function() {
this._shortcuts = [];
JX.Stratcom.listen('keypress', null, JX.bind(this, this._onkeypress));
JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkeydown));
JX.Stratcom.listen('keyup', null, JX.bind(this, this._onkeyup));
},
statics : {
_instance : null,
/**
* Some keys don't invoke keypress events in some browsers. We handle these
* on keydown instead of keypress.
*/
_downkeys : {
left: 1,
right: 1,
up: 1,
down: 1
},
getInstance : function() {
if (!JX.KeyboardShortcutManager._instance) {
JX.KeyboardShortcutManager._instance = new JX.KeyboardShortcutManager();
}
return JX.KeyboardShortcutManager._instance;
}
},
members : {
_shortcuts : null,
_focusReticle : null,
/**
* Instead of calling this directly, you should call
* KeyboardShortcut.register().
*/
addKeyboardShortcut : function(s) {
this._shortcuts.push(s);
},
getShortcutDescriptions : function() {
var desc = [];
for (var ii = 0; ii < this._shortcuts.length; ii++) {
desc.push({
keys : this._shortcuts[ii].getKeys(),
description : this._shortcuts[ii].getDescription()
});
}
return desc;
},
/**
* Scroll an element into view.
*/
scrollTo : function(node) {
var scroll_distance = JX.Vector.getAggregateScrollForNode(node);
var node_position = JX.$V(node);
JX.DOM.scrollToPosition(0, node_position.y + scroll_distance.y - 60);
},
/**
* Move the keyboard shortcut focus to an element.
*
* @param Node Node to focus, or pass null to clear the focus.
* @param Node To focus multiple nodes (like rows in a table), specify the
* top-left node as the first parameter and the bottom-right
* node as the focus extension.
* @return void
*/
focusOn : function(node, extended_node) {
this._clearReticle();
if (!node) {
return;
}
var r = JX.$N('div', {className : 'keyboard-focus-focus-reticle'});
extended_node = extended_node || node;
// Outset the reticle some pixels away from the element, so there's some
// space between the focused element and the outline.
var p = JX.Vector.getPos(node);
var s = JX.Vector.getAggregateScrollForNode(node);
p.add(s).add(-4, -4).setPos(r);
// Compute the size we need to extend to the full extent of the focused
// nodes.
JX.Vector.getPos(extended_node)
.add(-p.x, -p.y)
.add(JX.Vector.getDim(extended_node))
.add(8, 8)
.setDim(r);
JX.DOM.getContentFrame().appendChild(r);
this._focusReticle = r;
},
_clearReticle : function() {
this._focusReticle && JX.DOM.remove(this._focusReticle);
this._focusReticle = null;
},
_onkeypress : function(e) {
if (!(this._getKey(e) in JX.KeyboardShortcutManager._downkeys)) {
this._onkeyhit(e);
}
},
_onkeyhit : function(e) {
var raw = e.getRawEvent();
if (raw.altKey || raw.ctrlKey || raw.metaKey) {
// Never activate keyboard shortcuts if modifier keys are also
// depressed.
return;
}
var target = e.getTarget();
var ignore = ['input', 'select', 'textarea', 'object', 'embed'];
if (JX.DOM.isType(target, ignore)) {
// Never activate keyboard shortcuts if the user has some other control
// focused.
return;
}
var key = this._getKey(e);
var shortcuts = this._shortcuts;
for (var ii = 0; ii < shortcuts.length; ii++) {
var keys = shortcuts[ii].getKeys();
for (var jj = 0; jj < keys.length; jj++) {
if (keys[jj] == key) {
shortcuts[ii].getHandler()(this);
e.kill(); // Consume the event
return;
}
}
}
},
_onkeydown : function(e) {
this._handleTooltipKeyEvent(e, true);
if (this._getKey(e) in JX.KeyboardShortcutManager._downkeys) {
this._onkeyhit(e);
}
},
_onkeyup : function(e) {
this._handleTooltipKeyEvent(e, false);
},
_getKey : function(e) {
return e.getSpecialKey() || String.fromCharCode(e.getRawEvent().charCode);
},
_handleTooltipKeyEvent : function(e, is_keydown) {
if (e.getRawEvent().keyCode != 18) {
// If this isn't the alt/option key, don't do anything.
return;
}
// Fire all the shortcut handlers.
var shortcuts = this._shortcuts;
for (var ii = 0; ii < shortcuts.length; ii++) {
var handler = shortcuts[ii].getTooltipHandler();
handler && handler(this, is_keydown);
}
}
}
});

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 26, 8:38 PM (17 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
420278
Default Alt Text
KeyboardShortcutManager.js (4 KB)

Event Timeline