Page MenuHomePhabricator

D12446.id29868.diff
No OneTemporary

D12446.id29868.diff

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

Mime Type
text/plain
Expires
Mon, May 13, 3:50 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6274911
Default Alt Text
D12446.id29868.diff (19 KB)

Event Timeline