@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<?php
2
3final class PhabricatorHelpKeyboardShortcutController
4 extends PhabricatorHelpController {
5
6 public function shouldAllowPublic() {
7 return true;
8 }
9
10 public function handleRequest(AphrontRequest $request) {
11 $viewer = $request->getViewer();
12
13 $keys = $request->getStr('keys');
14 try {
15 $keys = phutil_json_decode($keys);
16 } catch (PhutilJSONParserException $ex) {
17 return new Aphront400Response();
18 }
19
20 // There have been at least two users asking for a keyboard shortcut to
21 // close the dialog, so be explicit that escape works since it isn't
22 // terribly discoverable.
23 $keys[] = array(
24 'keys' => array('Esc'),
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 ),
54 );
55
56 $stroke_map = array(
57 'left' => "\xE2\x86\x90",
58 'right' => "\xE2\x86\x92",
59 'up' => "\xE2\x86\x91",
60 'down' => "\xE2\x86\x93",
61 'return' => "\xE2\x8F\x8E",
62 'tab' => "\xE2\x87\xA5",
63 'delete' => "\xE2\x8C\xAB",
64 );
65
66 $row_maps = array();
67 foreach ($keys as $shortcut) {
68 $keystrokes = array();
69 foreach ($shortcut['keys'] as $stroke) {
70 $stroke = idx($stroke_map, $stroke, $stroke);
71 $keystrokes[] = phutil_tag(
72 'span',
73 array(
74 'class' => 'keyboard-shortcut-key',
75 ),
76 $stroke);
77 }
78 $keystrokes = phutil_implode_html(' or ', $keystrokes);
79
80 $group_key = idx($shortcut, 'group');
81 if (!isset($groups[$group_key])) {
82 $group_key = 'default';
83 }
84
85 $row = phutil_tag(
86 'tr',
87 array(),
88 array(
89 phutil_tag('th', array(), $keystrokes),
90 phutil_tag('td', array(), $shortcut['description']),
91 ));
92
93 $row_maps[$group_key][] = $row;
94 }
95
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 }
122
123 return $this->newDialog()
124 ->setTitle(pht('Keyboard Shortcuts'))
125 ->setWidth(AphrontDialogView::WIDTH_FULL)
126 ->setFlush(true)
127 ->appendChild($tab_group)
128 ->addCancelButton('#', pht('Close'));
129
130 }
131
132}