Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15415257
D19191.id45962.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
26 KB
Referenced Files
None
Subscribers
None
D19191.id45962.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
@@ -10,7 +10,7 @@
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
'core.pkg.css' => '2fa91e14',
- 'core.pkg.js' => 'e4d73c62',
+ 'core.pkg.js' => '32bb68e9',
'darkconsole.pkg.js' => '1f9a31bc',
'differential.pkg.css' => '113e692c',
'differential.pkg.js' => 'f6d809c0',
@@ -85,7 +85,7 @@
'rsrc/css/application/maniphest/task-edit.css' => 'fda62a9b',
'rsrc/css/application/maniphest/task-summary.css' => '11cc5344',
'rsrc/css/application/objectselector/object-selector.css' => '85ee8ce6',
- 'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b',
+ 'rsrc/css/application/owners/owners-path-editor.css' => '9c136c29',
'rsrc/css/application/paste/paste.css' => '9fcc9773',
'rsrc/css/application/people/people-picture-menu-item.css' => 'a06f7f34',
'rsrc/css/application/people/people-profile.css' => '4df76faf',
@@ -268,7 +268,7 @@
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '013ffff9',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '54f314a0',
- 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '0fcf201c',
+ 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => 'ab9e0a82',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '6c0e62fa',
'rsrc/favicons/apple-touch-icon-114x114.png' => '12a24178',
'rsrc/favicons/apple-touch-icon-120x120.png' => '0d1543c7',
@@ -418,13 +418,13 @@
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909',
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'dca75c0e',
- 'rsrc/js/application/herald/PathTypeahead.js' => '78039abe',
+ 'rsrc/js/application/herald/PathTypeahead.js' => '662e9cea',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ad54037e',
'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876',
'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2',
'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '71237763',
- 'rsrc/js/application/owners/OwnersPathEditor.js' => '52b9cbc4',
+ 'rsrc/js/application/owners/OwnersPathEditor.js' => 'c96502cf',
'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3',
'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => 'bee502c8',
@@ -534,7 +534,7 @@
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
- 'rsrc/js/phuix/PHUIXFormControl.js' => '16ad6224',
+ 'rsrc/js/phuix/PHUIXFormControl.js' => '210a16c1',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
),
'symbols' => array(
@@ -744,7 +744,7 @@
'javelin-typeahead-normalizer' => '185bbd53',
'javelin-typeahead-ondemand-source' => '013ffff9',
'javelin-typeahead-preloaded-source' => '54f314a0',
- 'javelin-typeahead-source' => '0fcf201c',
+ 'javelin-typeahead-source' => 'ab9e0a82',
'javelin-typeahead-static-source' => '6c0e62fa',
'javelin-uri' => 'c989ade3',
'javelin-util' => '93cc50d6',
@@ -764,10 +764,10 @@
'maniphest-task-edit-css' => 'fda62a9b',
'maniphest-task-summary-css' => '11cc5344',
'multirow-row-manager' => 'b5d57730',
- 'owners-path-editor' => '52b9cbc4',
- 'owners-path-editor-css' => '2f00933b',
+ 'owners-path-editor' => 'c96502cf',
+ 'owners-path-editor-css' => '9c136c29',
'paste-css' => '9fcc9773',
- 'path-typeahead' => '78039abe',
+ 'path-typeahead' => '662e9cea',
'people-picture-menu-item-css' => 'a06f7f34',
'people-profile-css' => '4df76faf',
'phabricator-action-list-view-css' => '0bcd9a45',
@@ -888,7 +888,7 @@
'phuix-autocomplete' => '7fa5c915',
'phuix-button-view' => '8a91e1ac',
'phuix-dropdown-menu' => '04b2ae03',
- 'phuix-form-control-view' => '16ad6224',
+ 'phuix-form-control-view' => '210a16c1',
'phuix-icon-view' => 'bff6884b',
'policy-css' => '957ea14c',
'policy-edit-css' => '815c66f7',
@@ -998,20 +998,10 @@
'javelin-install',
'javelin-util',
),
- '0fcf201c' => array(
- 'javelin-install',
- 'javelin-util',
- 'javelin-dom',
- 'javelin-typeahead-normalizer',
- ),
'15d5ff71' => array(
'aphront-typeahead-control-css',
'phui-tag-view-css',
),
- '16ad6224' => array(
- 'javelin-install',
- 'javelin-dom',
- ),
'17bb8539' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1061,6 +1051,10 @@
'javelin-install',
'javelin-dom',
),
+ '210a16c1' => array(
+ 'javelin-install',
+ 'javelin-dom',
+ ),
'2290aeef' => array(
'javelin-install',
'javelin-dom',
@@ -1337,14 +1331,6 @@
'javelin-vector',
'javelin-typeahead-static-source',
),
- '52b9cbc4' => array(
- 'multirow-row-manager',
- 'javelin-install',
- 'path-typeahead',
- 'javelin-dom',
- 'javelin-util',
- 'phabricator-prefab',
- ),
'54b612ba' => array(
'javelin-color',
'javelin-install',
@@ -1439,6 +1425,14 @@
'javelin-workflow',
'javelin-dom',
),
+ '662e9cea' => array(
+ 'javelin-install',
+ 'javelin-typeahead',
+ 'javelin-dom',
+ 'javelin-request',
+ 'javelin-typeahead-ondemand-source',
+ 'javelin-util',
+ ),
'66a6def1' => array(
'javelin-behavior',
'javelin-dom',
@@ -1542,14 +1536,6 @@
'javelin-request',
'javelin-util',
),
- '78039abe' => array(
- 'javelin-install',
- 'javelin-typeahead',
- 'javelin-dom',
- 'javelin-request',
- 'javelin-typeahead-ondemand-source',
- 'javelin-util',
- ),
'7927a7d3' => array(
'javelin-behavior',
'javelin-quicksand',
@@ -1799,6 +1785,12 @@
'javelin-util',
'phabricator-busy',
),
+ 'ab9e0a82' => array(
+ 'javelin-install',
+ 'javelin-util',
+ 'javelin-dom',
+ 'javelin-typeahead-normalizer',
+ ),
'acd29eee' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1974,6 +1966,15 @@
'javelin-install',
'javelin-util',
),
+ 'c96502cf' => array(
+ 'multirow-row-manager',
+ 'javelin-install',
+ 'path-typeahead',
+ 'javelin-dom',
+ 'javelin-util',
+ 'phabricator-prefab',
+ 'phuix-form-control-view',
+ ),
'c989ade3' => array(
'javelin-install',
'javelin-util',
diff --git a/src/applications/diffusion/controller/DiffusionPathValidateController.php b/src/applications/diffusion/controller/DiffusionPathValidateController.php
--- a/src/applications/diffusion/controller/DiffusionPathValidateController.php
+++ b/src/applications/diffusion/controller/DiffusionPathValidateController.php
@@ -45,19 +45,6 @@
'valid' => (bool)$valid,
);
- if (!$valid) {
- $branch = $drequest->getBranch();
- if ($branch) {
- $message = pht('Not found in %s', $branch);
- } else {
- $message = pht('Not found at %s', 'HEAD');
- }
- } else {
- $message = pht('OK');
- }
-
- $output['message'] = $message;
-
return id(new AphrontAjaxResponse())->setContent($output);
}
}
diff --git a/src/applications/owners/controller/PhabricatorOwnersPathsController.php b/src/applications/owners/controller/PhabricatorOwnersPathsController.php
--- a/src/applications/owners/controller/PhabricatorOwnersPathsController.php
+++ b/src/applications/owners/controller/PhabricatorOwnersPathsController.php
@@ -27,7 +27,7 @@
$path_refs = array();
foreach ($paths as $key => $path) {
- if (!isset($repos[$key])) {
+ if (!isset($repos[$key]) || !strlen($repos[$key])) {
throw new Exception(
pht(
'No repository PHID for path "%s"!',
@@ -70,17 +70,39 @@
$path_refs = mpull($paths, 'getRef');
}
- $repos = id(new PhabricatorRepositoryQuery())
- ->setViewer($viewer)
- ->execute();
+ $template = new AphrontTokenizerTemplateView();
+
+ $datasource = id(new DiffusionRepositoryDatasource())
+ ->setViewer($viewer);
- $repo_map = array();
- foreach ($repos as $key => $repo) {
- $monogram = $repo->getMonogram();
- $name = $repo->getName();
- $repo_map[$repo->getPHID()] = "{$monogram} {$name}";
+ $tokenizer_spec = array(
+ 'markup' => $template->render(),
+ 'config' => array(
+ 'src' => $datasource->getDatasourceURI(),
+ 'browseURI' => $datasource->getBrowseURI(),
+ 'placeholder' => $datasource->getPlaceholderText(),
+ 'limit' => 1,
+ ),
+ );
+
+ foreach ($path_refs as $key => $path_ref) {
+ $path_refs[$key]['repositoryValue'] = $datasource->getWireTokens(
+ array(
+ $path_ref['repositoryPHID'],
+ ));
}
- asort($repos);
+
+ $icon_test = id(new PHUIIconView())
+ ->setIcon('fa-spinner grey')
+ ->setTooltip(pht('Validating...'));
+
+ $icon_okay = id(new PHUIIconView())
+ ->setIcon('fa-check-circle green')
+ ->setTooltip(pht('Path Exists in Repository'));
+
+ $icon_fail = id(new PHUIIconView())
+ ->setIcon('fa-question-circle-o red')
+ ->setTooltip(pht('Path Not Found On Default Branch'));
$template = new AphrontTypeaheadTemplateView();
$template = $template->render();
@@ -88,15 +110,23 @@
Javelin::initBehavior(
'owners-path-editor',
array(
- 'root' => 'path-editor',
- 'table' => 'paths',
- 'add_button' => 'addpath',
- 'repositories' => $repo_map,
- 'input_template' => $template,
- 'pathRefs' => $path_refs,
-
- 'completeURI' => '/diffusion/services/path/complete/',
- 'validateURI' => '/diffusion/services/path/validate/',
+ 'root' => 'path-editor',
+ 'table' => 'paths',
+ 'add_button' => 'addpath',
+ 'input_template' => $template,
+ 'pathRefs' => $path_refs,
+ 'completeURI' => '/diffusion/services/path/complete/',
+ 'validateURI' => '/diffusion/services/path/validate/',
+ 'repositoryTokenizerSpec' => $tokenizer_spec,
+ 'icons' => array(
+ 'test' => hsprintf('%s', $icon_test),
+ 'okay' => hsprintf('%s', $icon_okay),
+ 'fail' => hsprintf('%s', $icon_fail),
+ ),
+ 'modeOptions' => array(
+ 0 => pht('Include'),
+ 1 => pht('Exclude'),
+ ),
));
require_celerity_resource('owners-path-editor-css');
diff --git a/webroot/rsrc/css/application/owners/owners-path-editor.css b/webroot/rsrc/css/application/owners/owners-path-editor.css
--- a/webroot/rsrc/css/application/owners/owners-path-editor.css
+++ b/webroot/rsrc/css/application/owners/owners-path-editor.css
@@ -3,7 +3,8 @@
*/
.owners-path-editor-table {
- margin: 10px;
+ margin: 10px 0;
+ width: 100%;
}
.owners-path-editor-table td {
@@ -11,27 +12,38 @@
vertical-align: middle;
}
-.owners-path-editor-table select.owners-repo {
- width: 150px;
+.owners-path-editor-table td.owners-path-mode-control {
+ width: 180px;
}
-.owners-path-editor-table input {
- width: 400px;
+.owners-path-editor-table td.owners-path-mode-control select {
+ width: 100%;
}
-.owners-path-editor-table div.error-display {
- padding: 4px 12px 0;
+.owners-path-editor-table td.owners-path-repo-control {
+ width: 280px;
}
-.owners-path-editor-table div.validating {
- color: {$greytext};
+.owners-path-editor-table td.owners-path-path-control {
+ width: auto;
}
-.owners-path-editor-table div.invalid {
- color: #aa0000;
+.owners-path-editor-table td.owners-path-path-control input {
+ width: 100%;
}
-.owners-path-editor-table div.valid {
- color: #00aa00;
- font-weight: bold;
+.owners-path-editor-table td.owners-path-path-control .jx-typeahead-results a {
+ padding: 4px;
+}
+
+.owners-path-editor-table td.owners-path-icon-control {
+ width: 18px;
+}
+
+.owners-path-editor-table td.remove-column {
+ width: 100px;
+}
+
+.owners-path-editor-table td.remove-column a {
+ display: block;
}
diff --git a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
--- a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
+++ b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
@@ -9,8 +9,7 @@
JX.install('TypeaheadSource', {
construct : function() {
- this._raw = {};
- this._lookup = {};
+ this.resetResults();
this.setNormalizer(JX.TypeaheadNormalizer.normalize);
this._excludeIDs = {};
},
@@ -359,6 +358,12 @@
}
return str.split(/\s+/g);
},
+
+ resetResults: function() {
+ this._raw = {};
+ this._lookup = {};
+ },
+
_defaultTransformer : function(object) {
return {
name : object[0],
diff --git a/webroot/rsrc/js/application/herald/PathTypeahead.js b/webroot/rsrc/js/application/herald/PathTypeahead.js
--- a/webroot/rsrc/js/application/herald/PathTypeahead.js
+++ b/webroot/rsrc/js/application/herald/PathTypeahead.js
@@ -11,7 +11,7 @@
JX.install('PathTypeahead', {
construct : function(config) {
- this._repositorySelect = config.repo_select;
+ this._repositoryTokenizer = config.repositoryTokenizer;
this._hardpoint = config.hardpoint;
this._input = config.path_input;
this._completeURI = config.completeURI;
@@ -19,14 +19,14 @@
this._errorDisplay = config.error_display;
this._textInputValues = {};
+ this._icons = config.icons;
+
this._initializeDatasource();
this._initializeTypeahead(this._input);
},
members : {
- /*
- * DOM <select> elem for choosing the repository of a path.
- */
- _repositorySelect : null,
+ _repositoryTokenizer : null,
+
/*
* DOM parent div "hardpoint" to be passed to the JX.Typeahead.
*/
@@ -79,31 +79,28 @@
*/
start : function() {
if (this._typeahead.getValue()) {
- this._textInputValues[this._repositorySelect.value] =
- this._typeahead.getValue();
+ var phid = this._getRepositoryPHID();
+ if (phid) {
+ this._textInputValues[phid] = this._typeahead.getValue();
+ }
}
this._typeahead.listen(
'change',
JX.bind(this, function(value) {
- this._textInputValues[this._repositorySelect.value] = value;
- this._validate();
- }));
+ var phid = this._getRepositoryPHID();
+ if (phid) {
+ this._textInputValues[phid] = value;
+ }
- this._typeahead.listen(
- 'choose',
- JX.bind(this, function() {
- setTimeout(JX.bind(this._typeahead, this._typeahead.refresh), 0);
+ this._validate();
}));
var repo_set_input = JX.bind(this, this._onrepochange);
this._typeahead.listen('start', repo_set_input);
- JX.DOM.listen(
- this._repositorySelect,
- 'change',
- null,
- repo_set_input);
+
+ this._repositoryTokenizer.listen('change', repo_set_input);
this._typeahead.start();
this._validate();
@@ -115,13 +112,18 @@
this._textInputValues);
this._datasource.setAuxiliaryData(
- {repositoryPHID : this._repositorySelect.value}
- );
+ {
+ repositoryPHID: this._getRepositoryPHID()
+ });
+
+ // Since we've changed the repository, reset the results.
+ this._datasource.resetResults();
},
_setPathInputBasedOnRepository : function(typeahead, lookup) {
- if (lookup[this._repositorySelect.value]) {
- typeahead.setValue(lookup[this._repositorySelect.value]);
+ var phid = this._getRepositoryPHID();
+ if (phid && lookup[phid]) {
+ typeahead.setValue(lookup[phid]);
} else {
typeahead.setValue('/');
}
@@ -147,9 +149,24 @@
return ('' + str).replace(/[\/]+/g, '\/');
},
+ _getRepositoryPHID: function() {
+ var tokens = this._repositoryTokenizer.getTokens();
+ var keys = JX.keys(tokens);
+
+ if (keys.length) {
+ return keys[0];
+ }
+
+ return null;
+ },
+
_validate : function() {
+ var repo_phid = this._getRepositoryPHID();
+ if (!repo_phid) {
+ return;
+ }
+
var input = this._input;
- var repo_id = this._repositorySelect.value;
var input_value = input.value;
var error_display = this._errorDisplay;
@@ -165,33 +182,32 @@
var validation_request = new JX.Request(
this._validateURI,
- function(payload) {
+ JX.bind(this, function(payload) {
// Don't change validation display state if the input has been
// changed since we started validation
- if (input.value === input_value) {
- if (payload.valid) {
- JX.DOM.alterClass(error_display, 'invalid', false);
- JX.DOM.alterClass(error_display, 'valid', true);
- } else {
- JX.DOM.alterClass(error_display, 'invalid', true);
- JX.DOM.alterClass(error_display, 'valid', false);
- }
- JX.DOM.setContent(error_display, payload.message);
+ if (input.value !== input_value) {
+ return;
}
- });
+
+ if (payload.valid) {
+ JX.DOM.setContent(error_display, JX.$H(this._icons.okay));
+ } else {
+ JX.DOM.setContent(error_display, JX.$H(this._icons.fail));
+ }
+ }));
validation_request.listen('finally', function() {
- JX.DOM.alterClass(error_display, 'validating', false);
this._validationInflight = null;
});
validation_request.setData(
{
- repositoryPHID : repo_id,
+ repositoryPHID : repo_phid,
path : input_value
});
this._validationInflight = validation_request;
+ JX.DOM.setContent(error_display, JX.$H(this._icons.test));
validation_request.setTimeout(750);
validation_request.send();
diff --git a/webroot/rsrc/js/application/owners/OwnersPathEditor.js b/webroot/rsrc/js/application/owners/OwnersPathEditor.js
--- a/webroot/rsrc/js/application/owners/OwnersPathEditor.js
+++ b/webroot/rsrc/js/application/owners/OwnersPathEditor.js
@@ -5,6 +5,7 @@
* javelin-dom
* javelin-util
* phabricator-prefab
+ * phuix-form-control-view
* @provides owners-path-editor
* @javelin
*/
@@ -23,11 +24,13 @@
JX.bind(this, this._onaddpath));
this._count = 0;
- this._repositories = config.repositories;
this._inputTemplate = config.input_template;
+ this._repositoryTokenizerSpec = config.repositoryTokenizerSpec;
this._completeURI = config.completeURI;
this._validateURI = config.validateURI;
+ this._icons = config.icons;
+ this._modeOptions = config.modeOptions;
this._initializePaths(config.pathRefs);
},
@@ -38,12 +41,6 @@
_rowManager : null,
/*
- * Array of objects with 'name' and 'repo_id' keys for
- * selecting the repository of a path.
- */
- _repositories : null,
-
- /*
* How many rows have been created, for form name generation.
*/
_count : 0,
@@ -65,6 +62,8 @@
* default for future rows.
*/
_lastRepositoryChoice : null,
+ _icons: null,
+ _modeOptions: null,
/*
* Initialize with 0 or more rows.
@@ -85,68 +84,34 @@
addPath : function(path_ref) {
// Smart default repository. See _lastRepositoryChoice.
if (path_ref) {
- this._lastRepositoryChoice = path_ref.repositoryPHID;
+ this._lastRepositoryChoice = path_ref.repositoryValue;
+ } else {
+ path_ref = {
+ repositoryValue: this._lastRepositoryChoice || {}
+ };
}
- path_ref = path_ref || {};
-
- var selected_repository = path_ref.repositoryPHID ||
- this._lastRepositoryChoice;
- var options = this._buildRepositoryOptions(selected_repository);
- var attrs = {
- name : 'repo[' + this._count + ']',
- className : 'owners-repo'
- };
- var repo_select = JX.$N('select', attrs, options);
-
- JX.DOM.listen(repo_select, 'change', null, JX.bind(this, function() {
- this._lastRepositoryChoice = repo_select.value;
- }));
-
- var repo_cell = JX.$N('td', {}, repo_select);
- var typeahead_cell = JX.$N(
- 'td',
- JX.$H(this._inputTemplate));
-
- // Text input for path.
- var path_input = JX.DOM.find(typeahead_cell, 'input');
- JX.copy(
- path_input,
- {
- value : path_ref.display || '',
- name : 'path[' + this._count + ']'
- });
-
- // The Typeahead requires a display div called hardpoint.
- var hardpoint = JX.DOM.find(
- typeahead_cell,
- 'div',
- 'typeahead-hardpoint');
- var error_display = JX.$N(
- 'div',
- {
- className : 'error-display validating'
- },
- 'Validating...');
-
- var error_display_cell = JX.$N('td', {}, error_display);
-
- var exclude = JX.Prefab.renderSelect(
- {'0' : 'Include', '1' : 'Exclude'},
- path_ref.excluded,
- {name : 'exclude[' + this._count + ']'});
- var exclude_cell = JX.$N('td', {}, exclude);
+ var repo = this._newRepoCell(path_ref.repositoryValue);
+ var path = this._newPathCell(path_ref.display);
+ var icon = this._newIconCell();
+ var mode_cell = this._newModeCell(path_ref.excluded);
var row = this._rowManager.addRow(
- [exclude_cell, repo_cell, typeahead_cell, error_display_cell]);
+ [
+ mode_cell,
+ repo.cell,
+ path.cell,
+ icon.cell
+ ]);
new JX.PathTypeahead({
- repo_select : repo_select,
- path_input : path_input,
- hardpoint : hardpoint,
- error_display : error_display,
+ repositoryTokenizer: repo.tokenizer,
+ path_input : path.input,
+ hardpoint : path.hardpoint,
+ error_display : icon.cell,
completeURI : this._completeURI,
- validateURI : this._validateURI
+ validateURI : this._validateURI,
+ icons: this._icons
}).start();
this._count++;
@@ -158,20 +123,109 @@
this.addPath();
},
- /**
- * Helper to build the options for the repository choice dropdown.
- */
- _buildRepositoryOptions : function(selected) {
- var repos = this._repositories;
- var result = [];
- for (var k in repos) {
- var attr = {
- value : k,
- selected : (selected == k)
- };
- result.push(JX.$N('option', attr, repos[k]));
+ _newModeCell: function(value) {
+ var options = this._modeOptions;
+
+ var name = 'exclude[' + this._count + ']';
+
+ var control = JX.Prefab.renderSelect(options, value, {name: name});
+
+ return JX.$N(
+ 'td',
+ {
+ className: 'owners-path-mode-control'
+ },
+ control);
+ },
+
+ _newRepoCell: function(value) {
+ var repo_control = new JX.PHUIXFormControl()
+ .setControl('tokenizer', this._repositoryTokenizerSpec)
+ .setValue(value);
+
+ var repo_tokenizer = repo_control.getTokenizer();
+ var name = 'repo[' + this._count + ']';
+
+ function get_phid() {
+ var phids = repo_control.getValue();
+ if (!phids.length) {
+ return null;
+ }
+
+ return phids[0];
}
- return result;
+
+ var input = JX.$N(
+ 'input',
+ {
+ type: 'hidden',
+ name: name,
+ value: get_phid()
+ });
+
+ repo_tokenizer.listen('change', JX.bind(this, function() {
+ this._lastRepositoryChoice = repo_tokenizer.getTokens();
+
+ input.value = get_phid();
+ }));
+
+ var cell = JX.$N(
+ 'td',
+ {
+ className: 'owners-path-repo-control'
+ },
+ [
+ repo_control.getRawInputNode(),
+ input
+ ]);
+
+ return {
+ cell: cell,
+ tokenizer: repo_tokenizer
+ };
+ },
+
+ _newPathCell: function(value) {
+ var path_cell = JX.$N(
+ 'td',
+ {
+ className: 'owners-path-path-control'
+ },
+ JX.$H(this._inputTemplate));
+
+ var path_input = JX.DOM.find(path_cell, 'input');
+
+ JX.copy(
+ path_input,
+ {
+ value: value || '',
+ name: 'path[' + this._count + ']'
+ });
+
+ var hardpoint = JX.DOM.find(
+ path_cell,
+ 'div',
+ 'typeahead-hardpoint');
+
+ return {
+ cell: path_cell,
+ input: path_input,
+ hardpoint: hardpoint
+ };
+ },
+
+ _newIconCell: function() {
+ var cell = JX.$N(
+ 'td',
+ {
+ className: 'owners-path-icon-control'
+ });
+
+ return {
+ cell: cell
+ };
}
+
}
+
});
diff --git a/webroot/rsrc/js/phuix/PHUIXFormControl.js b/webroot/rsrc/js/phuix/PHUIXFormControl.js
--- a/webroot/rsrc/js/phuix/PHUIXFormControl.js
+++ b/webroot/rsrc/js/phuix/PHUIXFormControl.js
@@ -15,6 +15,7 @@
_valueSetCallback: null,
_valueGetCallback: null,
_rawInputNode: null,
+ _tokenizer: null,
setLabel: function(label) {
JX.DOM.setContent(this._getLabelNode(), label);
@@ -70,6 +71,7 @@
this._valueGetCallback = input.get;
this._valueSetCallback = input.set;
this._rawInputNode = input.node;
+ this._tokenizer = input.tokenizer || null;
return this;
},
@@ -87,6 +89,10 @@
return this._rawInputNode;
},
+ getTokenizer: function() {
+ return this._tokenizer;
+ },
+
getNode: function() {
if (!this._node) {
@@ -168,7 +174,8 @@
return {
node: build.node,
get: get_value,
- set: set_value
+ set: set_value,
+ tokenizer: build.tokenizer
};
},
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 21, 5:05 AM (1 d, 12 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7715012
Default Alt Text
D19191.id45962.diff (26 KB)
Attached To
Mode
D19191: Use a tokenizer, not a gigantic poorly-ordered "<select />", to choose repositories in Owners
Attached
Detach File
Event Timeline
Log In to Comment