Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15425600
D12446.id29868.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D12446.id29868.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,8 +7,8 @@
*/
return array(
'names' => array(
- 'core.pkg.css' => '743edc44',
- 'core.pkg.js' => '42315bf4',
+ 'core.pkg.css' => '7870a8c5',
+ 'core.pkg.js' => 'b00140fe',
'darkconsole.pkg.js' => '8ab24e01',
'differential.pkg.css' => '3500921f',
'differential.pkg.js' => 'c0506961',
@@ -27,7 +27,7 @@
'rsrc/css/aphront/panel-view.css' => '8427b78d',
'rsrc/css/aphront/phabricator-nav-view.css' => '7aeaf435',
'rsrc/css/aphront/table-view.css' => '59e2c0f8',
- 'rsrc/css/aphront/tokenizer.css' => '95e931ab',
+ 'rsrc/css/aphront/tokenizer.css' => '6fd738ea',
'rsrc/css/aphront/tooltip.css' => '7672b60f',
'rsrc/css/aphront/two-column.css' => '16ab3ad2',
'rsrc/css/aphront/typeahead-browse.css' => '343ab59f',
@@ -222,7 +222,7 @@
'rsrc/externals/javelin/lib/__tests__/URI.js' => '1e45fda9',
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
- 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '0fd17937',
+ 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'dc708b7e',
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '70baed2f',
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'e6e25838',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
@@ -450,7 +450,7 @@
'rsrc/js/core/KeyboardShortcutManager.js' => 'c1700f6f',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => '0c6946e7',
- 'rsrc/js/core/Prefab.js' => 'd339753f',
+ 'rsrc/js/core/Prefab.js' => '4c292cc5',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => '5c93c52c',
'rsrc/js/core/Title.js' => 'df5e11d2',
@@ -510,7 +510,7 @@
'aphront-pager-view-css' => '2e3539af',
'aphront-panel-view-css' => '8427b78d',
'aphront-table-view-css' => '59e2c0f8',
- 'aphront-tokenizer-control-css' => '95e931ab',
+ 'aphront-tokenizer-control-css' => '6fd738ea',
'aphront-tooltip-css' => '7672b60f',
'aphront-two-column-view-css' => '16ab3ad2',
'aphront-typeahead-control-css' => '0e403212',
@@ -689,7 +689,7 @@
'javelin-scrollbar' => 'eaa5b321',
'javelin-sound' => '949c0fe5',
'javelin-stratcom' => '6c53634d',
- 'javelin-tokenizer' => '0fd17937',
+ 'javelin-tokenizer' => 'dc708b7e',
'javelin-typeahead' => '70baed2f',
'javelin-typeahead-composite-source' => '503e17fd',
'javelin-typeahead-normalizer' => 'e6e25838',
@@ -744,7 +744,7 @@
'phabricator-notification-menu-css' => '3c9d8aa1',
'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646',
- 'phabricator-prefab' => 'd339753f',
+ 'phabricator-prefab' => '4c292cc5',
'phabricator-profile-css' => '1a20dcbf',
'phabricator-remarkup-css' => 'bc65f3cc',
'phabricator-search-results-css' => '15c71110',
@@ -921,12 +921,6 @@
'javelin-install',
'javelin-util',
),
- '0fd17937' => array(
- 'javelin-dom',
- 'javelin-util',
- 'javelin-stratcom',
- 'javelin-install',
- ),
'13c739ea' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1158,6 +1152,18 @@
'4a2430d7' => array(
'phui-fontkit-css',
),
+ '4c292cc5' => array(
+ 'javelin-install',
+ 'javelin-util',
+ 'javelin-dom',
+ 'javelin-typeahead',
+ 'javelin-tokenizer',
+ 'javelin-typeahead-preloaded-source',
+ 'javelin-typeahead-ondemand-source',
+ 'javelin-dom',
+ 'javelin-stratcom',
+ 'javelin-util',
+ ),
'4d94d9c3' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1339,6 +1345,9 @@
'javelin-vector',
'javelin-stratcom',
),
+ '6fd738ea' => array(
+ 'aphront-typeahead-control-css',
+ ),
'70baed2f' => array(
'javelin-install',
'javelin-dom',
@@ -1587,9 +1596,6 @@
'javelin-resource',
'javelin-routable',
),
- '95e931ab' => array(
- 'aphront-typeahead-control-css',
- ),
'988040b4' => array(
'javelin-install',
'javelin-dom',
@@ -1793,18 +1799,6 @@
'd254d646' => array(
'javelin-util',
),
- 'd339753f' => array(
- 'javelin-install',
- 'javelin-util',
- 'javelin-dom',
- 'javelin-typeahead',
- 'javelin-tokenizer',
- 'javelin-typeahead-preloaded-source',
- 'javelin-typeahead-ondemand-source',
- 'javelin-dom',
- 'javelin-stratcom',
- 'javelin-util',
- ),
'd4505101' => array(
'javelin-stratcom',
'javelin-install',
@@ -1840,6 +1834,12 @@
'javelin-dom',
'phabricator-busy',
),
+ 'dc708b7e' => array(
+ 'javelin-dom',
+ 'javelin-util',
+ 'javelin-stratcom',
+ 'javelin-install',
+ ),
'de2e896f' => array(
'javelin-behavior',
'javelin-dom',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1206,6 +1206,7 @@
'PHUITimelineEventView' => 'view/phui/PHUITimelineEventView.php',
'PHUITimelineExample' => 'applications/uiexample/examples/PHUITimelineExample.php',
'PHUITimelineView' => 'view/phui/PHUITimelineView.php',
+ 'PHUITypeaheadExample' => 'applications/uiexample/examples/PHUITypeaheadExample.php',
'PHUIWorkboardView' => 'view/phui/PHUIWorkboardView.php',
'PHUIWorkpanelView' => 'view/phui/PHUIWorkpanelView.php',
'PackageCreateMail' => 'applications/owners/mail/PackageCreateMail.php',
@@ -4489,6 +4490,7 @@
'PHUITimelineEventView' => 'AphrontView',
'PHUITimelineExample' => 'PhabricatorUIExample',
'PHUITimelineView' => 'AphrontView',
+ 'PHUITypeaheadExample' => 'PhabricatorUIExample',
'PHUIWorkboardView' => 'AphrontTagView',
'PHUIWorkpanelView' => 'AphrontTagView',
'PackageCreateMail' => 'PackageMail',
diff --git a/src/applications/people/typeahead/PhabricatorViewerDatasource.php b/src/applications/people/typeahead/PhabricatorViewerDatasource.php
--- a/src/applications/people/typeahead/PhabricatorViewerDatasource.php
+++ b/src/applications/people/typeahead/PhabricatorViewerDatasource.php
@@ -50,6 +50,7 @@
return $this->newFunctionResult()
->setName(pht('Current Viewer'))
->setPHID('viewer()')
+ ->setIcon('fa-user')
->setUnique(true);
}
diff --git a/src/applications/phid/PhabricatorObjectHandle.php b/src/applications/phid/PhabricatorObjectHandle.php
--- a/src/applications/phid/PhabricatorObjectHandle.php
+++ b/src/applications/phid/PhabricatorObjectHandle.php
@@ -56,9 +56,17 @@
if ($this->tagColor) {
return $this->tagColor;
}
+
return 'blue';
}
+ public function getIconColor() {
+ if ($this->tagColor) {
+ return $this->tagColor;
+ }
+ return null;
+ }
+
public function getTypeIcon() {
if ($this->getPHIDType()) {
return $this->getPHIDType()->getTypeIcon();
diff --git a/src/applications/project/typeahead/PhabricatorProjectDatasource.php b/src/applications/project/typeahead/PhabricatorProjectDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectDatasource.php
@@ -63,7 +63,7 @@
->setDisplayType('Project')
->setURI('/tag/'.$proj->getPrimarySlug().'/')
->setPHID($proj->getPHID())
- ->setIcon($proj->getIcon().' bluegrey')
+ ->setIcon($proj->getIcon().' '.$proj->getColor())
->setPriorityType('proj')
->setClosed($closed);
diff --git a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
@@ -116,6 +116,7 @@
->setDisplayName(pht('Members: %s', $project->getName()))
->setURI('/tag/'.$project->getPrimarySlug().'/')
->setPHID('members('.$project->getPHID().')')
+ ->setIcon('fa-users')
->setClosed($closed);
}
diff --git a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
--- a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
+++ b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
@@ -187,16 +187,16 @@
}
protected function newFunctionResult() {
- // TODO: Find a more consistent design.
return id(new PhabricatorTypeaheadResult())
- ->setIcon('fa-magic indigo');
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setIcon('fa-asterisk');
}
public function newInvalidToken($name) {
return id(new PhabricatorTypeaheadTokenView())
- ->setKey(PhabricatorTypeaheadTokenView::KEY_INVALID)
->setValue($name)
- ->setIcon('fa-exclamation-circle red');
+ ->setIcon('fa-exclamation-circle')
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_INVALID);
}
/* -( Token Functions )---------------------------------------------------- */
diff --git a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
--- a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
+++ b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
@@ -13,6 +13,7 @@
private $imageSprite;
private $icon;
private $closed;
+ private $tokenType;
private $unique;
public function setIcon($icon) {
@@ -91,6 +92,18 @@
return $this;
}
+ public function setTokenType($type) {
+ $this->tokenType = $type;
+ return $this;
+ }
+
+ public function getTokenType() {
+ if ($this->closed && !$this->tokenType) {
+ return PhabricatorTypeaheadTokenView::TYPE_DISABLED;
+ }
+ return $this->tokenType;
+ }
+
public function getSortKey() {
// Put unique results (special parameter functions) ahead of other
// results.
@@ -116,6 +129,7 @@
$this->getIcon(),
$this->closed,
$this->imageSprite ? (string)$this->imageSprite : null,
+ $this->tokenType,
$this->unique ? 1 : null,
);
while (end($data) === null) {
diff --git a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
--- a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
+++ b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
@@ -3,12 +3,16 @@
final class PhabricatorTypeaheadTokenView
extends AphrontTagView {
+ const TYPE_OBJECT = 'object';
+ const TYPE_DISABLED = 'disabled';
+ const TYPE_FUNCTION = 'function';
+ const TYPE_INVALID = 'invalid';
+
private $key;
private $icon;
private $inputName;
private $value;
-
- const KEY_INVALID = '<invalid>';
+ private $tokenType = self::TYPE_OBJECT;
public static function newFromTypeaheadResult(
PhabricatorTypeaheadResult $result) {
@@ -16,16 +20,24 @@
return id(new PhabricatorTypeaheadTokenView())
->setKey($result->getPHID())
->setIcon($result->getIcon())
- ->setValue($result->getDisplayName());
+ ->setValue($result->getDisplayName())
+ ->setTokenType($result->getTokenType());
}
public static function newFromHandle(
PhabricatorObjectHandle $handle) {
- return id(new PhabricatorTypeaheadTokenView())
+ $token = id(new PhabricatorTypeaheadTokenView())
->setKey($handle->getPHID())
->setValue($handle->getFullName())
- ->setIcon($handle->getIcon());
+ ->setIcon(rtrim($handle->getIcon().' '.$handle->getIconColor()));
+
+ if ($handle->isDisabled() ||
+ $handle->getStatus() == PhabricatorObjectHandleStatus::STATUS_CLOSED) {
+ $token->setTokenType(self::TYPE_DISABLED);
+ }
+
+ return $token;
}
public function setKey($key) {
@@ -37,6 +49,15 @@
return $this->key;
}
+ public function setTokenType($token_type) {
+ $this->tokenType = $token_type;
+ return $this;
+ }
+
+ public function getTokenType() {
+ return $this->tokenType;
+ }
+
public function setInputName($input_name) {
$this->inputName = $input_name;
return $this;
@@ -69,8 +90,25 @@
}
protected function getTagAttributes() {
+ $classes = array();
+ $classes[] = 'jx-tokenizer-token';
+ switch ($this->getTokenType()) {
+ case self::TYPE_FUNCTION:
+ $classes[] = 'jx-tokenizer-token-function';
+ break;
+ case self::TYPE_INVALID:
+ $classes[] = 'jx-tokenizer-token-invalid';
+ break;
+ case self::TYPE_DISABLED:
+ $classes[] = 'jx-tokenizer-token-disabled';
+ break;
+ case self::TYPE_OBJECT:
+ default:
+ break;
+ }
+
return array(
- 'class' => 'jx-tokenizer-token',
+ 'class' => $classes,
);
}
diff --git a/src/applications/uiexample/examples/PHUITypeaheadExample.php b/src/applications/uiexample/examples/PHUITypeaheadExample.php
new file mode 100644
--- /dev/null
+++ b/src/applications/uiexample/examples/PHUITypeaheadExample.php
@@ -0,0 +1,57 @@
+<?php
+
+final class PHUITypeaheadExample extends PhabricatorUIExample {
+
+ public function getName() {
+ return 'Typeaheads';
+ }
+
+ public function getDescription() {
+ return pht('Typeaheads, tokenizers and tokens.');
+ }
+
+ public function renderExample() {
+
+ $token_list = array();
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Normal Object'))
+ ->setIcon('fa-user');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Disabled Object'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_DISABLED)
+ ->setIcon('fa-user');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Custom Object'))
+ ->setIcon('fa-tag green');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Function Token'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setIcon('fa-users');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Invalid Token'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_INVALID)
+ ->setIcon('fa-exclamation-circle');
+
+
+ $token_list = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'grouped',
+ 'style' => 'padding: 8px',
+ ),
+ $token_list);
+
+ $output = array();
+
+ $output[] = id(new PHUIObjectBoxView())
+ ->setHeaderText('Tokens')
+ ->appendChild($token_list);
+
+ return $output;
+ }
+}
diff --git a/src/view/form/control/AphrontFormTokenizerControl.php b/src/view/form/control/AphrontFormTokenizerControl.php
--- a/src/view/form/control/AphrontFormTokenizerControl.php
+++ b/src/view/form/control/AphrontFormTokenizerControl.php
@@ -51,7 +51,9 @@
}
$datasource = $this->datasource;
- $datasource->setViewer($this->getUser());
+ if ($datasource) {
+ $datasource->setViewer($this->getUser());
+ }
$placeholder = null;
if (!strlen($this->placeholder)) {
@@ -84,7 +86,8 @@
$token = $datasource->newInvalidToken($name);
}
- if ($token->getKey() == PhabricatorTypeaheadTokenView::KEY_INVALID) {
+ $type = $token->getTokenType();
+ if ($type == PhabricatorTypeaheadTokenView::TYPE_INVALID) {
$token->setKey($value);
}
}
@@ -117,12 +120,13 @@
if (!$this->disableBehavior) {
Javelin::initBehavior('aphront-basic-tokenizer', array(
- 'id' => $id,
- 'src' => $datasource_uri,
- 'value' => mpull($tokens, 'getValue', 'getKey'),
- 'icons' => mpull($tokens, 'getIcon', 'getKey'),
- 'limit' => $this->limit,
- 'username' => $username,
+ 'id' => $id,
+ 'src' => $datasource_uri,
+ 'value' => mpull($tokens, 'getValue', 'getKey'),
+ 'icons' => mpull($tokens, 'getIcon', 'getKey'),
+ 'types' => mpull($tokens, 'getTokenType', 'getKey'),
+ 'limit' => $this->limit,
+ 'username' => $username,
'placeholder' => $placeholder,
'browseURI' => $browse_uri,
));
diff --git a/webroot/rsrc/css/aphront/tokenizer.css b/webroot/rsrc/css/aphront/tokenizer.css
--- a/webroot/rsrc/css/aphront/tokenizer.css
+++ b/webroot/rsrc/css/aphront/tokenizer.css
@@ -83,6 +83,51 @@
color: {$bluetext};
}
+a.jx-tokenizer-token-function {
+ border-color: {$sh-lightyellowborder};
+ background: {$sh-yellowbackground};
+ color: {$sh-yellowtext};
+}
+
+a.jx-tokenizer-token-function:hover {
+ border-color: {$sh-yellowborder};
+ background: {$lightyellow};
+}
+
+.jx-tokenizer-token-function .phui-icon-view {
+ color: {$sh-yellowicon};
+}
+
+a.jx-tokenizer-token-disabled {
+ border-color: {$sh-lightgreyborder};
+ background: {$sh-greybackground};
+ color: {$sh-greytext};
+}
+
+a.jx-tokenizer-token-disabled:hover {
+ border-color: {$sh-greyborder};
+ background: {$greybackground};
+}
+
+.jx-tokenizer-token-disabled .phui-icon-view {
+ color: {$sh-greyicon};
+}
+
+a.jx-tokenizer-token-invalid {
+ border-color: {$sh-lightredborder};
+ background: {$sh-redbackground};
+ color: {$sh-redtext};
+}
+
+a.jx-tokenizer-token-invalid:hover {
+ border-color: {$sh-redborder};
+ background: {$lightred};
+}
+
+.jx-tokenizer-token-invalid .phui-icon-view {
+ color: {$sh-redicon};
+}
+
.tokenizer-result {
position: relative;
padding: 5px 8px 5px 28px;
diff --git a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
--- a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
+++ b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
@@ -348,16 +348,22 @@
}, '\u00d7'); // U+00D7 multiplication sign
var display_token = value;
- var render_callback = this.getRenderTokenCallback();
- if (render_callback) {
- display_token = render_callback(value, key);
- }
- return JX.$N('a', {
+ var attrs = {
className: 'jx-tokenizer-token',
sigil: 'token',
meta: {key: key}
- }, [display_token, input, remove]);
+ };
+ var container = JX.$N('a', attrs);
+
+ var render_callback = this.getRenderTokenCallback();
+ if (render_callback) {
+ display_token = render_callback(value, key, container);
+ }
+
+ JX.DOM.setContent(container, [display_token, input, remove]);
+
+ return container;
},
getTokens : function() {
diff --git a/webroot/rsrc/js/core/Prefab.js b/webroot/rsrc/js/core/Prefab.js
--- a/webroot/rsrc/js/core/Prefab.js
+++ b/webroot/rsrc/js/core/Prefab.js
@@ -172,23 +172,27 @@
var tokenizer = new JX.Tokenizer(root);
tokenizer.setTypeahead(typeahead);
- tokenizer.setRenderTokenCallback(function(value, key) {
+ tokenizer.setRenderTokenCallback(function(value, key, container) {
var result = datasource.getResult(key);
var icon;
+ var type;
if (result) {
icon = result.icon;
value = result.displayName;
+ type = result.tokenType;
} else {
icon = config.icons[key];
+ type = config.types[key];
}
if (icon) {
icon = JX.Prefab._renderIcon(icon);
}
- // TODO: Maybe we should render these closed tags in grey? Figure out
- // how we're going to use color.
+ if (type) {
+ JX.DOM.alterClass(container, 'jx-tokenizer-token-' + type, true);
+ }
return [icon, value];
});
@@ -288,7 +292,8 @@
closed: closed,
type: fields[5],
sprite: fields[10],
- unique: fields[11] || false
+ tokenType: fields[11],
+ unique: fields[12] || false
};
},
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 24, 5:00 AM (2 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7230626
Default Alt Text
D12446.id29868.diff (19 KB)
Attached To
Mode
D12446: Make token UI stronger and more consistent
Attached
Detach File
Event Timeline
Log In to Comment