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

Improve some typeahead matching behaviors

Summary:
Ref T8510. Sort prefix matches above non-prefix matches, so that "Ape Discovery" does not match "discovery" better than "Discovery".

Sort functions last.

Rename function internal strings so they don't get over-promoted the prefix-match rules.

Add kind of a hack to get "Project X" sorting above all the "Project X (Milestone 1)" results.

Test Plan:
Created "Ape Discovery", "Baboon Discovery", "Chimpanzee Discovery", etc.

Main project now sorts above milestones:

{F1681773}

Prefix matches now sort above other matches:

{F1681774}

Function results (rarely used) are now less prominent:

{F1681775}

Better function results here:

{F1681776}

More function results:

{F1681777}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T8510

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

+52 -27
+23 -23
resources/celerity/map.php
··· 8 8 return array( 9 9 'names' => array( 10 10 'core.pkg.css' => '6913fe66', 11 - 'core.pkg.js' => '3f2c120d', 11 + 'core.pkg.js' => '10275c16', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => 'f3fb8324', 14 14 'differential.pkg.js' => '4b7d8f19', ··· 258 258 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd', 259 259 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '013ffff9', 260 260 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '54f314a0', 261 - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '1bc11c4a', 261 + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => 'b25d5444', 262 262 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '6c0e62fa', 263 263 'rsrc/favicons/apple-touch-icon-120x120.png' => '43742962', 264 264 'rsrc/favicons/apple-touch-icon-152x152.png' => '669eaec3', ··· 465 465 'rsrc/js/core/KeyboardShortcutManager.js' => 'c1700f6f', 466 466 'rsrc/js/core/MultirowRowManager.js' => 'b5d57730', 467 467 'rsrc/js/core/Notification.js' => 'ccf1cbf8', 468 - 'rsrc/js/core/Prefab.js' => 'e67df814', 468 + 'rsrc/js/core/Prefab.js' => 'cfd23f37', 469 469 'rsrc/js/core/ShapedRequest.js' => '7cbe244b', 470 470 'rsrc/js/core/TextAreaUtils.js' => '320810c8', 471 471 'rsrc/js/core/Title.js' => 'df5e11d2', ··· 734 734 'javelin-typeahead-normalizer' => 'e6e25838', 735 735 'javelin-typeahead-ondemand-source' => '013ffff9', 736 736 'javelin-typeahead-preloaded-source' => '54f314a0', 737 - 'javelin-typeahead-source' => '1bc11c4a', 737 + 'javelin-typeahead-source' => 'b25d5444', 738 738 'javelin-typeahead-static-source' => '6c0e62fa', 739 739 'javelin-uri' => 'c989ade3', 740 740 'javelin-util' => '93cc50d6', ··· 785 785 'phabricator-notification-menu-css' => 'f31c0bde', 786 786 'phabricator-object-selector-css' => '85ee8ce6', 787 787 'phabricator-phtize' => 'd254d646', 788 - 'phabricator-prefab' => 'e67df814', 788 + 'phabricator-prefab' => 'cfd23f37', 789 789 'phabricator-remarkup-css' => '523d34bb', 790 790 'phabricator-search-results-css' => '7dea472c', 791 791 'phabricator-shaped-request' => '7cbe244b', ··· 1045 1045 'javelin-util', 1046 1046 'phabricator-keyboard-shortcut-manager', 1047 1047 ), 1048 - '1bc11c4a' => array( 1049 - 'javelin-install', 1050 - 'javelin-util', 1051 - 'javelin-dom', 1052 - 'javelin-typeahead-normalizer', 1053 - ), 1054 1048 '1bd28176' => array( 1055 1049 'javelin-install', 1056 1050 'javelin-dom', ··· 1779 1773 'javelin-request', 1780 1774 'phabricator-shaped-request', 1781 1775 ), 1776 + 'b25d5444' => array( 1777 + 'javelin-install', 1778 + 'javelin-util', 1779 + 'javelin-dom', 1780 + 'javelin-typeahead-normalizer', 1781 + ), 1782 1782 'b2b4fbaf' => array( 1783 1783 'javelin-behavior', 1784 1784 'javelin-dom', ··· 1932 1932 'javelin-workflow', 1933 1933 'phabricator-drag-and-drop-file-upload', 1934 1934 ), 1935 + 'cfd23f37' => array( 1936 + 'javelin-install', 1937 + 'javelin-util', 1938 + 'javelin-dom', 1939 + 'javelin-typeahead', 1940 + 'javelin-tokenizer', 1941 + 'javelin-typeahead-preloaded-source', 1942 + 'javelin-typeahead-ondemand-source', 1943 + 'javelin-dom', 1944 + 'javelin-stratcom', 1945 + 'javelin-util', 1946 + ), 1935 1947 'd0c516d5' => array( 1936 1948 'javelin-behavior', 1937 1949 'javelin-dom', ··· 2076 2088 'javelin-json', 2077 2089 'javelin-workflow', 2078 2090 'javelin-magical-init', 2079 - ), 2080 - 'e67df814' => array( 2081 - 'javelin-install', 2082 - 'javelin-util', 2083 - 'javelin-dom', 2084 - 'javelin-typeahead', 2085 - 'javelin-tokenizer', 2086 - 'javelin-typeahead-preloaded-source', 2087 - 'javelin-typeahead-ondemand-source', 2088 - 'javelin-dom', 2089 - 'javelin-stratcom', 2090 - 'javelin-util', 2091 2091 ), 2092 2092 'e6e25838' => array( 2093 2093 'javelin-install',
+5
src/applications/project/typeahead/PhabricatorProjectDatasource.php
··· 84 84 85 85 $all_strings = array(); 86 86 $all_strings[] = $proj->getDisplayName(); 87 + 88 + // Add an extra space after the name so that the original project 89 + // sorts ahead of milestones. This is kind of a hack but ehh? 90 + $all_strings[] = null; 91 + 87 92 foreach ($proj->getSlugs() as $project_slug) { 88 93 $all_strings[] = $project_slug->getSlug(); 89 94 }
+2 -2
src/applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php
··· 92 92 $return[] = id(clone $result) 93 93 ->setPHID('any('.$result->getPHID().')') 94 94 ->setDisplayName(pht('In Any: %s', $result->getDisplayName())) 95 - ->setName($result->getName().' any'); 95 + ->setName('any '.$result->getName()); 96 96 } 97 97 98 98 if ($return_not) { 99 99 $return[] = id(clone $result) 100 100 ->setPHID('not('.$result->getPHID().')') 101 101 ->setDisplayName(pht('Not In: %s', $result->getDisplayName())) 102 - ->setName($result->getName().' not'); 102 + ->setName('not '.$result->getName()); 103 103 } 104 104 } 105 105
+1 -1
src/applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php
··· 46 46 ->setIcon('fa-asterisk') 47 47 ->setPHID('projects('.$result->getPHID().')') 48 48 ->setDisplayName(pht("User's Projects: %s", $result->getDisplayName())) 49 - ->setName($result->getName().' projects'); 49 + ->setName('projects '.$result->getName()); 50 50 } 51 51 52 52 return $results;
+1 -1
webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
··· 357 357 if (!str.length) { 358 358 return []; 359 359 } 360 - return str.split(/\s/g); 360 + return str.split(/\s+/g); 361 361 }, 362 362 _defaultTransformer : function(object) { 363 363 return {
+20
webroot/rsrc/js/core/Prefab.js
··· 184 184 var priority_hits = {}; 185 185 var self_hits = {}; 186 186 187 + // We'll put matches where the user's input is a prefix of the name 188 + // above mathches where that isn't true. 189 + var prefix_hits = {}; 190 + 187 191 var tokens = this.tokenize(value); 192 + var normal = this.normalize(value); 188 193 189 194 for (var ii = 0; ii < list.length; ii++) { 190 195 var item = list[ii]; 196 + 197 + if (this.normalize(item.name).indexOf(normal) === 0) { 198 + prefix_hits[item.id] = true; 199 + } 191 200 192 201 for (var jj = 0; jj < tokens.length; jj++) { 193 202 if (item.name.indexOf(tokens[jj]) === 0) { ··· 237 246 return priority_hits[v.id] ? 1 : -1; 238 247 } 239 248 249 + if (prefix_hits[u.id] != prefix_hits[v.id]) { 250 + return prefix_hits[v.id] ? 1 : -1; 251 + } 252 + 240 253 // Sort users ahead of other result types. 241 254 if (u.priorityType != v.priorityType) { 242 255 if (u.priorityType == 'user') { ··· 245 258 if (v.priorityType == 'user') { 246 259 return 1; 247 260 } 261 + } 262 + 263 + // Sort functions after other result types. 264 + var uf = (u.tokenType == 'function'); 265 + var vf = (v.tokenType == 'function'); 266 + if (uf != vf) { 267 + return uf ? 1 : -1; 248 268 } 249 269 250 270 return cmp(u, v);