1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-14 02:42:40 +01:00

Share more code between tokenizers and global typeahead

Summary:
Ref T4420. Fixes T5306. Currently, the main menubar search has a lot of redundant/unshared code.

Move some common functions into `JX.Prefab.whatever()` and call them from the main search.

The major change here is that we apply the same "only show closed/disabled/archived objects if there are no matching open objects" logic, fixing T5306.

Test Plan:
  - Used normal typeaheads.
  - Used global search.
  - Searched for a prefix shared by open and archived projects, didn't see the archived ones until the open ones were exhausted.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T5306, T4420

Differential Revision: https://secure.phabricator.com/D9899
This commit is contained in:
epriestley 2014-07-17 15:52:58 -07:00
parent c52b3c28e1
commit a592b32ca4
3 changed files with 127 additions and 117 deletions

View file

@ -8,7 +8,7 @@
return array( return array(
'names' => array( 'names' => array(
'core.pkg.css' => 'c2c68e64', 'core.pkg.css' => 'c2c68e64',
'core.pkg.js' => '80884e9b', 'core.pkg.js' => '0095fb2c',
'darkconsole.pkg.js' => 'df001cab', 'darkconsole.pkg.js' => 'df001cab',
'differential.pkg.css' => '4a93db37', 'differential.pkg.css' => '4a93db37',
'differential.pkg.js' => '7528cfc9', 'differential.pkg.js' => '7528cfc9',
@ -450,7 +450,7 @@ return array(
'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca', 'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca',
'rsrc/js/core/MultirowRowManager.js' => '41e47dea', 'rsrc/js/core/MultirowRowManager.js' => '41e47dea',
'rsrc/js/core/Notification.js' => '0c6946e7', 'rsrc/js/core/Notification.js' => '0c6946e7',
'rsrc/js/core/Prefab.js' => '41ed7994', 'rsrc/js/core/Prefab.js' => 'c11bac49',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b', 'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc', 'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc',
'rsrc/js/core/ToolTip.js' => '3915d490', 'rsrc/js/core/ToolTip.js' => '3915d490',
@ -485,7 +485,7 @@ return array(
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45', 'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e', 'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7', 'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
'rsrc/js/core/behavior-search-typeahead.js' => '5a376f34', 'rsrc/js/core/behavior-search-typeahead.js' => 'd712ac5f',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6', 'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c', 'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c',
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884', 'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
@ -629,7 +629,7 @@ return array(
'javelin-behavior-phabricator-oncopy' => '2926fff2', 'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'e32d14ab', 'javelin-behavior-phabricator-remarkup-assist' => 'e32d14ab',
'javelin-behavior-phabricator-reveal-content' => '60821bc7', 'javelin-behavior-phabricator-reveal-content' => '60821bc7',
'javelin-behavior-phabricator-search-typeahead' => '5a376f34', 'javelin-behavior-phabricator-search-typeahead' => 'd712ac5f',
'javelin-behavior-phabricator-show-all-transactions' => '7c273581', 'javelin-behavior-phabricator-show-all-transactions' => '7c273581',
'javelin-behavior-phabricator-tooltips' => '3ee3408b', 'javelin-behavior-phabricator-tooltips' => '3ee3408b',
'javelin-behavior-phabricator-transaction-comment-form' => '9f7309fb', 'javelin-behavior-phabricator-transaction-comment-form' => '9f7309fb',
@ -737,7 +737,7 @@ return array(
'phabricator-notification-menu-css' => '8ae4a008', 'phabricator-notification-menu-css' => '8ae4a008',
'phabricator-object-selector-css' => '029a133d', 'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646', 'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '41ed7994', 'phabricator-prefab' => 'c11bac49',
'phabricator-profile-css' => 'b459416e', 'phabricator-profile-css' => 'b459416e',
'phabricator-remarkup-css' => 'ad4c0676', 'phabricator-remarkup-css' => 'ad4c0676',
'phabricator-search-results-css' => 'f240504c', 'phabricator-search-results-css' => 'f240504c',
@ -1126,18 +1126,6 @@ return array(
2 => 'javelin-dom', 2 => 'javelin-dom',
3 => 'javelin-util', 3 => 'javelin-util',
), ),
'41ed7994' => array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead',
4 => 'javelin-tokenizer',
5 => 'javelin-typeahead-preloaded-source',
6 => 'javelin-typeahead-ondemand-source',
7 => 'javelin-dom',
8 => 'javelin-stratcom',
9 => 'javelin-util',
),
'44168bad' => array( '44168bad' => array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
1 => 'javelin-dom', 1 => 'javelin-dom',
@ -1232,15 +1220,6 @@ return array(
2 => 'javelin-vector', 2 => 'javelin-vector',
3 => 'javelin-dom', 3 => 'javelin-dom',
), ),
'5a376f34' => array(
0 => 'javelin-behavior',
1 => 'javelin-typeahead-ondemand-source',
2 => 'javelin-typeahead',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-stratcom',
),
'5bc2cb21' => array( '5bc2cb21' => array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
1 => 'javelin-stratcom', 1 => 'javelin-stratcom',
@ -1690,6 +1669,18 @@ return array(
2 => 'javelin-util', 2 => 'javelin-util',
3 => 'phabricator-shaped-request', 3 => 'phabricator-shaped-request',
), ),
'c11bac49' => array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead',
4 => 'javelin-tokenizer',
5 => 'javelin-typeahead-preloaded-source',
6 => 'javelin-typeahead-ondemand-source',
7 => 'javelin-dom',
8 => 'javelin-stratcom',
9 => 'javelin-util',
),
'c4569c05' => array( 'c4569c05' => array(
0 => 'javelin-magical-init', 0 => 'javelin-magical-init',
1 => 'javelin-install', 1 => 'javelin-install',
@ -1764,6 +1755,16 @@ return array(
2 => 'javelin-stratcom', 2 => 'javelin-stratcom',
3 => 'javelin-dom', 3 => 'javelin-dom',
), ),
'd712ac5f' => array(
0 => 'javelin-behavior',
1 => 'javelin-typeahead-ondemand-source',
2 => 'javelin-typeahead',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-stratcom',
7 => 'phabricator-prefab',
),
'd75709e6' => array( 'd75709e6' => array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
1 => 'javelin-workflow', 1 => 'javelin-workflow',

View file

@ -31,6 +31,7 @@ JX.install('Prefab', {
return select; return select;
}, },
/** /**
* Build a Phabricator tokenizer out of a configuration with application * Build a Phabricator tokenizer out of a configuration with application
* sorting, datasource and placeholder rules. * sorting, datasource and placeholder rules.
@ -142,82 +143,9 @@ JX.install('Prefab', {
}); });
}; };
var render_icon = function(icon) {
return JX.$N(
'span',
{className: 'phui-icon-view phui-font-fa ' + icon});
};
datasource.setSortHandler(JX.bind(datasource, sort_handler)); datasource.setSortHandler(JX.bind(datasource, sort_handler));
datasource.setFilterHandler(JX.Prefab.filterClosedResults);
// Don't show any closed objects until the query is specific enough that datasource.setTransformer(JX.Prefab.transformDatasourceResults);
// it only selects closed objects. Specifically, if the result list had
// any open objects, remove all the closed objects from the list.
var filter_handler = function(value, list) {
// Look for any open result.
var has_open = false;
var ii;
for (ii = 0; ii < list.length; ii++) {
if (!list[ii].closed) {
has_open = true;
break;
}
}
if (!has_open) {
// Everything is closed, so just use it as-is.
return list;
}
// Otherwise, only display the open results.
var results = [];
for (ii = 0; ii < list.length; ii++) {
if (!list[ii].closed) {
results.push(list[ii]);
}
}
return results;
};
datasource.setFilterHandler(filter_handler);
datasource.setTransformer(
function(object) {
var closed = object[9];
var closed_ui;
if (closed) {
closed_ui = JX.$N(
'div',
{className: 'tokenizer-closed'},
closed);
}
var icon = object[8];
var icon_ui;
if (icon) {
icon_ui = render_icon(icon);
}
var display = JX.$N(
'div',
{className: 'tokenizer-result'},
[icon_ui, object[0], closed_ui]);
if (closed) {
JX.DOM.alterClass(display, 'tokenizer-result-closed', true);
}
return {
name: object[0],
display: display,
uri: object[1],
id: object[2],
priority: object[3],
priorityType: object[7],
icon: icon,
closed: closed
};
});
var typeahead = new JX.Typeahead( var typeahead = new JX.Typeahead(
root, root,
@ -238,7 +166,7 @@ JX.install('Prefab', {
return value; return value;
} }
icon = render_icon(icon); icon = JX.Prefab._renderIcon(icon);
// TODO: Maybe we should render these closed tags in grey? Figure out // TODO: Maybe we should render these closed tags in grey? Figure out
// how we're going to use color. // how we're going to use color.
@ -263,7 +191,89 @@ JX.install('Prefab', {
return { return {
tokenizer: tokenizer tokenizer: tokenizer
}; };
},
/**
* Filter callback for tokenizers and typeaheads which filters out closed
* or disabled objects unless they are the only options.
*/
filterClosedResults: function(value, list) {
// Look for any open result.
var has_open = false;
var ii;
for (ii = 0; ii < list.length; ii++) {
if (!list[ii].closed) {
has_open = true;
break;
}
}
if (!has_open) {
// Everything is closed, so just use it as-is.
return list;
}
// Otherwise, only display the open results.
var results = [];
for (ii = 0; ii < list.length; ii++) {
if (!list[ii].closed) {
results.push(list[ii]);
}
}
return results;
},
/**
* Transform results from a wire format into a usable format in a standard
* way.
*/
transformDatasourceResults: function(fields) {
var closed = fields[9];
var closed_ui;
if (closed) {
closed_ui = JX.$N(
'div',
{className: 'tokenizer-closed'},
closed);
}
var icon = fields[8];
var icon_ui;
if (icon) {
icon_ui = JX.Prefab._renderIcon(icon);
}
var display = JX.$N(
'div',
{className: 'tokenizer-result'},
[icon_ui, fields[4] || fields[0], closed_ui]);
if (closed) {
JX.DOM.alterClass(display, 'tokenizer-result-closed', true);
}
return {
name: fields[0],
displayName: fields[4] || fields[0],
display: display,
uri: fields[1],
id: fields[2],
priority: fields[3],
priorityType: fields[7],
imageURI: fields[6],
icon: icon,
closed: closed,
type: fields[5],
sprite: fields[10]
};
},
_renderIcon: function(icon) {
return JX.$N(
'span',
{className: 'phui-icon-view phui-font-fa ' + icon});
} }
} }
}); });

View file

@ -7,6 +7,7 @@
* javelin-uri * javelin-uri
* javelin-util * javelin-util
* javelin-stratcom * javelin-stratcom
* phabricator-prefab
*/ */
JX.behavior('phabricator-search-typeahead', function(config) { JX.behavior('phabricator-search-typeahead', function(config) {
@ -14,31 +15,28 @@ JX.behavior('phabricator-search-typeahead', function(config) {
var datasource = new JX.TypeaheadOnDemandSource(config.src); var datasource = new JX.TypeaheadOnDemandSource(config.src);
function transform(object) { function transform(object) {
object = JX.Prefab.transformDatasourceResults(object);
var attr = { var attr = {
className: 'phabricator-main-search-typeahead-result' className: 'phabricator-main-search-typeahead-result'
}; };
if (object[6]) { if (object.imageURI) {
attr.style = {backgroundImage: 'url('+object[6]+')'}; attr.style = {backgroundImage: 'url('+object.imageURI+')'};
} }
var render = JX.$N( var render = JX.$N(
'span', 'span',
attr, attr,
[ [
JX.$N('span', {className: object[10]}), JX.$N('span', {className: object.sprite}),
JX.$N('span', {className: 'result-name'}, object[4] || object[0]), JX.$N('span', {className: 'result-name'}, object.displayName),
JX.$N('span', {className: 'result-type'}, object[5]) JX.$N('span', {className: 'result-type'}, object.type)
]); ]);
return { object.display = render;
name: object[0],
display: render, return object;
uri: object[1],
id: object[2],
priority: object[3],
type: object[7]
};
} }
datasource.setTransformer(transform); datasource.setTransformer(transform);
@ -76,8 +74,8 @@ JX.behavior('phabricator-search-typeahead', function(config) {
} }
list.sort(function(u, v) { list.sort(function(u, v) {
var u_type = type_priority[u.type] || 999; var u_type = type_priority[u.priorityType] || 999;
var v_type = type_priority[v.type] || 999; var v_type = type_priority[v.priorityType] || 999;
if (u_type != v_type) { if (u_type != v_type) {
return u_type - v_type; return u_type - v_type;
@ -120,6 +118,7 @@ JX.behavior('phabricator-search-typeahead', function(config) {
}; };
datasource.setSortHandler(JX.bind(datasource, sort_handler)); datasource.setSortHandler(JX.bind(datasource, sort_handler));
datasource.setFilterHandler(JX.Prefab.filterClosedResults);
datasource.setMaximumResultCount(config.limit); datasource.setMaximumResultCount(config.limit);
var typeahead = new JX.Typeahead(JX.$(config.id), JX.$(config.input)); var typeahead = new JX.Typeahead(JX.$(config.id), JX.$(config.input));