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

Make the "Keyboard Shortcuts" dialog in Differential less hideous

Summary:
Ref T13515. Adding "\" ("Open in External Editor") made this slighlty worse, but it was already pretty bad.

Long ago the keys had a special style on them, but this got changed and dropped somewhere around D16568 -- although at the time, I think they still had a grey background (see T11654).

Some later change removed this background.

Put the background back and separate the keystrokes into groups.

Test Plan: {F7370615}

Maniphest Tasks: T13515

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

+327 -110
+78 -78
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => '3c8a0668', 11 11 'conpherence.pkg.js' => '020aebcf', 12 - 'core.pkg.css' => '86f155f9', 13 - 'core.pkg.js' => '705aec2c', 12 + 'core.pkg.css' => 'a4a2417c', 13 + 'core.pkg.js' => '4355a8d3', 14 14 'differential.pkg.css' => '607c84be', 15 - 'differential.pkg.js' => '99e2cb01', 15 + 'differential.pkg.js' => 'ececaeef', 16 16 'diffusion.pkg.css' => '42c75c37', 17 17 'diffusion.pkg.js' => 'a98c0bf7', 18 18 'maniphest.pkg.css' => '35995d6d', ··· 40 40 'rsrc/css/application/base/main-menu-view.css' => 'bcec20f0', 41 41 'rsrc/css/application/base/notification-menu.css' => '4df1ee30', 42 42 'rsrc/css/application/base/phui-theme.css' => '35883b37', 43 - 'rsrc/css/application/base/standard-page-view.css' => '8a295cb9', 43 + 'rsrc/css/application/base/standard-page-view.css' => 'ed076e5a', 44 44 'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee', 45 45 'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41', 46 46 'rsrc/css/application/config/config-options.css' => '16c920ae', ··· 165 165 'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4', 166 166 'rsrc/css/phui/phui-left-right.css' => '68513c34', 167 167 'rsrc/css/phui/phui-lightbox.css' => '4ebf22da', 168 - 'rsrc/css/phui/phui-list.css' => 'b05144dd', 168 + 'rsrc/css/phui/phui-list.css' => '2f253c22', 169 169 'rsrc/css/phui/phui-object-box.css' => 'b8d7eea0', 170 170 'rsrc/css/phui/phui-pager.css' => 'd022c7ad', 171 171 'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8', ··· 378 378 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 379 379 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 380 380 'rsrc/js/application/diff/DiffChangeset.js' => '5a4e4a3b', 381 - 'rsrc/js/application/diff/DiffChangesetList.js' => '4769cfe7', 381 + 'rsrc/js/application/diff/DiffChangesetList.js' => 'f813ef26', 382 382 'rsrc/js/application/diff/DiffInline.js' => '16e97ebc', 383 383 'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17', 384 384 'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd', ··· 435 435 'rsrc/js/application/transactions/behavior-comment-actions.js' => '4dffaeb2', 436 436 'rsrc/js/application/transactions/behavior-reorder-configs.js' => '4842f137', 437 437 'rsrc/js/application/transactions/behavior-reorder-fields.js' => '0ad8d31f', 438 - 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '600f440c', 438 + 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8b5c7d65', 439 439 'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '2bdadf1a', 440 440 'rsrc/js/application/transactions/behavior-transaction-list.js' => '9cec214e', 441 441 'rsrc/js/application/trigger/TriggerRule.js' => '41b7b4f6', ··· 453 453 'rsrc/js/core/Favicon.js' => '7930776a', 454 454 'rsrc/js/core/FileUpload.js' => 'ab85e184', 455 455 'rsrc/js/core/Hovercard.js' => '074f0783', 456 - 'rsrc/js/core/KeyboardShortcut.js' => 'c9749dcd', 457 - 'rsrc/js/core/KeyboardShortcutManager.js' => '37b8a04a', 456 + 'rsrc/js/core/KeyboardShortcut.js' => '1a844c06', 457 + 'rsrc/js/core/KeyboardShortcutManager.js' => 'ef926938', 458 458 'rsrc/js/core/MultirowRowManager.js' => '5b54c823', 459 459 'rsrc/js/core/Notification.js' => 'a9b91e3f', 460 460 'rsrc/js/core/Prefab.js' => '5793d835', ··· 473 473 'rsrc/js/core/behavior-device.js' => '0cf79f45', 474 474 'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '7ad020a5', 475 475 'rsrc/js/core/behavior-fancy-datepicker.js' => '956f3eeb', 476 - 'rsrc/js/core/behavior-file-tree.js' => 'ee82cedb', 476 + 'rsrc/js/core/behavior-file-tree.js' => 'a61c2d11', 477 477 'rsrc/js/core/behavior-form.js' => '55d7b788', 478 478 'rsrc/js/core/behavior-gesture.js' => 'b58d1a2a', 479 479 'rsrc/js/core/behavior-global-drag-and-drop.js' => '1cab0e9a', ··· 481 481 'rsrc/js/core/behavior-history-install.js' => '6a1583a8', 482 482 'rsrc/js/core/behavior-hovercard.js' => '6c379000', 483 483 'rsrc/js/core/behavior-keyboard-pager.js' => '1325b731', 484 - 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '2cc87f49', 484 + 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '42c44e8b', 485 485 'rsrc/js/core/behavior-lightbox-attachments.js' => 'c7e748bf', 486 486 'rsrc/js/core/behavior-line-linker.js' => 'e15c8b1f', 487 487 'rsrc/js/core/behavior-linked-container.js' => '74446546', ··· 489 489 'rsrc/js/core/behavior-object-selector.js' => '98ef467f', 490 490 'rsrc/js/core/behavior-oncopy.js' => 'ff7b3f22', 491 491 'rsrc/js/core/behavior-phabricator-nav.js' => 'f166c949', 492 - 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '2f80333f', 492 + 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '54262396', 493 493 'rsrc/js/core/behavior-read-only-warning.js' => 'b9109f8f', 494 494 'rsrc/js/core/behavior-redirect.js' => '407ee861', 495 495 'rsrc/js/core/behavior-refresh-csrf.js' => '46116c01', ··· 511 511 'rsrc/js/core/behavior-workflow.js' => '9623adc1', 512 512 'rsrc/js/core/darkconsole/DarkLog.js' => '3b869402', 513 513 'rsrc/js/core/darkconsole/DarkMessage.js' => '26cd4b73', 514 - 'rsrc/js/core/darkconsole/behavior-dark-console.js' => 'f39d968b', 514 + 'rsrc/js/core/darkconsole/behavior-dark-console.js' => '457f4d16', 515 515 'rsrc/js/core/phtize.js' => '2f1db1ed', 516 516 'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '5cf0501a', 517 517 'rsrc/js/phui/behavior-phui-file-upload.js' => 'e150bd50', ··· 598 598 'javelin-behavior-conpherence-pontificate' => '4ae58b5a', 599 599 'javelin-behavior-conpherence-search' => '91befbcc', 600 600 'javelin-behavior-countdown-timer' => '6a162524', 601 - 'javelin-behavior-dark-console' => 'f39d968b', 601 + 'javelin-behavior-dark-console' => '457f4d16', 602 602 'javelin-behavior-dashboard-async-panel' => '9c01e364', 603 603 'javelin-behavior-dashboard-move-panels' => 'a2ab19be', 604 604 'javelin-behavior-dashboard-query-panel-select' => '1e413dc9', ··· 639 639 'javelin-behavior-phabricator-active-nav' => '7353f43d', 640 640 'javelin-behavior-phabricator-autofocus' => '65bb0011', 641 641 'javelin-behavior-phabricator-clipboard-copy' => 'cf32921f', 642 - 'javelin-behavior-phabricator-file-tree' => 'ee82cedb', 642 + 'javelin-behavior-phabricator-file-tree' => 'a61c2d11', 643 643 'javelin-behavior-phabricator-gesture' => 'b58d1a2a', 644 644 'javelin-behavior-phabricator-gesture-example' => '242dedd0', 645 645 'javelin-behavior-phabricator-keyboard-pager' => '1325b731', 646 - 'javelin-behavior-phabricator-keyboard-shortcuts' => '2cc87f49', 646 + 'javelin-behavior-phabricator-keyboard-shortcuts' => '42c44e8b', 647 647 'javelin-behavior-phabricator-line-linker' => 'e15c8b1f', 648 648 'javelin-behavior-phabricator-nav' => 'f166c949', 649 649 'javelin-behavior-phabricator-notification-example' => '29819b75', 650 650 'javelin-behavior-phabricator-object-selector' => '98ef467f', 651 651 'javelin-behavior-phabricator-oncopy' => 'ff7b3f22', 652 - 'javelin-behavior-phabricator-remarkup-assist' => '2f80333f', 652 + 'javelin-behavior-phabricator-remarkup-assist' => '54262396', 653 653 'javelin-behavior-phabricator-reveal-content' => 'b105a3a6', 654 654 'javelin-behavior-phabricator-search-typeahead' => '1cb7d027', 655 - 'javelin-behavior-phabricator-show-older-transactions' => '600f440c', 655 + 'javelin-behavior-phabricator-show-older-transactions' => '8b5c7d65', 656 656 'javelin-behavior-phabricator-tooltips' => '73ecc1f8', 657 657 'javelin-behavior-phabricator-transaction-comment-form' => '2bdadf1a', 658 658 'javelin-behavior-phabricator-transaction-list' => '9cec214e', ··· 775 775 'phabricator-darkmessage' => '26cd4b73', 776 776 'phabricator-dashboard-css' => '5a205b9d', 777 777 'phabricator-diff-changeset' => '5a4e4a3b', 778 - 'phabricator-diff-changeset-list' => '4769cfe7', 778 + 'phabricator-diff-changeset-list' => 'f813ef26', 779 779 'phabricator-diff-inline' => '16e97ebc', 780 780 'phabricator-drag-and-drop-file-upload' => '4370900d', 781 781 'phabricator-draggable-list' => '0169e425', ··· 785 785 'phabricator-file-upload' => 'ab85e184', 786 786 'phabricator-filetree-view-css' => '56cdd875', 787 787 'phabricator-flag-css' => '2b77be8d', 788 - 'phabricator-keyboard-shortcut' => 'c9749dcd', 789 - 'phabricator-keyboard-shortcut-manager' => '37b8a04a', 788 + 'phabricator-keyboard-shortcut' => '1a844c06', 789 + 'phabricator-keyboard-shortcut-manager' => 'ef926938', 790 790 'phabricator-main-menu-view' => 'bcec20f0', 791 791 'phabricator-nav-view-css' => 'f8a0c1bf', 792 792 'phabricator-notification' => 'a9b91e3f', ··· 800 800 'phabricator-shaped-request' => 'abf88db8', 801 801 'phabricator-slowvote-css' => '1694baed', 802 802 'phabricator-source-code-view-css' => '03d7ac28', 803 - 'phabricator-standard-page-view' => '8a295cb9', 803 + 'phabricator-standard-page-view' => 'ed076e5a', 804 804 'phabricator-textareautils' => 'f340a484', 805 805 'phabricator-title' => '43bc9360', 806 806 'phabricator-tooltip' => '83754533', ··· 856 856 'phui-invisible-character-view-css' => 'c694c4a4', 857 857 'phui-left-right-css' => '68513c34', 858 858 'phui-lightbox-css' => '4ebf22da', 859 - 'phui-list-view-css' => 'b05144dd', 859 + 'phui-list-view-css' => '2f253c22', 860 860 'phui-object-box-css' => 'b8d7eea0', 861 861 'phui-oi-big-ui-css' => 'fa74cc35', 862 862 'phui-oi-color-css' => 'b517bfa0', ··· 1032 1032 '16e97ebc' => array( 1033 1033 'javelin-dom', 1034 1034 ), 1035 + '1a844c06' => array( 1036 + 'javelin-install', 1037 + 'javelin-util', 1038 + 'phabricator-keyboard-shortcut-manager', 1039 + ), 1035 1040 '1b6acc2a' => array( 1036 1041 'javelin-magical-init', 1037 1042 'javelin-util', ··· 1160 1165 'javelin-request', 1161 1166 'phabricator-shaped-request', 1162 1167 ), 1163 - '2cc87f49' => array( 1164 - 'javelin-behavior', 1165 - 'javelin-workflow', 1166 - 'javelin-json', 1167 - 'javelin-dom', 1168 - 'phabricator-keyboard-shortcut', 1169 - ), 1170 1168 '2e255291' => array( 1171 1169 'javelin-install', 1172 1170 'javelin-util', ··· 1175 1173 '2f1db1ed' => array( 1176 1174 'javelin-util', 1177 1175 ), 1178 - '2f80333f' => array( 1179 - 'javelin-behavior', 1180 - 'javelin-stratcom', 1181 - 'javelin-dom', 1182 - 'phabricator-phtize', 1183 - 'phabricator-textareautils', 1184 - 'javelin-workflow', 1185 - 'javelin-vector', 1186 - 'phuix-autocomplete', 1187 - 'javelin-mask', 1188 - ), 1189 1176 '2fbe234d' => array( 1190 1177 'javelin-install', 1191 1178 'javelin-dom', ··· 1219 1206 '34e2a838' => array( 1220 1207 'aphront-typeahead-control-css', 1221 1208 'phui-tag-view-css', 1222 - ), 1223 - '37b8a04a' => array( 1224 - 'javelin-install', 1225 - 'javelin-util', 1226 - 'javelin-stratcom', 1227 - 'javelin-dom', 1228 - 'javelin-vector', 1229 1209 ), 1230 1210 '3829a3cf' => array( 1231 1211 'javelin-behavior', ··· 1279 1259 'javelin-behavior', 1280 1260 'javelin-uri', 1281 1261 ), 1262 + '42c44e8b' => array( 1263 + 'javelin-behavior', 1264 + 'javelin-workflow', 1265 + 'javelin-json', 1266 + 'javelin-dom', 1267 + 'phabricator-keyboard-shortcut', 1268 + ), 1282 1269 '4370900d' => array( 1283 1270 'javelin-install', 1284 1271 'javelin-util', ··· 1299 1286 '43bc9360' => array( 1300 1287 'javelin-install', 1301 1288 ), 1289 + '457f4d16' => array( 1290 + 'javelin-behavior', 1291 + 'javelin-stratcom', 1292 + 'javelin-util', 1293 + 'javelin-dom', 1294 + 'javelin-request', 1295 + 'phabricator-keyboard-shortcut', 1296 + 'phabricator-darklog', 1297 + 'phabricator-darkmessage', 1298 + ), 1302 1299 '46116c01' => array( 1303 1300 'javelin-request', 1304 1301 'javelin-behavior', ··· 1306 1303 'javelin-router', 1307 1304 'javelin-util', 1308 1305 'phabricator-busy', 1309 - ), 1310 - '4769cfe7' => array( 1311 - 'javelin-install', 1312 - 'phuix-button-view', 1313 1306 ), 1314 1307 '47a0728b' => array( 1315 1308 'javelin-behavior', ··· 1401 1394 '541f81c3' => array( 1402 1395 'javelin-install', 1403 1396 ), 1397 + 54262396 => array( 1398 + 'javelin-behavior', 1399 + 'javelin-stratcom', 1400 + 'javelin-dom', 1401 + 'phabricator-phtize', 1402 + 'phabricator-textareautils', 1403 + 'javelin-workflow', 1404 + 'javelin-vector', 1405 + 'phuix-autocomplete', 1406 + 'javelin-mask', 1407 + ), 1404 1408 '55a24e84' => array( 1405 1409 'javelin-install', 1406 1410 'javelin-dom', ··· 1493 1497 ), 1494 1498 '5faf27b9' => array( 1495 1499 'phuix-form-control-view', 1496 - ), 1497 - '600f440c' => array( 1498 - 'javelin-behavior', 1499 - 'javelin-stratcom', 1500 - 'javelin-dom', 1501 - 'phabricator-busy', 1502 1500 ), 1503 1501 '60cd9241' => array( 1504 1502 'javelin-behavior', ··· 1674 1672 'javelin-dom', 1675 1673 'phabricator-draggable-list', 1676 1674 ), 1675 + '8b5c7d65' => array( 1676 + 'javelin-behavior', 1677 + 'javelin-stratcom', 1678 + 'javelin-dom', 1679 + 'phabricator-busy', 1680 + ), 1677 1681 '8badee71' => array( 1678 1682 'javelin-install', 1679 1683 'javelin-util', ··· 1838 1842 'a5257c4e' => array( 1839 1843 'javelin-install', 1840 1844 'javelin-dom', 1845 + ), 1846 + 'a61c2d11' => array( 1847 + 'javelin-behavior', 1848 + 'phabricator-keyboard-shortcut', 1849 + 'javelin-stratcom', 1841 1850 ), 1842 1851 'a9942052' => array( 1843 1852 'javelin-behavior', ··· 2037 2046 'phuix-icon-view', 2038 2047 'phabricator-busy', 2039 2048 ), 2040 - 'c9749dcd' => array( 2041 - 'javelin-install', 2042 - 'javelin-util', 2043 - 'phabricator-keyboard-shortcut-manager', 2044 - ), 2045 2049 'cf32921f' => array( 2046 2050 'javelin-behavior', 2047 2051 'javelin-dom', ··· 2130 2134 'ee77366f' => array( 2131 2135 'aphront-dialog-view-css', 2132 2136 ), 2133 - 'ee82cedb' => array( 2137 + 'ef836bf2' => array( 2134 2138 'javelin-behavior', 2135 - 'phabricator-keyboard-shortcut', 2139 + 'javelin-dom', 2136 2140 'javelin-stratcom', 2137 2141 ), 2138 - 'ef836bf2' => array( 2139 - 'javelin-behavior', 2142 + 'ef926938' => array( 2143 + 'javelin-install', 2144 + 'javelin-util', 2145 + 'javelin-stratcom', 2140 2146 'javelin-dom', 2141 - 'javelin-stratcom', 2147 + 'javelin-vector', 2142 2148 ), 2143 2149 'f166c949' => array( 2144 2150 'javelin-behavior', ··· 2155 2161 'javelin-dom', 2156 2162 'javelin-vector', 2157 2163 ), 2158 - 'f39d968b' => array( 2164 + 'f51e9c17' => array( 2159 2165 'javelin-behavior', 2160 2166 'javelin-stratcom', 2161 - 'javelin-util', 2162 2167 'javelin-dom', 2163 - 'javelin-request', 2164 - 'phabricator-keyboard-shortcut', 2165 - 'phabricator-darklog', 2166 - 'phabricator-darkmessage', 2167 2168 ), 2168 - 'f51e9c17' => array( 2169 - 'javelin-behavior', 2170 - 'javelin-stratcom', 2171 - 'javelin-dom', 2169 + 'f813ef26' => array( 2170 + 'javelin-install', 2171 + 'phuix-button-view', 2172 2172 ), 2173 2173 'f84bcbf4' => array( 2174 2174 'javelin-behavior',
+74 -9
src/applications/help/controller/PhabricatorHelpKeyboardShortcutController.php
··· 21 21 // close the dialog, so be explicit that escape works since it isn't 22 22 // terribly discoverable. 23 23 $keys[] = array( 24 - 'keys' => array('esc'), 24 + 'keys' => array('Esc'), 25 25 'description' => pht('Close any dialog, including this one.'), 26 + 'group' => 'global', 27 + ); 28 + 29 + $groups = array( 30 + 'default' => array( 31 + 'name' => pht('Page Shortcuts'), 32 + 'icon' => 'fa-keyboard-o', 33 + ), 34 + 'diff-nav' => array( 35 + 'name' => pht('Diff Navigation'), 36 + 'icon' => 'fa-arrows', 37 + ), 38 + 'diff-vis' => array( 39 + 'name' => pht('Hiding Content'), 40 + 'icon' => 'fa-eye-slash', 41 + ), 42 + 'inline' => array( 43 + 'name' => pht('Editing Inline Comments'), 44 + 'icon' => 'fa-pencil', 45 + ), 46 + 'xactions' => array( 47 + 'name' => pht('Comments'), 48 + 'icon' => 'fa-comments-o', 49 + ), 50 + 'global' => array( 51 + 'name' => pht('Global Shortcuts'), 52 + 'icon' => 'fa-globe', 53 + ), 26 54 ); 27 55 28 56 $stroke_map = array( ··· 35 63 'delete' => "\xE2\x8C\xAB", 36 64 ); 37 65 38 - $rows = array(); 66 + $row_maps = array(); 39 67 foreach ($keys as $shortcut) { 40 68 $keystrokes = array(); 41 69 foreach ($shortcut['keys'] as $stroke) { 42 70 $stroke = idx($stroke_map, $stroke, $stroke); 43 - $keystrokes[] = phutil_tag('kbd', array(), $stroke); 71 + $keystrokes[] = phutil_tag( 72 + 'span', 73 + array( 74 + 'class' => 'keyboard-shortcut-key', 75 + ), 76 + $stroke); 44 77 } 45 78 $keystrokes = phutil_implode_html(' or ', $keystrokes); 46 - $rows[] = phutil_tag( 79 + 80 + $group_key = idx($shortcut, 'group'); 81 + if (!isset($groups[$group_key])) { 82 + $group_key = 'default'; 83 + } 84 + 85 + $row = phutil_tag( 47 86 'tr', 48 87 array(), 49 88 array( 50 89 phutil_tag('th', array(), $keystrokes), 51 90 phutil_tag('td', array(), $shortcut['description']), 52 91 )); 92 + 93 + $row_maps[$group_key][] = $row; 53 94 } 54 95 55 - $table = phutil_tag( 56 - 'table', 57 - array('class' => 'keyboard-shortcut-help'), 58 - $rows); 96 + $tab_group = id(new PHUITabGroupView()) 97 + ->setVertical(true); 98 + 99 + foreach ($groups as $key => $group) { 100 + $rows = idx($row_maps, $key); 101 + if (!$rows) { 102 + continue; 103 + } 104 + 105 + $icon = id(new PHUIIconView()) 106 + ->setIcon($group['icon']); 107 + 108 + $tab = id(new PHUITabView()) 109 + ->setKey($key) 110 + ->setName($group['name']) 111 + ->setIcon($icon); 112 + 113 + $table = phutil_tag( 114 + 'table', 115 + array('class' => 'keyboard-shortcut-help'), 116 + $rows); 117 + 118 + $tab->appendChild($table); 119 + 120 + $tab_group->addTab($tab); 121 + } 59 122 60 123 return $this->newDialog() 61 124 ->setTitle(pht('Keyboard Shortcuts')) 62 - ->appendChild($table) 125 + ->setWidth(AphrontDialogView::WIDTH_FULL) 126 + ->setFlush(true) 127 + ->appendChild($tab_group) 63 128 ->addCancelButton('#', pht('Close')); 64 129 65 130 }
+4
src/view/phui/PHUIIconView.php
··· 57 57 return $this; 58 58 } 59 59 60 + public function getIconName() { 61 + return $this->iconFont; 62 + } 63 + 60 64 public function setBackground($color) { 61 65 $this->iconBackground = $color; 62 66 return $this;
+15 -1
src/view/phui/PHUIListView.php
··· 3 3 final class PHUIListView extends AphrontTagView { 4 4 5 5 const NAVBAR_LIST = 'phui-list-navbar'; 6 + const NAVBAR_VERTICAL = 'phui-list-navbar-vertical'; 6 7 const SIDENAV_LIST = 'phui-list-sidenav'; 7 8 const TABBAR_LIST = 'phui-list-tabbar'; 8 9 ··· 180 181 $classes = array(); 181 182 $classes[] = 'phui-list-view'; 182 183 if ($this->type) { 183 - $classes[] = $this->type; 184 + switch ($this->type) { 185 + case self::NAVBAR_LIST: 186 + $classes[] = 'phui-list-navbar'; 187 + $classes[] = 'phui-list-navbar-horizontal'; 188 + break; 189 + case self::NAVBAR_VERTICAL: 190 + $classes[] = 'phui-list-navbar'; 191 + $classes[] = 'phui-list-navbar-vertical'; 192 + break; 193 + default: 194 + $classes[] = $this->type; 195 + break; 196 + } 184 197 } 198 + 185 199 return array( 186 200 'class' => implode(' ', $classes), 187 201 );
+51 -2
src/view/phui/PHUITabGroupView.php
··· 4 4 5 5 private $tabs = array(); 6 6 private $selectedTab; 7 + private $vertical; 7 8 8 9 private $hideSingleTab; 9 10 10 11 protected function canAppendChild() { 11 12 return false; 13 + } 14 + 15 + public function setVertical($vertical) { 16 + $this->vertical = $vertical; 17 + return $this; 18 + } 19 + 20 + public function getVertical() { 21 + return $this->vertical; 12 22 } 13 23 14 24 public function setHideSingleTab($hide_single_tab) { ··· 65 75 protected function getTagAttributes() { 66 76 $tab_map = mpull($this->tabs, 'getContentID', 'getKey'); 67 77 78 + $classes = array(); 79 + if ($this->getVertical()) { 80 + $classes[] = 'phui-tab-group-view-vertical'; 81 + } 82 + 68 83 return array( 84 + 'class' => $classes, 69 85 'sigil' => 'phui-tab-group-view', 70 86 'meta' => array( 71 87 'tabMap' => $tab_map, ··· 76 92 protected function getTagContent() { 77 93 Javelin::initBehavior('phui-tab-group'); 78 94 79 - $tabs = id(new PHUIListView()) 80 - ->setType(PHUIListView::NAVBAR_LIST); 95 + $tabs = new PHUIListView(); 96 + 97 + if ($this->getVertical()) { 98 + $tabs->setType(PHUIListView::NAVBAR_VERTICAL); 99 + } else { 100 + $tabs->setType(PHUIListView::NAVBAR_LIST); 101 + } 102 + 81 103 $content = array(); 82 104 83 105 $selected_tab = $this->getSelectedTabKey(); ··· 104 126 } 105 127 106 128 if ($this->hideSingleTab && (count($this->tabs) == 1)) { 129 + $tabs = null; 130 + } 131 + 132 + if ($tabs && $this->getVertical()) { 133 + $content = phutil_tag( 134 + 'table', 135 + array( 136 + 'style' => 'width: 100%', 137 + ), 138 + phutil_tag( 139 + 'tbody', 140 + array(), 141 + phutil_tag( 142 + 'tr', 143 + array(), 144 + array( 145 + phutil_tag( 146 + 'td', 147 + array( 148 + 'class' => 'phui-tab-group-view-tab-column', 149 + ), 150 + $tabs), 151 + phutil_tag( 152 + 'td', 153 + array(), 154 + $content), 155 + )))); 107 156 $tabs = null; 108 157 } 109 158
+15
src/view/phui/PHUITabView.php
··· 2 2 3 3 final class PHUITabView extends AphrontTagView { 4 4 5 + private $icon; 5 6 private $name; 6 7 private $key; 7 8 private $keyLocked; ··· 51 52 return $this->name; 52 53 } 53 54 55 + public function setIcon(PHUIIconView $icon) { 56 + $this->icon = $icon; 57 + return $this; 58 + } 59 + 60 + public function getIcon() { 61 + return $this->icon; 62 + } 63 + 54 64 public function getContentID() { 55 65 if ($this->contentID === null) { 56 66 $this->contentID = celerity_generate_unique_node_id(); ··· 79 89 array( 80 90 'tabKey' => $this->getKey(), 81 91 )); 92 + 93 + $icon = $this->getIcon(); 94 + if ($icon) { 95 + $item->setIcon($icon->getIconName()); 96 + } 82 97 83 98 $color = $this->getColor(); 84 99 if ($color !== null) {
+21 -1
webroot/rsrc/css/application/base/standard-page-view.css
··· 49 49 display: none; 50 50 } 51 51 52 + .keyboard-shortcut-help { 53 + margin: 4px 12px; 54 + } 55 + 52 56 .keyboard-shortcut-help td, 53 57 .keyboard-shortcut-help th { 54 - padding: 8px; 58 + padding: 6px; 55 59 vertical-align: middle; 56 60 } 57 61 58 62 .keyboard-shortcut-help th { 59 63 white-space: nowrap; 60 64 color: {$greytext}; 65 + } 66 + 67 + .keyboard-shortcut-key { 68 + display: inline-block; 69 + min-width: 1em; 70 + min-height: 1em; 71 + padding: 4px 6px; 72 + font-weight: normal; 73 + text-align: center; 74 + text-decoration: none; 75 + border-radius: 3px; 76 + box-shadow: inset 0 -1px 0 rgba({$alphablue}, 0.08); 77 + user-select: none; 78 + color: {$darkgreytext}; 79 + background: {$lightgreybackground}; 80 + border: 1px solid {$lightgreyborder}; 61 81 } 62 82 63 83 .keyboard-focus-focus-reticle {
+40 -4
webroot/rsrc/css/phui/phui-list.css
··· 100 100 .phui-list-view.phui-list-navbar { 101 101 list-style: none; 102 102 overflow: hidden; 103 + } 104 + 105 + .phui-list-view.phui-list-navbar-horizontal { 103 106 border-bottom: 1px solid {$thinblueborder}; 104 107 } 105 108 106 109 .phui-list-view.phui-list-navbar > li { 107 110 list-style: none; 111 + display: block; 112 + } 113 + 114 + .phui-list-view.phui-list-navbar-horizontal > li { 108 115 float: left; 109 - display: block; 110 116 border-right: 1px solid {$thinblueborder}; 111 117 } 112 118 113 119 .phui-list-navbar .phui-list-item-href { 114 120 color: {$bluetext}; 115 - padding: 8px 16px; 116 121 line-height: 16px; 117 122 } 118 123 124 + .phui-list-navbar-horizontal .phui-list-item-href { 125 + padding: 8px 16px; 126 + } 127 + 128 + .phui-list-navbar-vertical .phui-list-item-href { 129 + padding: 8px 12px; 130 + } 131 + 132 + .phui-list-navbar-vertical { 133 + box-shadow: 0 1px 0 rgba({$alphablue}, 0.05); 134 + } 135 + 136 + .phui-list-navbar-vertical .phui-list-item-href { 137 + display: block; 138 + background: #ffffff; 139 + } 140 + 119 141 .phui-list-navbar .phui-list-item-selected .phui-list-item-href { 120 142 background: {$lightbluebackground}; 121 143 color: {$darkbluetext}; 122 144 font-weight: bold; 123 145 } 124 146 147 + .phui-tab-group-view-tab-column { 148 + width: 220px; 149 + border-right: 1px solid {$thinblueborder}; 150 + background: {$lightgreybackground}; 151 + } 152 + 125 153 .phui-list-navbar .phui-list-item-href:hover { 126 154 background: rgba(100,100,100,.1); 127 155 color: {$darkgreytext}; ··· 131 159 .phui-list-navbar .phui-list-item-icon { 132 160 height: 14px; 133 161 width: 14px; 134 - display: block; 135 162 font-size: 14px; 163 + text-align: center; 136 164 } 137 165 138 - .device-phone .phui-list-view.phui-list-navbar > li { 166 + .phui-list-navbar-vertical .phui-list-item-icon { 167 + margin-right: 8px; 168 + } 169 + 170 + .phui-list-navbar-horizontal .phui-list-item-icon { 171 + display: block; 172 + } 173 + 174 + .device-phone .phui-list-view.phui-list-navbar-horizontal > li { 139 175 float: none; 140 176 border: none; 141 177 }
+18 -13
webroot/rsrc/js/application/diff/DiffChangesetList.js
··· 158 158 159 159 var label; 160 160 161 + if (!standalone) { 162 + label = pht('Jump to the table of contents.'); 163 + this._installKey('t', 'diff-nav', label, this._ontoc); 164 + } 165 + 161 166 label = pht('Jump to next change.'); 162 167 this._installJumpKey('j', label, 1); 163 168 ··· 187 192 188 193 if (!standalone) { 189 194 label = pht('Hide or show the current file.'); 190 - this._installKey('h', label, this._onkeytogglefile); 191 - 192 - label = pht('Jump to the table of contents.'); 193 - this._installKey('t', label, this._ontoc); 195 + this._installKey('h', 'diff-vis', label, this._onkeytogglefile); 194 196 } 195 197 196 198 label = pht('Reply to selected inline comment or change.'); 197 - this._installKey('r', label, JX.bind(this, this._onkeyreply, false)); 199 + this._installKey('r', 'inline', label, 200 + JX.bind(this, this._onkeyreply, false)); 198 201 199 202 label = pht('Reply and quote selected inline comment.'); 200 - this._installKey('R', label, JX.bind(this, this._onkeyreply, true)); 203 + this._installKey('R', 'inline', label, 204 + JX.bind(this, this._onkeyreply, true)); 201 205 202 206 label = pht('Edit selected inline comment.'); 203 - this._installKey('e', label, this._onkeyedit); 207 + this._installKey('e', 'inline', label, this._onkeyedit); 204 208 205 209 label = pht('Mark or unmark selected inline comment as done.'); 206 - this._installKey('w', label, this._onkeydone); 210 + this._installKey('w', 'inline', label, this._onkeydone); 207 211 208 212 label = pht('Collapse or expand inline comment.'); 209 - this._installKey('q', label, this._onkeycollapse); 213 + this._installKey('q', 'diff-vis', label, this._onkeycollapse); 210 214 211 215 label = pht('Hide or show all inline comments.'); 212 - this._installKey('A', label, this._onkeyhideall); 216 + this._installKey('A', 'diff-vis', label, this._onkeyhideall); 213 217 214 218 label = pht('Open file in external editor.'); 215 - this._installKey('\\', label, this._onkeyopeneditor); 219 + this._installKey('\\', 'diff-nav', label, this._onkeyopeneditor); 216 220 217 221 }, 218 222 ··· 282 286 } 283 287 }, 284 288 285 - _installKey: function(key, label, handler) { 289 + _installKey: function(key, group, label, handler) { 286 290 handler = JX.bind(this, this._ifawake, handler); 287 291 288 292 return new JX.KeyboardShortcut(key, label) 289 293 .setHandler(handler) 294 + .setGroup(group) 290 295 .register(); 291 296 }, 292 297 ··· 299 304 }; 300 305 301 306 var handler = JX.bind(this, this._onjumpkey, delta, options); 302 - return this._installKey(key, label, handler); 307 + return this._installKey(key, 'diff-nav', label, handler); 303 308 }, 304 309 305 310 _ontoc: function(manager) {
+1
webroot/rsrc/js/application/transactions/behavior-show-older-transactions.js
··· 114 114 check_hash(); 115 115 116 116 new JX.KeyboardShortcut(['@'], 'Show all older changes in the timeline.') 117 + .setGroup('xactions') 117 118 .setHandler(JX.bind(null, load_older, load_all_older_callback)) 118 119 .register(); 119 120 });
+1
webroot/rsrc/js/core/KeyboardShortcut.js
··· 20 20 21 21 properties : { 22 22 keys : null, 23 + group: null, 23 24 description : null, 24 25 handler : null, 25 26 tooltipHandler : null
+4 -2
webroot/rsrc/js/core/KeyboardShortcutManager.js
··· 65 65 getShortcutDescriptions : function() { 66 66 var desc = []; 67 67 for (var ii = 0; ii < this._shortcuts.length; ii++) { 68 + var shortcut = this._shortcuts[ii]; 68 69 desc.push({ 69 - keys : this._shortcuts[ii].getKeys(), 70 - description : this._shortcuts[ii].getDescription() 70 + keys : shortcut.getKeys(), 71 + group: shortcut.getGroup(), 72 + description : shortcut.getDescription() 71 73 }); 72 74 } 73 75 return desc;
+1
webroot/rsrc/js/core/behavior-file-tree.js
··· 8 8 JX.behavior('phabricator-file-tree', function() { 9 9 10 10 new JX.KeyboardShortcut('f', 'Toggle file tree.') 11 + .setGroup('diff-vis') 11 12 .setHandler(function() { 12 13 JX.Stratcom.invoke('differential-filetree-toggle'); 13 14 })
+2
webroot/rsrc/js/core/behavior-keyboard-shortcuts.js
··· 15 15 var workflow = null; 16 16 17 17 new JX.KeyboardShortcut('?', pht('?')) 18 + .setGroup('global') 18 19 .setHandler(function(manager) { 19 20 if (workflow) { 20 21 // Already showing the dialog. ··· 32 33 33 34 if (config.searchID) { 34 35 new JX.KeyboardShortcut('/', pht('/')) 36 + .setGroup('global') 35 37 .setHandler(function() { 36 38 var search = JX.$(config.searchID); 37 39 search.focus();
+1
webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js
··· 379 379 380 380 if (config.canPin) { 381 381 new JX.KeyboardShortcut('z', pht('key-help')) 382 + .setGroup('xactions') 382 383 .setHandler(function() { 383 384 set_pinned_mode(root, !pinned); 384 385 })
+1
webroot/rsrc/js/core/darkconsole/behavior-dark-console.js
··· 259 259 function install_shortcut() { 260 260 var desc = 'Toggle visibility of DarkConsole.'; 261 261 new JX.KeyboardShortcut('`', desc) 262 + .setGroup('global') 262 263 .setHandler(function() { 263 264 statics.visible = !statics.visible; 264 265