@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Move keyboard focus reticle code to Differential

Summary:
Ref T12634. Using keyboard shortcuts in Differential currently relies on focus behavior in `KeyboardShortcutManager`.

This possibly made sense long ago, but no longer does, and leads to a whole slew of bugs where the reticle doesn't interact properly with anything else.

Move it to Differential so it can be made reasonably aware of edit operations, Quicksand navigation, etc.

This just moves the code; future diffs will actually fix bugs.

Test Plan: Used "n", "j", etc., saw the same behavior as before.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12634

Differential Revision: https://secure.phabricator.com/D17899

+49 -56
+49 -13
webroot/rsrc/js/application/diff/DiffChangesetList.js
··· 60 60 _changesets: null, 61 61 62 62 _cursorItem: null, 63 - _lastKeyboardManager: null, 63 + 64 + _focusNode: null, 65 + _focusStart: null, 66 + _focusEnd: null, 64 67 65 68 sleep: function() { 66 69 this._asleep = true; ··· 198 201 if (cursor.type == 'comment') { 199 202 var inline = cursor.inline; 200 203 if (inline.canReply()) { 201 - manager.focusOn(null); 204 + this.setFocus(null); 202 205 203 206 inline.reply(); 204 207 return; ··· 217 220 if (cursor.type == 'comment') { 218 221 var inline = cursor.inline; 219 222 if (inline.canEdit()) { 220 - manager.focusOn(null); 223 + this.setFocus(null); 221 224 222 225 inline.edit(); 223 226 return; ··· 310 313 }, 311 314 312 315 _redrawSelection: function(manager, scroll) { 313 - manager = manager || this._lastKeyboardManager; 314 - this._lastKeyboardManager = manager; 315 - 316 - if (this.isAsleep()) { 317 - manager.focusOn(null); 318 - return; 319 - } 320 - 321 316 var cursor = this._cursorItem; 322 317 if (!cursor) { 323 - manager.focusOn(null); 318 + this.setFocus(null); 324 319 return; 325 320 } 326 321 327 - manager.focusOn(cursor.nodes.begin, cursor.nodes.end); 322 + this.setFocus(cursor.nodes.begin, cursor.nodes.end); 328 323 329 324 if (scroll) { 330 325 manager.scrollTo(cursor.nodes.begin); ··· 642 637 if (forms.length) { 643 638 JX.DOM.invoke(forms[0], 'shouldRefresh'); 644 639 } 640 + }, 641 + 642 + setFocus: function(node, extended_node) { 643 + this._focusStart = node; 644 + this._focusEnd = extended_node; 645 + this._redrawFocus(); 646 + }, 647 + 648 + _redrawFocus: function() { 649 + var node = this._focusStart; 650 + var extended_node = this._focusEnd || node; 651 + 652 + var reticle = this._getFocusNode(); 653 + if (!node) { 654 + JX.DOM.remove(reticle); 655 + return; 656 + } 657 + 658 + // Outset the reticle some pixels away from the element, so there's some 659 + // space between the focused element and the outline. 660 + var p = JX.Vector.getPos(node); 661 + var s = JX.Vector.getAggregateScrollForNode(node); 662 + 663 + p.add(s).add(-4, -4).setPos(reticle); 664 + // Compute the size we need to extend to the full extent of the focused 665 + // nodes. 666 + JX.Vector.getPos(extended_node) 667 + .add(-p.x, -p.y) 668 + .add(JX.Vector.getDim(extended_node)) 669 + .add(8, 8) 670 + .setDim(reticle); 671 + 672 + JX.DOM.getContentFrame().appendChild(reticle); 673 + }, 674 + 675 + _getFocusNode: function() { 676 + if (!this._focusNode) { 677 + var node = JX.$N('div', {className : 'keyboard-focus-focus-reticle'}); 678 + this._focusNode = node; 679 + } 680 + return this._focusNode; 645 681 }, 646 682 647 683 _deleteInlineByID: function(id) {
-43
webroot/rsrc/js/core/KeyboardShortcutManager.js
··· 54 54 55 55 members : { 56 56 _shortcuts : null, 57 - _focusReticle : null, 58 57 59 58 /** 60 59 * Instead of calling this directly, you should call ··· 83 82 JX.DOM.scrollToPosition(0, node_position.y + scroll_distance.y - 60); 84 83 }, 85 84 86 - /** 87 - * Move the keyboard shortcut focus to an element. 88 - * 89 - * @param Node Node to focus, or pass null to clear the focus. 90 - * @param Node To focus multiple nodes (like rows in a table), specify the 91 - * top-left node as the first parameter and the bottom-right 92 - * node as the focus extension. 93 - * @return void 94 - */ 95 - focusOn : function(node, extended_node) { 96 - this._clearReticle(); 97 - 98 - if (!node) { 99 - return; 100 - } 101 - 102 - var r = JX.$N('div', {className : 'keyboard-focus-focus-reticle'}); 103 - 104 - extended_node = extended_node || node; 105 - 106 - // Outset the reticle some pixels away from the element, so there's some 107 - // space between the focused element and the outline. 108 - var p = JX.Vector.getPos(node); 109 - var s = JX.Vector.getAggregateScrollForNode(node); 110 - 111 - p.add(s).add(-4, -4).setPos(r); 112 - // Compute the size we need to extend to the full extent of the focused 113 - // nodes. 114 - JX.Vector.getPos(extended_node) 115 - .add(-p.x, -p.y) 116 - .add(JX.Vector.getDim(extended_node)) 117 - .add(8, 8) 118 - .setDim(r); 119 - JX.DOM.getContentFrame().appendChild(r); 120 - 121 - this._focusReticle = r; 122 - }, 123 - 124 - _clearReticle : function() { 125 - this._focusReticle && JX.DOM.remove(this._focusReticle); 126 - this._focusReticle = null; 127 - }, 128 85 _onkeypress : function(e) { 129 86 if (!(this._getKey(e) in JX.KeyboardShortcutManager._downkeys)) { 130 87 this._onkeyhit(e);