mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 02:32:42 +01:00
Change All Search Boxes into Jump Navs
Summary: - all search boxes are now jump navs (old functionality retained if none of the jump nav patterns match) - added global keyboard shortcut '/' to focus the search box in the upper right Test Plan: - pressed '/' and noticed the search box gains keyboard focus - triggered jump nav functionality from search box and saw it worked - did a search which did not match a jump nav pattern and saw it worked (and searched in the selected context) NOTE: The search box on the /search/ page is also changed to have jump nav functionality. Old functionality is not impared. Still, this may not be desirable. Reviewers: epriestley, btrahan Reviewed By: epriestley CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1794
This commit is contained in:
parent
831133e880
commit
639ed0faa6
13 changed files with 242 additions and 212 deletions
|
@ -788,7 +788,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' =>
|
||||
array(
|
||||
'uri' => '/res/94b009e2/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||
'uri' => '/res/ea3ea05e/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1542,7 +1542,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-keyboard-shortcut-manager' =>
|
||||
array(
|
||||
'uri' => '/res/04767571/rsrc/js/application/core/KeyboardShortcutManager.js',
|
||||
'uri' => '/res/0be80136/rsrc/js/application/core/KeyboardShortcutManager.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1984,28 +1984,6 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/8d8e1030/differential.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'adcb05b5' =>
|
||||
array(
|
||||
'name' => 'core.pkg.js',
|
||||
'symbols' =>
|
||||
array(
|
||||
0 => 'javelin-mask',
|
||||
1 => 'javelin-workflow',
|
||||
2 => 'javelin-behavior-workflow',
|
||||
3 => 'javelin-behavior-aphront-form-disable-on-submit',
|
||||
4 => 'phabricator-keyboard-shortcut-manager',
|
||||
5 => 'phabricator-keyboard-shortcut',
|
||||
6 => 'javelin-behavior-phabricator-keyboard-shortcuts',
|
||||
7 => 'javelin-behavior-refresh-csrf',
|
||||
8 => 'javelin-behavior-phabricator-watch-anchor',
|
||||
9 => 'javelin-behavior-phabricator-autofocus',
|
||||
10 => 'phabricator-paste-file-upload',
|
||||
11 => 'phabricator-menu-item',
|
||||
12 => 'phabricator-dropdown-menu',
|
||||
),
|
||||
'uri' => '/res/pkg/adcb05b5/core.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'ae7ea233' =>
|
||||
array(
|
||||
'name' => 'typeahead.pkg.js',
|
||||
|
@ -2063,6 +2041,28 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/31583232/maniphest.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
95944588 =>
|
||||
array(
|
||||
'name' => 'core.pkg.js',
|
||||
'symbols' =>
|
||||
array(
|
||||
0 => 'javelin-mask',
|
||||
1 => 'javelin-workflow',
|
||||
2 => 'javelin-behavior-workflow',
|
||||
3 => 'javelin-behavior-aphront-form-disable-on-submit',
|
||||
4 => 'phabricator-keyboard-shortcut-manager',
|
||||
5 => 'phabricator-keyboard-shortcut',
|
||||
6 => 'javelin-behavior-phabricator-keyboard-shortcuts',
|
||||
7 => 'javelin-behavior-refresh-csrf',
|
||||
8 => 'javelin-behavior-phabricator-watch-anchor',
|
||||
9 => 'javelin-behavior-phabricator-autofocus',
|
||||
10 => 'phabricator-paste-file-upload',
|
||||
11 => 'phabricator-menu-item',
|
||||
12 => 'phabricator-dropdown-menu',
|
||||
),
|
||||
'uri' => '/res/pkg/95944588/core.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
),
|
||||
'reverse' =>
|
||||
array(
|
||||
|
@ -2093,7 +2093,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-aphront-basic-tokenizer' => 'ae7ea233',
|
||||
'javelin-behavior-aphront-drag-and-drop' => '8d8e1030',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => '8d8e1030',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => 'adcb05b5',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => '95944588',
|
||||
'javelin-behavior-buoyant' => '8d8e1030',
|
||||
'javelin-behavior-differential-accept-with-errors' => '8d8e1030',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => '8d8e1030',
|
||||
|
@ -2109,17 +2109,17 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-maniphest-transaction-controls' => '0ed3e020',
|
||||
'javelin-behavior-maniphest-transaction-expand' => '0ed3e020',
|
||||
'javelin-behavior-maniphest-transaction-preview' => '0ed3e020',
|
||||
'javelin-behavior-phabricator-autofocus' => 'adcb05b5',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => 'adcb05b5',
|
||||
'javelin-behavior-phabricator-autofocus' => '95944588',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => '95944588',
|
||||
'javelin-behavior-phabricator-object-selector' => '8d8e1030',
|
||||
'javelin-behavior-phabricator-watch-anchor' => 'adcb05b5',
|
||||
'javelin-behavior-refresh-csrf' => 'adcb05b5',
|
||||
'javelin-behavior-workflow' => 'adcb05b5',
|
||||
'javelin-behavior-phabricator-watch-anchor' => '95944588',
|
||||
'javelin-behavior-refresh-csrf' => '95944588',
|
||||
'javelin-behavior-workflow' => '95944588',
|
||||
'javelin-dom' => '4fbae2af',
|
||||
'javelin-event' => '4fbae2af',
|
||||
'javelin-install' => '4fbae2af',
|
||||
'javelin-json' => '4fbae2af',
|
||||
'javelin-mask' => 'adcb05b5',
|
||||
'javelin-mask' => '95944588',
|
||||
'javelin-request' => '4fbae2af',
|
||||
'javelin-stratcom' => '4fbae2af',
|
||||
'javelin-tokenizer' => 'ae7ea233',
|
||||
|
@ -2131,7 +2131,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-uri' => '4fbae2af',
|
||||
'javelin-util' => '4fbae2af',
|
||||
'javelin-vector' => '4fbae2af',
|
||||
'javelin-workflow' => 'adcb05b5',
|
||||
'javelin-workflow' => '95944588',
|
||||
'maniphest-task-detail-css' => '31583232',
|
||||
'maniphest-task-summary-css' => '31583232',
|
||||
'maniphest-transaction-detail-css' => '31583232',
|
||||
|
@ -2141,13 +2141,13 @@ celerity_register_resource_map(array(
|
|||
'phabricator-core-css' => 'e2934828',
|
||||
'phabricator-directory-css' => 'e2934828',
|
||||
'phabricator-drag-and-drop-file-upload' => '8d8e1030',
|
||||
'phabricator-dropdown-menu' => 'adcb05b5',
|
||||
'phabricator-dropdown-menu' => '95944588',
|
||||
'phabricator-jump-nav' => 'e2934828',
|
||||
'phabricator-keyboard-shortcut' => 'adcb05b5',
|
||||
'phabricator-keyboard-shortcut-manager' => 'adcb05b5',
|
||||
'phabricator-menu-item' => 'adcb05b5',
|
||||
'phabricator-keyboard-shortcut' => '95944588',
|
||||
'phabricator-keyboard-shortcut-manager' => '95944588',
|
||||
'phabricator-menu-item' => '95944588',
|
||||
'phabricator-object-selector-css' => '09c86840',
|
||||
'phabricator-paste-file-upload' => 'adcb05b5',
|
||||
'phabricator-paste-file-upload' => '95944588',
|
||||
'phabricator-remarkup-css' => 'e2934828',
|
||||
'phabricator-shaped-request' => '8d8e1030',
|
||||
'phabricator-standard-page-view' => 'e2934828',
|
||||
|
|
|
@ -584,6 +584,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorImageTransformer' => 'applications/files/transform',
|
||||
'PhabricatorInfrastructureTestCase' => 'infrastructure/__tests__',
|
||||
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/javelin',
|
||||
'PhabricatorJumpNavHandler' => 'applications/search/engine/jumpnav',
|
||||
'PhabricatorLintEngine' => 'infrastructure/lint/engine',
|
||||
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
|
||||
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/localdisk',
|
||||
|
@ -696,7 +697,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
|
||||
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
|
||||
'PhabricatorProjectQuery' => 'applications/project/query/project',
|
||||
'PhabricatorProjectQueryUtil' => 'applications/project/query/util',
|
||||
'PhabricatorProjectStatus' => 'applications/project/constants/status',
|
||||
'PhabricatorProjectSubproject' => 'applications/project/storage/subproject',
|
||||
'PhabricatorProjectTransaction' => 'applications/project/storage/transaction',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,6 +18,8 @@
|
|||
|
||||
/**
|
||||
* @group console
|
||||
* @phutil-external-symbol function xhprof_enable
|
||||
* @phutil-external-symbol function xhprof_disable
|
||||
*/
|
||||
final class DarkConsoleXHProfPluginAPI {
|
||||
|
||||
|
|
|
@ -105,76 +105,11 @@ class PhabricatorDirectoryMainController
|
|||
|
||||
if ($request->isFormPost()) {
|
||||
$jump = $request->getStr('jump');
|
||||
$jump = trim($jump);
|
||||
|
||||
$help_href = PhabricatorEnv::getDocLink(
|
||||
'article/Jump_Nav_User_Guide.html');
|
||||
|
||||
$patterns = array(
|
||||
'/^help/i' => 'uri:'.$help_href,
|
||||
'/^d$/i' => 'uri:/differential/',
|
||||
'/^r$/i' => 'uri:/diffusion/',
|
||||
'/^t$/i' => 'uri:/maniphest/',
|
||||
'/^p$/i' => 'uri:/project/',
|
||||
'/^u$/i' => 'uri:/people/',
|
||||
'/^r([A-Z]+)$/' => 'repository',
|
||||
'/^r([A-Z]+)(\S+)$/' => 'commit',
|
||||
'/^d(\d+)$/i' => 'revision',
|
||||
'/^t(\d+)$/i' => 'task',
|
||||
'/^p\s+(.+)$/i' => 'project',
|
||||
'/^u\s+(\S+)$/i' => 'user',
|
||||
'/^task:\s*(.+)/i' => 'create-task',
|
||||
'/^(?:s|symbol)\s+(\S+)/i' => 'find-symbol',
|
||||
);
|
||||
|
||||
|
||||
foreach ($patterns as $pattern => $effect) {
|
||||
$matches = null;
|
||||
if (preg_match($pattern, $jump, $matches)) {
|
||||
if (!strncmp($effect, 'uri:', 4)) {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI(substr($effect, 4));
|
||||
$response = PhabricatorJumpNavHandler::jumpPostResponse($jump);
|
||||
if ($response) {
|
||||
return $response;
|
||||
} else {
|
||||
switch ($effect) {
|
||||
case 'repository':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/diffusion/'.$matches[1].'/');
|
||||
case 'commit':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/'.$matches[0]);
|
||||
case 'revision':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/D'.$matches[1]);
|
||||
case 'task':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/T'.$matches[1]);
|
||||
case 'user':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/p/'.$matches[1].'/');
|
||||
case 'project':
|
||||
$project = PhabricatorProjectQueryUtil
|
||||
::findCloselyNamedProject($matches[1]);
|
||||
if ($project) {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/project/view/'.$project->getID().'/');
|
||||
} else {
|
||||
$jump = $matches[1];
|
||||
}
|
||||
break;
|
||||
case 'find-symbol':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/diffusion/symbol/'.$matches[1].'/?jump=true');
|
||||
case 'create-task':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/maniphest/task/create/?title='
|
||||
.phutil_escape_uri($matches[1]));
|
||||
default:
|
||||
throw new Exception("Unknown jump effect '{$effect}'!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query = new PhabricatorSearchQuery();
|
||||
$query->setQuery($jump);
|
||||
$query->save();
|
||||
|
@ -182,6 +117,7 @@ class PhabricatorDirectoryMainController
|
|||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/search/'.$query->getQueryKey().'/');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$nav->appendChild($this->buildJumpPanel());
|
||||
|
|
|
@ -22,7 +22,7 @@ phutil_require_module('phabricator', 'applications/maniphest/query');
|
|||
phutil_require_module('phabricator', 'applications/maniphest/view/tasklist');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/project/query/project');
|
||||
phutil_require_module('phabricator', 'applications/project/query/util');
|
||||
phutil_require_module('phabricator', 'applications/search/engine/jumpnav');
|
||||
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorProjectQueryUtil {
|
||||
public static function findCloselyNamedProject($name) {
|
||||
$project = id(new PhabricatorProject())->loadOneWhere(
|
||||
'name = %s',
|
||||
name);
|
||||
if ($project) {
|
||||
return $project;
|
||||
} else { // no exact match, try a fuzzy match
|
||||
$projects = id(new PhabricatorProject())->loadAllWhere(
|
||||
'name LIKE %~',
|
||||
$name);
|
||||
if ($projects) {
|
||||
$min_name_length = PHP_INT_MAX;
|
||||
$best_project = null;
|
||||
foreach ($projects as $project) {
|
||||
$name_length = strlen($project->getName());
|
||||
if ($name_length <= $min_name_length) {
|
||||
$min_name_length = $name_length;
|
||||
$best_project = $project;
|
||||
}
|
||||
}
|
||||
return $best_project;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
* @group search
|
||||
*/
|
||||
class PhabricatorSearchController extends PhabricatorSearchBaseController {
|
||||
|
||||
private $key;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
|
@ -42,7 +41,12 @@ class PhabricatorSearchController extends PhabricatorSearchBaseController {
|
|||
$query = new PhabricatorSearchQuery();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$query->setQuery($request->getStr('query'));
|
||||
$query_str = $request->getStr('query');
|
||||
$response = PhabricatorJumpNavHandler::jumpPostResponse($query_str);
|
||||
if ($response) {
|
||||
return $response;
|
||||
} else {
|
||||
$query->setQuery($query_str);
|
||||
|
||||
if ($request->getStr('scope')) {
|
||||
switch ($request->getStr('scope')) {
|
||||
|
@ -98,6 +102,7 @@ class PhabricatorSearchController extends PhabricatorSearchBaseController {
|
|||
->setURI('/search/'.$query->getQueryKey().'/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$more = PhabricatorEnv::getEnvConfig('search.more-document-types', array());
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ phutil_require_module('phabricator', 'applications/phid/constants');
|
|||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/search/constants/scope');
|
||||
phutil_require_module('phabricator', 'applications/search/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/search/engine/jumpnav');
|
||||
phutil_require_module('phabricator', 'applications/search/selector/base');
|
||||
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||
phutil_require_module('phabricator', 'applications/search/view/searchresult');
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorJumpNavHandler {
|
||||
public static function jumpPostResponse($jump) {
|
||||
$jump = trim($jump);
|
||||
$help_href = PhabricatorEnv::getDocLink(
|
||||
'article/Jump_Nav_User_Guide.html');
|
||||
|
||||
$patterns = array(
|
||||
'/^help/i' => 'uri:'.$help_href,
|
||||
'/^d$/i' => 'uri:/differential/',
|
||||
'/^r$/i' => 'uri:/diffusion/',
|
||||
'/^t$/i' => 'uri:/maniphest/',
|
||||
'/^p$/i' => 'uri:/project/',
|
||||
'/^u$/i' => 'uri:/people/',
|
||||
'/^r([A-Z]+)$/' => 'repository',
|
||||
'/^r([A-Z]+)(\S+)$/' => 'commit',
|
||||
'/^d(\d+)$/i' => 'revision',
|
||||
'/^t(\d+)$/i' => 'task',
|
||||
'/^p\s+(.+)$/i' => 'project',
|
||||
'/^u\s+(\S+)$/i' => 'user',
|
||||
'/^task:\s*(.+)/i' => 'create-task',
|
||||
'/^(?:s|symbol)\s+(\S+)/i' => 'find-symbol',
|
||||
);
|
||||
|
||||
|
||||
foreach ($patterns as $pattern => $effect) {
|
||||
$matches = null;
|
||||
if (preg_match($pattern, $jump, $matches)) {
|
||||
if (!strncmp($effect, 'uri:', 4)) {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI(substr($effect, 4));
|
||||
} else {
|
||||
switch ($effect) {
|
||||
case 'repository':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/diffusion/'.$matches[1].'/');
|
||||
case 'commit':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/'.$matches[0]);
|
||||
case 'revision':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/D'.$matches[1]);
|
||||
case 'task':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/T'.$matches[1]);
|
||||
case 'user':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/p/'.$matches[1].'/');
|
||||
case 'project':
|
||||
$project = static::findCloselyNamedProject($matches[1]);
|
||||
if ($project) {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/project/view/'.$project->getID().'/');
|
||||
} else {
|
||||
$jump = $matches[1];
|
||||
}
|
||||
break;
|
||||
case 'find-symbol':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/diffusion/symbol/'.$matches[1].'/?jump=true');
|
||||
case 'create-task':
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/maniphest/task/create/?title='
|
||||
.phutil_escape_uri($matches[1]));
|
||||
default:
|
||||
throw new Exception("Unknown jump effect '{$effect}'!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function findCloselyNamedProject($name) {
|
||||
$project = id(new PhabricatorProject())->loadOneWhere(
|
||||
'name = %s',
|
||||
name);
|
||||
if ($project) {
|
||||
return $project;
|
||||
} else { // no exact match, try a fuzzy match
|
||||
$projects = id(new PhabricatorProject())->loadAllWhere(
|
||||
'name LIKE %~',
|
||||
$name);
|
||||
if ($projects) {
|
||||
$min_name_length = PHP_INT_MAX;
|
||||
$best_project = null;
|
||||
foreach ($projects as $project) {
|
||||
$name_length = strlen($project->getName());
|
||||
if ($name_length <= $min_name_length) {
|
||||
$min_name_length = $name_length;
|
||||
$best_project = $project;
|
||||
}
|
||||
}
|
||||
return $best_project;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectQueryUtil.php');
|
||||
phutil_require_source('PhabricatorJumpNavHandler.php');
|
|
@ -288,7 +288,7 @@ class PhabricatorStandardPageView extends AphrontPageView {
|
|||
'method' => 'post',
|
||||
'style' => 'display: inline',
|
||||
),
|
||||
'<input type="text" name="query" />'.
|
||||
'<input type="text" name="query" id="standard-search-box" />'.
|
||||
' in '.
|
||||
AphrontFormSelectControl::renderSelectTag(
|
||||
$this->getSearchDefaultScope(),
|
||||
|
|
|
@ -122,6 +122,7 @@ JX.install('KeyboardShortcutManager', {
|
|||
for (var jj = 0; jj < keys.length; jj++) {
|
||||
if (keys[jj] == key) {
|
||||
shortcuts[ii].getHandler()(this);
|
||||
e.kill(); // Consume the event
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,4 +28,14 @@ JX.behavior('phabricator-keyboard-shortcuts', function(config) {
|
|||
workflow.start();
|
||||
})
|
||||
.register();
|
||||
|
||||
desc = 'Give keyboard focus to the search box.';
|
||||
new JX.KeyboardShortcut('/', desc)
|
||||
.setHandler(function() {
|
||||
var search = JX.$("standard-search-box");
|
||||
search.focus();
|
||||
search.select();
|
||||
})
|
||||
.register();
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue