diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 2d02e61843..f7183e44f9 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -248,6 +248,17 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/javelin/lib/behavior.js', ), + 0 => + array( + 'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-uri', + 1 => 'javelin-php-serializer', + ), + 'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js', + ), 'javelin-behavior-aphront-basic-tokenizer' => array( 'uri' => '/res/9be30797/rsrc/js/application/core/behavior-tokenizer.js', @@ -675,6 +686,18 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/owners/owners-path-editor.js', ), + 'javelin-behavior-phabricator-keyboard-pager' => + array( + 'uri' => '/res/56d64eff/rsrc/js/application/core/behavior-keyboard-pager.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-uri', + 2 => 'phabricator-keyboard-shortcut', + ), + 'disk' => '/rsrc/js/application/core/behavior-keyboard-pager.js', + ), 'javelin-behavior-phabricator-keyboard-shortcuts' => array( 'uri' => '/res/94b009e2/rsrc/js/application/core/behavior-keyboard-shortcuts.js', diff --git a/src/applications/conduit/controller/log/PhabricatorConduitLogController.php b/src/applications/conduit/controller/log/PhabricatorConduitLogController.php index 18139313e0..8213e5c232 100644 --- a/src/applications/conduit/controller/log/PhabricatorConduitLogController.php +++ b/src/applications/conduit/controller/log/PhabricatorConduitLogController.php @@ -32,7 +32,7 @@ class PhabricatorConduitLogController extends PhabricatorConduitController { $nav = new AphrontSideNavView(); $links = array( - 'calls' => 'All Calls', + 'calls' => 'All Calls', ); if (empty($links[$this->view])) { @@ -65,6 +65,7 @@ class PhabricatorConduitLogController extends PhabricatorConduitController { $pager->getPageSize() + 1); $calls = $pager->sliceResults($calls); $pager->setURI(new PhutilURI('/conduit/log/view/'.$this->view.'/'), 'page'); + $pager->setEnableKeyboardShortcuts(true); $min = $pager->getOffset() + 1; $max = ($min + count($calls) - 1); diff --git a/src/view/control/pager/AphrontPagerView.php b/src/view/control/pager/AphrontPagerView.php index 0429b8ca13..abd51498c4 100644 --- a/src/view/control/pager/AphrontPagerView.php +++ b/src/view/control/pager/AphrontPagerView.php @@ -27,6 +27,7 @@ final class AphrontPagerView extends AphrontView { private $uri; private $pagingParameter; private $surroundingPages = 2; + private $enableKeyboardShortcuts; final public function setPageSize($page_size) { $this->pageSize = max(1, $page_size); @@ -106,6 +107,11 @@ final class AphrontPagerView extends AphrontView { return $results; } + public function setEnableKeyboardShortcuts($enable) { + $this->enableKeyboardShortcuts = $enable; + return $this; + } + public function render() { if (!$this->uri) { throw new Exception( @@ -146,12 +152,16 @@ final class AphrontPagerView extends AphrontView { $links = array(); + $prev_index = null; + $next_index = null; + if ($min > 0) { $links[] = array(0, 'First', null); } if ($page > 0) { $links[] = array($page - 1, 'Prev', null); + $prev_index = $page - 1; } for ($ii = $min; $ii <= $max; $ii++) { @@ -160,6 +170,7 @@ final class AphrontPagerView extends AphrontView { if ($page < $last && $last > 0) { $links[] = array($page + 1, 'Next', null); + $next_index = $page + 1; } if ($max < ($last - 1)) { @@ -168,20 +179,29 @@ final class AphrontPagerView extends AphrontView { $base_uri = $this->uri; $parameter = $this->pagingParameter; - $page_size = $this->getPageSize(); + + if ($this->enableKeyboardShortcuts) { + $pager_links = array(); + $pager_index = array( + 'prev' => $prev_index, + 'next' => $next_index, + ); + foreach ($pager_index as $key => $index) { + if ($index !== null) { + $display_index = $this->getDisplayIndex($index); + $pager_links[$key] = (string)$base_uri->alter( + $parameter, + $display_index); + } + } + Javelin::initBehavior('phabricator-keyboard-pager', $pager_links); + } // Convert tuples into rendered nodes. $rendered_links = array(); foreach ($links as $link) { list($index, $label, $class) = $link; - // Use a 1-based sequence for display so that the number in the URI is - // the same as the page number you're on. - if ($index == 0) { - // No need for the first page to say page=1. - $display_index = null; - } else { - $display_index = $index * $page_size; - } + $display_index = $this->getDisplayIndex($index); $link = $base_uri->alter($parameter, $display_index); $rendered_links[] = phutil_render_tag( 'a', @@ -198,4 +218,17 @@ final class AphrontPagerView extends AphrontView { ''; } + private function getDisplayIndex($page_index) { + $page_size = $this->getPageSize(); + // Use a 1-based sequence for display so that the number in the URI is + // the same as the page number you're on. + if ($page_index == 0) { + // No need for the first page to say page=1. + $display_index = null; + } else { + $display_index = $page_index * $page_size; + } + return $display_index; + } + } diff --git a/src/view/control/pager/__init__.php b/src/view/control/pager/__init__.php index 488d68a205..21d0b89e61 100644 --- a/src/view/control/pager/__init__.php +++ b/src/view/control/pager/__init__.php @@ -7,6 +7,7 @@ phutil_require_module('phabricator', 'infrastructure/celerity/api'); +phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'view/base'); phutil_require_module('phutil', 'markup'); diff --git a/webroot/rsrc/js/application/core/behavior-keyboard-pager.js b/webroot/rsrc/js/application/core/behavior-keyboard-pager.js new file mode 100644 index 0000000000..02b98ffe70 --- /dev/null +++ b/webroot/rsrc/js/application/core/behavior-keyboard-pager.js @@ -0,0 +1,26 @@ +/** + * @provides javelin-behavior-phabricator-keyboard-pager + * @requires javelin-behavior + * javelin-uri + * phabricator-keyboard-shortcut + */ + +JX.behavior('phabricator-keyboard-pager', function(config) { + + new JX.KeyboardShortcut('[', 'Prev Page') + .setHandler(function(manager) { + if (config.prev) { + JX.$U(config.prev).go(); + } + }) + .register(); + + new JX.KeyboardShortcut(']', 'Next Page') + .setHandler(function(manager) { + if (config.next) { + JX.$U(config.next).go(); + } + }) + .register(); + +});