@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.

Allow speical keys to be bound to keystrokes

Summary: Fixes T2711. Allows special keys (arrows, tab, return) to be bound as shortcuts. Binds left and right as shortcuts in Pholio.

Test Plan: Pressed left. Pressed right.

Reviewers: chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T2711

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

+126 -93
+87 -89
src/__celerity_resource_map__.php
··· 805 805 ), 806 806 'conpherence-widget-pane-css' => 807 807 array( 808 - 'uri' => '/res/e67ad581/rsrc/css/application/conpherence/widget-pane.css', 808 + 'uri' => '/res/6e5755bb/rsrc/css/application/conpherence/widget-pane.css', 809 809 'type' => 'css', 810 810 'requires' => 811 811 array( ··· 1167 1167 ), 1168 1168 'javelin-behavior-conpherence-menu' => 1169 1169 array( 1170 - 'uri' => '/res/cb1a5cf0/rsrc/js/application/conpherence/behavior-menu.js', 1170 + 'uri' => '/res/0ad6ab54/rsrc/js/application/conpherence/behavior-menu.js', 1171 1171 'type' => 'js', 1172 1172 'requires' => 1173 1173 array( 1174 1174 0 => 'javelin-behavior', 1175 1175 1 => 'javelin-dom', 1176 - 2 => 'javelin-request', 1177 - 3 => 'javelin-stratcom', 1178 - 4 => 'javelin-uri', 1179 - 5 => 'javelin-util', 1180 - 6 => 'javelin-workflow', 1176 + 2 => 'javelin-workflow', 1177 + 3 => 'javelin-util', 1178 + 4 => 'javelin-stratcom', 1179 + 5 => 'javelin-uri', 1181 1180 ), 1182 1181 'disk' => '/rsrc/js/application/conpherence/behavior-menu.js', 1183 1182 ), 1184 1183 'javelin-behavior-conpherence-pontificate' => 1185 1184 array( 1186 - 'uri' => '/res/15263692/rsrc/js/application/conpherence/behavior-pontificate.js', 1185 + 'uri' => '/res/06214a06/rsrc/js/application/conpherence/behavior-pontificate.js', 1187 1186 'type' => 'js', 1188 1187 'requires' => 1189 1188 array( 1190 1189 0 => 'javelin-behavior', 1191 1190 1 => 'javelin-dom', 1192 - 2 => 'javelin-util', 1193 - 3 => 'javelin-workflow', 1191 + 2 => 'javelin-request', 1194 1192 ), 1195 1193 'disk' => '/rsrc/js/application/conpherence/behavior-pontificate.js', 1196 1194 ), ··· 1935 1933 ), 1936 1934 'javelin-behavior-pholio-mock-view' => 1937 1935 array( 1938 - 'uri' => '/res/bee3cef2/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 1936 + 'uri' => '/res/6b8ca4e4/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 1939 1937 'type' => 'js', 1940 1938 'requires' => 1941 1939 array( ··· 2666 2664 ), 2667 2665 'phabricator-core-css' => 2668 2666 array( 2669 - 'uri' => '/res/1e7afaa9/rsrc/css/core/core.css', 2667 + 'uri' => '/res/b34e5c75/rsrc/css/core/core.css', 2670 2668 'type' => 'css', 2671 2669 'requires' => 2672 2670 array( ··· 2819 2817 ), 2820 2818 'phabricator-keyboard-shortcut-manager' => 2821 2819 array( 2822 - 'uri' => '/res/0be80136/rsrc/js/application/core/KeyboardShortcutManager.js', 2820 + 'uri' => '/res/d0bee7c7/rsrc/js/application/core/KeyboardShortcutManager.js', 2823 2821 'type' => 'js', 2824 2822 'requires' => 2825 2823 array( ··· 3057 3055 ), 3058 3056 'phabricator-standard-page-view' => 3059 3057 array( 3060 - 'uri' => '/res/70fa2da4/rsrc/css/application/base/standard-page-view.css', 3058 + 'uri' => '/res/252faaf4/rsrc/css/application/base/standard-page-view.css', 3061 3059 'type' => 'css', 3062 3060 'requires' => 3063 3061 array( ··· 3502 3500 ), array( 3503 3501 'packages' => 3504 3502 array( 3505 - 'fdd3bb5f' => 3503 + '8e2735e2' => 3506 3504 array( 3507 3505 'name' => 'core.pkg.css', 3508 3506 'symbols' => ··· 3545 3543 35 => 'phabricator-object-item-list-view-css', 3546 3544 36 => 'global-drag-and-drop-css', 3547 3545 ), 3548 - 'uri' => '/res/pkg/fdd3bb5f/core.pkg.css', 3546 + 'uri' => '/res/pkg/8e2735e2/core.pkg.css', 3549 3547 'type' => 'css', 3550 3548 ), 3551 - 'f24c209c' => 3549 + '0ed3458f' => 3552 3550 array( 3553 3551 'name' => 'core.pkg.js', 3554 3552 'symbols' => ··· 3588 3586 32 => 'javelin-behavior-global-drag-and-drop', 3589 3587 33 => 'javelin-behavior-phabricator-reveal-content', 3590 3588 ), 3591 - 'uri' => '/res/pkg/f24c209c/core.pkg.js', 3589 + 'uri' => '/res/pkg/0ed3458f/core.pkg.js', 3592 3590 'type' => 'js', 3593 3591 ), 3594 3592 'dca4a03d' => ··· 3735 3733 'reverse' => 3736 3734 array( 3737 3735 'aphront-attached-file-view-css' => 'eb35a026', 3738 - 'aphront-crumbs-view-css' => 'fdd3bb5f', 3739 - 'aphront-dialog-view-css' => 'fdd3bb5f', 3740 - 'aphront-error-view-css' => 'fdd3bb5f', 3741 - 'aphront-form-view-css' => 'fdd3bb5f', 3742 - 'aphront-list-filter-view-css' => 'fdd3bb5f', 3743 - 'aphront-pager-view-css' => 'fdd3bb5f', 3744 - 'aphront-panel-view-css' => 'fdd3bb5f', 3745 - 'aphront-table-view-css' => 'fdd3bb5f', 3746 - 'aphront-tokenizer-control-css' => 'fdd3bb5f', 3747 - 'aphront-tooltip-css' => 'fdd3bb5f', 3748 - 'aphront-typeahead-control-css' => 'fdd3bb5f', 3736 + 'aphront-crumbs-view-css' => '8e2735e2', 3737 + 'aphront-dialog-view-css' => '8e2735e2', 3738 + 'aphront-error-view-css' => '8e2735e2', 3739 + 'aphront-form-view-css' => '8e2735e2', 3740 + 'aphront-list-filter-view-css' => '8e2735e2', 3741 + 'aphront-pager-view-css' => '8e2735e2', 3742 + 'aphront-panel-view-css' => '8e2735e2', 3743 + 'aphront-table-view-css' => '8e2735e2', 3744 + 'aphront-tokenizer-control-css' => '8e2735e2', 3745 + 'aphront-tooltip-css' => '8e2735e2', 3746 + 'aphront-typeahead-control-css' => '8e2735e2', 3749 3747 'differential-changeset-view-css' => '8aaacd1b', 3750 3748 'differential-core-view-css' => '8aaacd1b', 3751 3749 'differential-inline-comment-editor' => '322728f3', ··· 3759 3757 'differential-table-of-contents-css' => '8aaacd1b', 3760 3758 'diffusion-commit-view-css' => 'c8ce2d88', 3761 3759 'diffusion-icons-css' => 'c8ce2d88', 3762 - 'global-drag-and-drop-css' => 'fdd3bb5f', 3760 + 'global-drag-and-drop-css' => '8e2735e2', 3763 3761 'inline-comment-summary-css' => '8aaacd1b', 3764 - 'javelin-aphlict' => 'f24c209c', 3762 + 'javelin-aphlict' => '0ed3458f', 3765 3763 'javelin-behavior' => 'cd1d650a', 3766 - 'javelin-behavior-aphlict-dropdown' => 'f24c209c', 3767 - 'javelin-behavior-aphlict-listen' => 'f24c209c', 3768 - 'javelin-behavior-aphront-basic-tokenizer' => 'f24c209c', 3764 + 'javelin-behavior-aphlict-dropdown' => '0ed3458f', 3765 + 'javelin-behavior-aphlict-listen' => '0ed3458f', 3766 + 'javelin-behavior-aphront-basic-tokenizer' => '0ed3458f', 3769 3767 'javelin-behavior-aphront-drag-and-drop' => '322728f3', 3770 3768 'javelin-behavior-aphront-drag-and-drop-textarea' => '322728f3', 3771 - 'javelin-behavior-aphront-form-disable-on-submit' => 'f24c209c', 3769 + 'javelin-behavior-aphront-form-disable-on-submit' => '0ed3458f', 3772 3770 'javelin-behavior-audit-preview' => 'f96657b8', 3773 3771 'javelin-behavior-dark-console' => 'dca4a03d', 3774 - 'javelin-behavior-device' => 'f24c209c', 3772 + 'javelin-behavior-device' => '0ed3458f', 3775 3773 'javelin-behavior-differential-accept-with-errors' => '322728f3', 3776 3774 'javelin-behavior-differential-add-reviewers-and-ccs' => '322728f3', 3777 3775 'javelin-behavior-differential-comment-jump' => '322728f3', ··· 3787 3785 'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 3788 3786 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 3789 3787 'javelin-behavior-error-log' => 'dca4a03d', 3790 - 'javelin-behavior-global-drag-and-drop' => 'f24c209c', 3791 - 'javelin-behavior-history-install' => 'f24c209c', 3792 - 'javelin-behavior-konami' => 'f24c209c', 3793 - 'javelin-behavior-lightbox-attachments' => 'f24c209c', 3788 + 'javelin-behavior-global-drag-and-drop' => '0ed3458f', 3789 + 'javelin-behavior-history-install' => '0ed3458f', 3790 + 'javelin-behavior-konami' => '0ed3458f', 3791 + 'javelin-behavior-lightbox-attachments' => '0ed3458f', 3794 3792 'javelin-behavior-load-blame' => '322728f3', 3795 3793 'javelin-behavior-maniphest-batch-selector' => '7707de41', 3796 3794 'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 3797 3795 'javelin-behavior-maniphest-transaction-controls' => '7707de41', 3798 3796 'javelin-behavior-maniphest-transaction-expand' => '7707de41', 3799 3797 'javelin-behavior-maniphest-transaction-preview' => '7707de41', 3800 - 'javelin-behavior-phabricator-active-nav' => 'f24c209c', 3801 - 'javelin-behavior-phabricator-autofocus' => 'f24c209c', 3802 - 'javelin-behavior-phabricator-keyboard-shortcuts' => 'f24c209c', 3803 - 'javelin-behavior-phabricator-nav' => 'f24c209c', 3798 + 'javelin-behavior-phabricator-active-nav' => '0ed3458f', 3799 + 'javelin-behavior-phabricator-autofocus' => '0ed3458f', 3800 + 'javelin-behavior-phabricator-keyboard-shortcuts' => '0ed3458f', 3801 + 'javelin-behavior-phabricator-nav' => '0ed3458f', 3804 3802 'javelin-behavior-phabricator-object-selector' => '322728f3', 3805 - 'javelin-behavior-phabricator-oncopy' => 'f24c209c', 3806 - 'javelin-behavior-phabricator-remarkup-assist' => 'f24c209c', 3807 - 'javelin-behavior-phabricator-reveal-content' => 'f24c209c', 3808 - 'javelin-behavior-phabricator-search-typeahead' => 'f24c209c', 3809 - 'javelin-behavior-phabricator-tooltips' => 'f24c209c', 3810 - 'javelin-behavior-phabricator-watch-anchor' => 'f24c209c', 3811 - 'javelin-behavior-refresh-csrf' => 'f24c209c', 3803 + 'javelin-behavior-phabricator-oncopy' => '0ed3458f', 3804 + 'javelin-behavior-phabricator-remarkup-assist' => '0ed3458f', 3805 + 'javelin-behavior-phabricator-reveal-content' => '0ed3458f', 3806 + 'javelin-behavior-phabricator-search-typeahead' => '0ed3458f', 3807 + 'javelin-behavior-phabricator-tooltips' => '0ed3458f', 3808 + 'javelin-behavior-phabricator-watch-anchor' => '0ed3458f', 3809 + 'javelin-behavior-refresh-csrf' => '0ed3458f', 3812 3810 'javelin-behavior-repository-crossreference' => '322728f3', 3813 - 'javelin-behavior-toggle-class' => 'f24c209c', 3814 - 'javelin-behavior-workflow' => 'f24c209c', 3811 + 'javelin-behavior-toggle-class' => '0ed3458f', 3812 + 'javelin-behavior-workflow' => '0ed3458f', 3815 3813 'javelin-dom' => 'cd1d650a', 3816 3814 'javelin-event' => 'cd1d650a', 3817 3815 'javelin-install' => 'cd1d650a', ··· 3830 3828 'javelin-util' => 'cd1d650a', 3831 3829 'javelin-vector' => 'cd1d650a', 3832 3830 'javelin-workflow' => 'cd1d650a', 3833 - 'lightbox-attachment-css' => 'fdd3bb5f', 3831 + 'lightbox-attachment-css' => '8e2735e2', 3834 3832 'maniphest-task-summary-css' => 'eb35a026', 3835 3833 'maniphest-transaction-detail-css' => 'eb35a026', 3836 - 'phabricator-busy' => 'f24c209c', 3834 + 'phabricator-busy' => '0ed3458f', 3837 3835 'phabricator-content-source-view-css' => '8aaacd1b', 3838 - 'phabricator-core-buttons-css' => 'fdd3bb5f', 3839 - 'phabricator-core-css' => 'fdd3bb5f', 3840 - 'phabricator-crumbs-view-css' => 'fdd3bb5f', 3841 - 'phabricator-directory-css' => 'fdd3bb5f', 3836 + 'phabricator-core-buttons-css' => '8e2735e2', 3837 + 'phabricator-core-css' => '8e2735e2', 3838 + 'phabricator-crumbs-view-css' => '8e2735e2', 3839 + 'phabricator-directory-css' => '8e2735e2', 3842 3840 'phabricator-drag-and-drop-file-upload' => '322728f3', 3843 - 'phabricator-dropdown-menu' => 'f24c209c', 3844 - 'phabricator-file-upload' => 'f24c209c', 3845 - 'phabricator-filetree-view-css' => 'fdd3bb5f', 3846 - 'phabricator-flag-css' => 'fdd3bb5f', 3847 - 'phabricator-form-view-css' => 'fdd3bb5f', 3848 - 'phabricator-header-view-css' => 'fdd3bb5f', 3849 - 'phabricator-jump-nav' => 'fdd3bb5f', 3850 - 'phabricator-keyboard-shortcut' => 'f24c209c', 3851 - 'phabricator-keyboard-shortcut-manager' => 'f24c209c', 3852 - 'phabricator-main-menu-view' => 'fdd3bb5f', 3853 - 'phabricator-menu-item' => 'f24c209c', 3854 - 'phabricator-nav-view-css' => 'fdd3bb5f', 3855 - 'phabricator-notification' => 'f24c209c', 3856 - 'phabricator-notification-css' => 'fdd3bb5f', 3857 - 'phabricator-notification-menu-css' => 'fdd3bb5f', 3858 - 'phabricator-object-item-list-view-css' => 'fdd3bb5f', 3841 + 'phabricator-dropdown-menu' => '0ed3458f', 3842 + 'phabricator-file-upload' => '0ed3458f', 3843 + 'phabricator-filetree-view-css' => '8e2735e2', 3844 + 'phabricator-flag-css' => '8e2735e2', 3845 + 'phabricator-form-view-css' => '8e2735e2', 3846 + 'phabricator-header-view-css' => '8e2735e2', 3847 + 'phabricator-jump-nav' => '8e2735e2', 3848 + 'phabricator-keyboard-shortcut' => '0ed3458f', 3849 + 'phabricator-keyboard-shortcut-manager' => '0ed3458f', 3850 + 'phabricator-main-menu-view' => '8e2735e2', 3851 + 'phabricator-menu-item' => '0ed3458f', 3852 + 'phabricator-nav-view-css' => '8e2735e2', 3853 + 'phabricator-notification' => '0ed3458f', 3854 + 'phabricator-notification-css' => '8e2735e2', 3855 + 'phabricator-notification-menu-css' => '8e2735e2', 3856 + 'phabricator-object-item-list-view-css' => '8e2735e2', 3859 3857 'phabricator-object-selector-css' => '8aaacd1b', 3860 - 'phabricator-paste-file-upload' => 'f24c209c', 3861 - 'phabricator-prefab' => 'f24c209c', 3858 + 'phabricator-paste-file-upload' => '0ed3458f', 3859 + 'phabricator-prefab' => '0ed3458f', 3862 3860 'phabricator-project-tag-css' => 'eb35a026', 3863 - 'phabricator-remarkup-css' => 'fdd3bb5f', 3861 + 'phabricator-remarkup-css' => '8e2735e2', 3864 3862 'phabricator-shaped-request' => '322728f3', 3865 - 'phabricator-side-menu-view-css' => 'fdd3bb5f', 3866 - 'phabricator-standard-page-view' => 'fdd3bb5f', 3867 - 'phabricator-textareautils' => 'f24c209c', 3868 - 'phabricator-tooltip' => 'f24c209c', 3869 - 'phabricator-transaction-view-css' => 'fdd3bb5f', 3870 - 'phabricator-zindex-css' => 'fdd3bb5f', 3871 - 'sprite-apps-large-css' => 'fdd3bb5f', 3872 - 'sprite-gradient-css' => 'fdd3bb5f', 3873 - 'sprite-icon-css' => 'fdd3bb5f', 3874 - 'sprite-menu-css' => 'fdd3bb5f', 3875 - 'syntax-highlighting-css' => 'fdd3bb5f', 3863 + 'phabricator-side-menu-view-css' => '8e2735e2', 3864 + 'phabricator-standard-page-view' => '8e2735e2', 3865 + 'phabricator-textareautils' => '0ed3458f', 3866 + 'phabricator-tooltip' => '0ed3458f', 3867 + 'phabricator-transaction-view-css' => '8e2735e2', 3868 + 'phabricator-zindex-css' => '8e2735e2', 3869 + 'sprite-apps-large-css' => '8e2735e2', 3870 + 'sprite-gradient-css' => '8e2735e2', 3871 + 'sprite-icon-css' => '8e2735e2', 3872 + 'sprite-menu-css' => '8e2735e2', 3873 + 'syntax-highlighting-css' => '8e2735e2', 3876 3874 ), 3877 3875 ));
+11
src/applications/help/controller/PhabricatorHelpKeyboardShortcutController.php
··· 21 21 'description' => 'Close any dialog, including this one.', 22 22 ); 23 23 24 + $stroke_map = array( 25 + 'left' => "\xE2\x86\x90", 26 + 'right' => "\xE2\x86\x92", 27 + 'up' => "\xE2\x86\x91", 28 + 'down' => "\xE2\x86\x93", 29 + 'return' => "\xE2\x8F\x8E", 30 + 'tab' => "\xE2\x87\xA5", 31 + 'delete' => "\xE2\x8C\xAB", 32 + ); 33 + 24 34 $rows = array(); 25 35 foreach ($keys as $shortcut) { 26 36 $keystrokes = array(); 27 37 foreach ($shortcut['keys'] as $stroke) { 38 + $stroke = idx($stroke_map, $stroke, $stroke); 28 39 $keystrokes[] = phutil_tag('kbd', array(), $stroke); 29 40 } 30 41 $keystrokes = phutil_implode_html(' or ', $keystrokes);
+26 -2
webroot/rsrc/js/application/core/KeyboardShortcutManager.js
··· 20 20 21 21 statics : { 22 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 + 23 35 getInstance : function() { 24 36 if (!JX.KeyboardShortcutManager._instance) { 25 37 JX.KeyboardShortcutManager._instance = new JX.KeyboardShortcutManager(); ··· 98 110 this._focusReticle = null; 99 111 }, 100 112 _onkeypress : function(e) { 113 + if (!(this._getKey(e) in JX.KeyboardShortcutManager._downkeys)) { 114 + this._onkeyhit(e); 115 + } 116 + }, 117 + _onkeyhit : function(e) { 101 118 var raw = e.getRawEvent(); 102 119 103 120 if (raw.altKey || raw.ctrlKey || raw.metaKey) { ··· 113 130 // focused. 114 131 return; 115 132 } 116 - // TODO: This likely needs to be refined to deal with arrow keys, etc. 117 - var key = String.fromCharCode(raw.charCode); 133 + 134 + var key = this._getKey(e); 118 135 119 136 var shortcuts = this._shortcuts; 120 137 for (var ii = 0; ii < shortcuts.length; ii++) { ··· 130 147 }, 131 148 _onkeydown : function(e) { 132 149 this._handleTooltipKeyEvent(e, true); 150 + 151 + if (this._getKey(e) in JX.KeyboardShortcutManager._downkeys) { 152 + this._onkeyhit(e); 153 + } 133 154 }, 134 155 _onkeyup : function(e) { 135 156 this._handleTooltipKeyEvent(e, false); 157 + }, 158 + _getKey : function(e) { 159 + return e.getSpecialKey() || String.fromCharCode(e.getRawEvent().charCode); 136 160 }, 137 161 _handleTooltipKeyEvent : function(e, is_keydown) { 138 162 if (e.getRawEvent().keyCode != 18) {
+2 -2
webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
··· 586 586 /* -( Keyboard Shortcuts )------------------------------------------------- */ 587 587 588 588 589 - new JX.KeyboardShortcut('j', 'Show next image.') 589 + new JX.KeyboardShortcut(['j', 'right'], 'Show next image.') 590 590 .setHandler(function() { 591 591 switch_image(1); 592 592 }) 593 593 .register(); 594 594 595 - new JX.KeyboardShortcut('k', 'Show previous image.') 595 + new JX.KeyboardShortcut(['k', 'left'], 'Show previous image.') 596 596 .setHandler(function() { 597 597 switch_image(-1); 598 598 })