[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 /** 2 * @provides phabricator-keyboard-shortcut-manager 3 * @requires javelin-install 4 * javelin-util 5 * javelin-stratcom 6 * javelin-dom 7 * javelin-vector 8 * @javelin 9 */ 10 11 JX.install('KeyboardShortcutManager', { 12 13 construct : function() { 14 this._shortcuts = []; 15 16 JX.Stratcom.listen('keypress', null, JX.bind(this, this._onkeypress)); 17 JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkeydown)); 18 JX.Stratcom.listen('keyup', null, JX.bind(this, this._onkeyup)); 19 }, 20 21 statics : { 22 _instance : null, 23 24 /** 25 * Some keys don't invoke keypress events in some browsers. We handle these 26 * on keydown instead of keypress. 27 */ 28 _downkeys : { 29 left: 1, 30 right: 1, 31 up: 1, 32 down: 1 33 }, 34 35 getInstance : function() { 36 if (!JX.KeyboardShortcutManager._instance) { 37 JX.KeyboardShortcutManager._instance = new JX.KeyboardShortcutManager(); 38 } 39 return JX.KeyboardShortcutManager._instance; 40 } 41 }, 42 43 members : { 44 _shortcuts : null, 45 _focusReticle : null, 46 47 /** 48 * Instead of calling this directly, you should call 49 * KeyboardShortcut.register(). 50 */ 51 addKeyboardShortcut : function(s) { 52 this._shortcuts.push(s); 53 }, 54 getShortcutDescriptions : function() { 55 var desc = []; 56 for (var ii = 0; ii < this._shortcuts.length; ii++) { 57 desc.push({ 58 keys : this._shortcuts[ii].getKeys(), 59 description : this._shortcuts[ii].getDescription() 60 }); 61 } 62 return desc; 63 }, 64 65 /** 66 * Scroll an element into view. 67 */ 68 scrollTo : function(node) { 69 window.scrollTo(0, JX.$V(node).y - 60); 70 }, 71 72 /** 73 * Move the keyboard shortcut focus to an element. 74 * 75 * @param Node Node to focus, or pass null to clear the focus. 76 * @param Node To focus multiple nodes (like rows in a table), specify the 77 * top-left node as the first parameter and the bottom-right 78 * node as the focus extension. 79 * @return void 80 */ 81 focusOn : function(node, extended_node) { 82 this._clearReticle(); 83 84 if (!node) { 85 return; 86 } 87 88 var r = JX.$N('div', {className : 'keyboard-focus-focus-reticle'}); 89 90 extended_node = extended_node || node; 91 92 // Outset the reticle some pixels away from the element, so there's some 93 // space between the focused element and the outline. 94 var p = JX.Vector.getPos(node); 95 p.add(-4, -4).setPos(r); 96 // Compute the size we need to extend to the full extent of the focused 97 // nodes. 98 JX.Vector.getPos(extended_node) 99 .add(-p.x, -p.y) 100 .add(JX.Vector.getDim(extended_node)) 101 .add(8, 8) 102 .setDim(r); 103 document.body.appendChild(r); 104 105 this._focusReticle = r; 106 }, 107 108 _clearReticle : function() { 109 this._focusReticle && JX.DOM.remove(this._focusReticle); 110 this._focusReticle = null; 111 }, 112 _onkeypress : function(e) { 113 if (!(this._getKey(e) in JX.KeyboardShortcutManager._downkeys)) { 114 this._onkeyhit(e); 115 } 116 }, 117 _onkeyhit : function(e) { 118 var raw = e.getRawEvent(); 119 120 if (raw.altKey || raw.ctrlKey || raw.metaKey) { 121 // Never activate keyboard shortcuts if modifier keys are also 122 // depressed. 123 return; 124 } 125 126 var target = e.getTarget(); 127 var ignore = ['input', 'select', 'textarea', 'object', 'embed']; 128 if (JX.DOM.isType(target, ignore)) { 129 // Never activate keyboard shortcuts if the user has some other control 130 // focused. 131 return; 132 } 133 134 var key = this._getKey(e); 135 136 var shortcuts = this._shortcuts; 137 for (var ii = 0; ii < shortcuts.length; ii++) { 138 var keys = shortcuts[ii].getKeys(); 139 for (var jj = 0; jj < keys.length; jj++) { 140 if (keys[jj] == key) { 141 shortcuts[ii].getHandler()(this); 142 e.kill(); // Consume the event 143 return; 144 } 145 } 146 } 147 }, 148 _onkeydown : function(e) { 149 this._handleTooltipKeyEvent(e, true); 150 151 if (this._getKey(e) in JX.KeyboardShortcutManager._downkeys) { 152 this._onkeyhit(e); 153 } 154 }, 155 _onkeyup : function(e) { 156 this._handleTooltipKeyEvent(e, false); 157 }, 158 _getKey : function(e) { 159 return e.getSpecialKey() || String.fromCharCode(e.getRawEvent().charCode); 160 }, 161 _handleTooltipKeyEvent : function(e, is_keydown) { 162 if (e.getRawEvent().keyCode != 18) { 163 // If this isn't the alt/option key, don't do anything. 164 return; 165 } 166 // Fire all the shortcut handlers. 167 var shortcuts = this._shortcuts; 168 for (var ii = 0; ii < shortcuts.length; ii++) { 169 var handler = shortcuts[ii].getTooltipHandler(); 170 handler && handler(this, is_keydown); 171 } 172 } 173 174 } 175 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |