mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-10 23:01:04 +01:00
(stable) Promote 2018 Week 19
This commit is contained in:
commit
121a18de8c
22 changed files with 451 additions and 46 deletions
|
@ -9,8 +9,8 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => 'e68cf1fa',
|
'conpherence.pkg.css' => 'e68cf1fa',
|
||||||
'conpherence.pkg.js' => '15191c65',
|
'conpherence.pkg.js' => '15191c65',
|
||||||
'core.pkg.css' => 'cb8ae4dc',
|
'core.pkg.css' => '8be474cc',
|
||||||
'core.pkg.js' => 'e1f0f7bd',
|
'core.pkg.js' => 'e452721e',
|
||||||
'differential.pkg.css' => '06dc617c',
|
'differential.pkg.css' => '06dc617c',
|
||||||
'differential.pkg.js' => 'c2ca903a',
|
'differential.pkg.js' => 'c2ca903a',
|
||||||
'diffusion.pkg.css' => 'a2d17c7d',
|
'diffusion.pkg.css' => 'a2d17c7d',
|
||||||
|
@ -144,7 +144,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-cms.css' => '504b4b23',
|
'rsrc/css/phui/phui-cms.css' => '504b4b23',
|
||||||
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
||||||
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
|
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
|
||||||
'rsrc/css/phui/phui-crumbs-view.css' => '6ece3bbb',
|
'rsrc/css/phui/phui-crumbs-view.css' => '10728aaa',
|
||||||
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
|
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
|
||||||
'rsrc/css/phui/phui-document-pro.css' => '8af7ea27',
|
'rsrc/css/phui/phui-document-pro.css' => '8af7ea27',
|
||||||
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
|
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
|
||||||
|
@ -259,7 +259,7 @@ return array(
|
||||||
'rsrc/externals/javelin/lib/__tests__/URI.js' => '1e45fda9',
|
'rsrc/externals/javelin/lib/__tests__/URI.js' => '1e45fda9',
|
||||||
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
|
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
|
||||||
'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
|
'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
|
||||||
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '8d3bc1b2',
|
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'dfaf006b',
|
||||||
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '70baed2f',
|
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '70baed2f',
|
||||||
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '185bbd53',
|
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '185bbd53',
|
||||||
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
|
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
|
||||||
|
@ -710,7 +710,7 @@ return array(
|
||||||
'javelin-scrollbar' => '9065f639',
|
'javelin-scrollbar' => '9065f639',
|
||||||
'javelin-sound' => '949c0fe5',
|
'javelin-sound' => '949c0fe5',
|
||||||
'javelin-stratcom' => '327f418a',
|
'javelin-stratcom' => '327f418a',
|
||||||
'javelin-tokenizer' => '8d3bc1b2',
|
'javelin-tokenizer' => 'dfaf006b',
|
||||||
'javelin-typeahead' => '70baed2f',
|
'javelin-typeahead' => '70baed2f',
|
||||||
'javelin-typeahead-composite-source' => '503e17fd',
|
'javelin-typeahead-composite-source' => '503e17fd',
|
||||||
'javelin-typeahead-normalizer' => '185bbd53',
|
'javelin-typeahead-normalizer' => '185bbd53',
|
||||||
|
@ -810,7 +810,7 @@ return array(
|
||||||
'phui-cms-css' => '504b4b23',
|
'phui-cms-css' => '504b4b23',
|
||||||
'phui-comment-form-css' => 'ac68149f',
|
'phui-comment-form-css' => 'ac68149f',
|
||||||
'phui-comment-panel-css' => 'f50152ad',
|
'phui-comment-panel-css' => 'f50152ad',
|
||||||
'phui-crumbs-view-css' => '6ece3bbb',
|
'phui-crumbs-view-css' => '10728aaa',
|
||||||
'phui-curtain-view-css' => '2bdaf026',
|
'phui-curtain-view-css' => '2bdaf026',
|
||||||
'phui-document-summary-view-css' => '9ca48bdf',
|
'phui-document-summary-view-css' => '9ca48bdf',
|
||||||
'phui-document-view-css' => '878c2f52',
|
'phui-document-view-css' => '878c2f52',
|
||||||
|
@ -1573,12 +1573,6 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
),
|
),
|
||||||
'8d3bc1b2' => array(
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-install',
|
|
||||||
),
|
|
||||||
'8d4a8c72' => array(
|
'8d4a8c72' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -2025,6 +2019,12 @@ return array(
|
||||||
'phuix-icon-view',
|
'phuix-icon-view',
|
||||||
'phabricator-prefab',
|
'phabricator-prefab',
|
||||||
),
|
),
|
||||||
|
'dfaf006b' => array(
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-install',
|
||||||
|
),
|
||||||
'e1d25dfb' => array(
|
'e1d25dfb' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
|
|
|
@ -816,6 +816,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionHovercardEngineExtension' => 'applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php',
|
'DiffusionHovercardEngineExtension' => 'applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php',
|
||||||
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
|
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
|
||||||
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
|
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
|
||||||
|
'DiffusionInternalAncestorsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalAncestorsConduitAPIMethod.php',
|
||||||
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalGitRawDiffQueryConduitAPIMethod.php',
|
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalGitRawDiffQueryConduitAPIMethod.php',
|
||||||
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
|
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
|
||||||
'DiffusionLastModifiedQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php',
|
'DiffusionLastModifiedQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php',
|
||||||
|
@ -2525,6 +2526,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php',
|
'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php',
|
||||||
'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php',
|
'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php',
|
||||||
'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php',
|
'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php',
|
||||||
|
'PhabricatorCheckboxesEditField' => 'applications/transactions/editfield/PhabricatorCheckboxesEditField.php',
|
||||||
'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php',
|
'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php',
|
||||||
'PhabricatorClassConfigType' => 'applications/config/type/PhabricatorClassConfigType.php',
|
'PhabricatorClassConfigType' => 'applications/config/type/PhabricatorClassConfigType.php',
|
||||||
'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php',
|
'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php',
|
||||||
|
@ -2881,6 +2883,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDocumentRef' => 'applications/files/document/PhabricatorDocumentRef.php',
|
'PhabricatorDocumentRef' => 'applications/files/document/PhabricatorDocumentRef.php',
|
||||||
'PhabricatorDocumentRenderingEngine' => 'applications/files/document/render/PhabricatorDocumentRenderingEngine.php',
|
'PhabricatorDocumentRenderingEngine' => 'applications/files/document/render/PhabricatorDocumentRenderingEngine.php',
|
||||||
'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php',
|
'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php',
|
||||||
|
'PhabricatorDoubleExportField' => 'infrastructure/export/field/PhabricatorDoubleExportField.php',
|
||||||
'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
|
'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
|
||||||
'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
|
'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
|
||||||
'PhabricatorDraftEngine' => 'applications/transactions/draft/PhabricatorDraftEngine.php',
|
'PhabricatorDraftEngine' => 'applications/transactions/draft/PhabricatorDraftEngine.php',
|
||||||
|
@ -6147,6 +6150,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
'DiffusionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||||
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
|
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
|
||||||
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
||||||
|
'DiffusionInternalAncestorsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||||
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||||
'DiffusionLastModifiedController' => 'DiffusionController',
|
'DiffusionLastModifiedController' => 'DiffusionController',
|
||||||
'DiffusionLastModifiedQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
'DiffusionLastModifiedQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||||
|
@ -8140,6 +8144,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorCheckboxesEditField' => 'PhabricatorEditField',
|
||||||
'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine',
|
'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine',
|
||||||
'PhabricatorClassConfigType' => 'PhabricatorTextConfigType',
|
'PhabricatorClassConfigType' => 'PhabricatorTextConfigType',
|
||||||
'PhabricatorClusterConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorClusterConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
@ -8538,6 +8543,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDocumentRef' => 'Phobject',
|
'PhabricatorDocumentRef' => 'Phobject',
|
||||||
'PhabricatorDocumentRenderingEngine' => 'Phobject',
|
'PhabricatorDocumentRenderingEngine' => 'Phobject',
|
||||||
'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication',
|
'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorDoubleExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
||||||
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorDraftEngine' => 'Phobject',
|
'PhabricatorDraftEngine' => 'Phobject',
|
||||||
|
|
|
@ -53,6 +53,10 @@ final class PhabricatorCommitSearchEngine
|
||||||
$query->withUnreachable($map['unreachable']);
|
$query->withUnreachable($map['unreachable']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($map['ancestorsOf']) {
|
||||||
|
$query->withAncestorsOf($map['ancestorsOf']);
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +107,13 @@ final class PhabricatorCommitSearchEngine
|
||||||
pht(
|
pht(
|
||||||
'Find or exclude unreachable commits which are not ancestors of '.
|
'Find or exclude unreachable commits which are not ancestors of '.
|
||||||
'any branch, tag, or ref.')),
|
'any branch, tag, or ref.')),
|
||||||
|
id(new PhabricatorSearchStringListField())
|
||||||
|
->setLabel(pht('Ancestors Of'))
|
||||||
|
->setKey('ancestorsOf')
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'Find commits which are ancestors of a particular ref, '.
|
||||||
|
'like "master".')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,25 +182,31 @@ final class DifferentialRevisionViewController
|
||||||
if ($large_warning) {
|
if ($large_warning) {
|
||||||
$count = $this->getChangesetCount();
|
$count = $this->getChangesetCount();
|
||||||
|
|
||||||
$warning = new PHUIInfoView();
|
$expand_uri = $request_uri
|
||||||
$warning->setTitle(pht('Large Diff'));
|
->alter('large', 'true')
|
||||||
$warning->setSeverity(PHUIInfoView::SEVERITY_WARNING);
|
->setFragment('toc');
|
||||||
$warning->appendChild(hsprintf(
|
|
||||||
'%s <strong>%s</strong>',
|
$message = array(
|
||||||
pht(
|
pht(
|
||||||
'This diff is large and affects %s files. '.
|
'This large diff affects %s files. Files without inline '.
|
||||||
'You may load each file individually or ',
|
'comments have been collapsed.',
|
||||||
new PhutilNumber($count)),
|
new PhutilNumber($count)),
|
||||||
|
' ',
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
'a',
|
'strong',
|
||||||
array(
|
array(),
|
||||||
'class' => 'button button-grey',
|
phutil_tag(
|
||||||
'href' => $request_uri
|
'a',
|
||||||
->alter('large', 'true')
|
array(
|
||||||
->setFragment('toc'),
|
'href' => $expand_uri,
|
||||||
),
|
),
|
||||||
pht('Show All Files Inline'))));
|
pht('Expand All Files'))),
|
||||||
$warning = $warning->render();
|
);
|
||||||
|
|
||||||
|
$warning = id(new PHUIInfoView())
|
||||||
|
->setTitle(pht('Large Diff'))
|
||||||
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||||
|
->appendChild($message);
|
||||||
|
|
||||||
$old = array_select_keys($changesets, $old_ids);
|
$old = array_select_keys($changesets, $old_ids);
|
||||||
$new = array_select_keys($changesets, $new_ids);
|
$new = array_select_keys($changesets, $new_ids);
|
||||||
|
|
|
@ -682,8 +682,13 @@ final class DifferentialTransactionEditor
|
||||||
if ($config_inline || $config_attach) {
|
if ($config_inline || $config_attach) {
|
||||||
$body_limit = PhabricatorEnv::getEnvConfig('metamta.email-body-limit');
|
$body_limit = PhabricatorEnv::getEnvConfig('metamta.email-body-limit');
|
||||||
|
|
||||||
$patch = $this->buildPatchForMail($diff);
|
try {
|
||||||
if ($config_inline) {
|
$patch = $this->buildPatchForMail($diff, $body_limit);
|
||||||
|
} catch (ArcanistDiffByteSizeException $ex) {
|
||||||
|
$patch = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($patch !== null) && $config_inline) {
|
||||||
$lines = substr_count($patch, "\n");
|
$lines = substr_count($patch, "\n");
|
||||||
$bytes = strlen($patch);
|
$bytes = strlen($patch);
|
||||||
|
|
||||||
|
@ -706,7 +711,7 @@ final class DifferentialTransactionEditor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($config_attach) {
|
if (($patch !== null) && $config_attach) {
|
||||||
// See T12033, T11767, and PHI55. This is a crude fix to stop the
|
// See T12033, T11767, and PHI55. This is a crude fix to stop the
|
||||||
// major concrete problems that lackluster email size limits cause.
|
// major concrete problems that lackluster email size limits cause.
|
||||||
if (strlen($patch) < $body_limit) {
|
if (strlen($patch) < $body_limit) {
|
||||||
|
@ -1411,13 +1416,14 @@ final class DifferentialTransactionEditor
|
||||||
array('style' => 'font-family: monospace;'), $patch);
|
array('style' => 'font-family: monospace;'), $patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPatchForMail(DifferentialDiff $diff) {
|
private function buildPatchForMail(DifferentialDiff $diff, $byte_limit) {
|
||||||
$format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format');
|
$format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format');
|
||||||
|
|
||||||
return id(new DifferentialRawDiffRenderer())
|
return id(new DifferentialRawDiffRenderer())
|
||||||
->setViewer($this->getActor())
|
->setViewer($this->getActor())
|
||||||
->setFormat($format)
|
->setFormat($format)
|
||||||
->setChangesets($diff->getChangesets())
|
->setChangesets($diff->getChangesets())
|
||||||
|
->setByteLimit($byte_limit)
|
||||||
->buildPatch();
|
->buildPatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class DifferentialRawDiffRenderer extends Phobject {
|
||||||
private $changesets;
|
private $changesets;
|
||||||
private $format = 'unified';
|
private $format = 'unified';
|
||||||
private $viewer;
|
private $viewer;
|
||||||
|
private $byteLimit;
|
||||||
|
|
||||||
public function setFormat($format) {
|
public function setFormat($format) {
|
||||||
$this->format = $format;
|
$this->format = $format;
|
||||||
|
@ -35,6 +36,15 @@ final class DifferentialRawDiffRenderer extends Phobject {
|
||||||
return $this->viewer;
|
return $this->viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setByteLimit($byte_limit) {
|
||||||
|
$this->byteLimit = $byte_limit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByteLimit() {
|
||||||
|
return $this->byteLimit;
|
||||||
|
}
|
||||||
|
|
||||||
public function buildPatch() {
|
public function buildPatch() {
|
||||||
$diff = new DifferentialDiff();
|
$diff = new DifferentialDiff();
|
||||||
$diff->attachChangesets($this->getChangesets());
|
$diff->attachChangesets($this->getChangesets());
|
||||||
|
@ -52,15 +62,18 @@ final class DifferentialRawDiffRenderer extends Phobject {
|
||||||
$bundle = ArcanistBundle::newFromChanges($changes);
|
$bundle = ArcanistBundle::newFromChanges($changes);
|
||||||
$bundle->setLoadFileDataCallback(array($loader, 'loadFileData'));
|
$bundle->setLoadFileDataCallback(array($loader, 'loadFileData'));
|
||||||
|
|
||||||
|
$byte_limit = $this->getByteLimit();
|
||||||
|
if ($byte_limit) {
|
||||||
|
$bundle->setByteLimit($byte_limit);
|
||||||
|
}
|
||||||
|
|
||||||
$format = $this->getFormat();
|
$format = $this->getFormat();
|
||||||
switch ($format) {
|
switch ($format) {
|
||||||
case 'git':
|
case 'git':
|
||||||
return $bundle->toGitPatch();
|
return $bundle->toGitPatch();
|
||||||
break;
|
|
||||||
case 'unified':
|
case 'unified':
|
||||||
default:
|
default:
|
||||||
return $bundle->toUnifiedDiff();
|
return $bundle->toUnifiedDiff();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionInternalAncestorsConduitAPIMethod
|
||||||
|
extends DiffusionQueryConduitAPIMethod {
|
||||||
|
|
||||||
|
public function isInternalAPI() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAPIMethodName() {
|
||||||
|
return 'diffusion.internal.ancestors';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMethodDescription() {
|
||||||
|
return pht('Internal method for filtering ref ancestors.');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function defineReturnType() {
|
||||||
|
return 'list<string>';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function defineCustomParamTypes() {
|
||||||
|
return array(
|
||||||
|
'ref' => 'required string',
|
||||||
|
'commits' => 'required list<string>',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getResult(ConduitAPIRequest $request) {
|
||||||
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
$commits = $request->getValue('commits');
|
||||||
|
$ref = $request->getValue('ref');
|
||||||
|
|
||||||
|
$graph = new PhabricatorGitGraphStream($repository, $ref);
|
||||||
|
|
||||||
|
$keep = array();
|
||||||
|
foreach ($commits as $identifier) {
|
||||||
|
try {
|
||||||
|
$graph->getCommitDate($identifier);
|
||||||
|
$keep[] = $identifier;
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// Not an ancestor.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $keep;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,10 +22,14 @@ final class DiffusionCommitQuery
|
||||||
private $epochMin;
|
private $epochMin;
|
||||||
private $epochMax;
|
private $epochMax;
|
||||||
private $importing;
|
private $importing;
|
||||||
|
private $ancestorsOf;
|
||||||
|
|
||||||
private $needCommitData;
|
private $needCommitData;
|
||||||
private $needDrafts;
|
private $needDrafts;
|
||||||
|
|
||||||
|
private $mustFilterRefs = false;
|
||||||
|
private $refRepository;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -92,7 +96,7 @@ final class DiffusionCommitQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withRepositoryIDs(array $repository_ids) {
|
public function withRepositoryIDs(array $repository_ids) {
|
||||||
$this->repositoryIDs = $repository_ids;
|
$this->repositoryIDs = array_unique($repository_ids);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +156,11 @@ final class DiffusionCommitQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withAncestorsOf(array $refs) {
|
||||||
|
$this->ancestorsOf = $refs;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getIdentifierMap() {
|
public function getIdentifierMap() {
|
||||||
if ($this->identifierMap === null) {
|
if ($this->identifierMap === null) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
@ -307,6 +316,54 @@ final class DiffusionCommitQuery
|
||||||
protected function didFilterPage(array $commits) {
|
protected function didFilterPage(array $commits) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
if ($this->mustFilterRefs) {
|
||||||
|
// If this flag is set, the query has an "Ancestors Of" constraint and
|
||||||
|
// at least one of the constraining refs had too many ancestors for us
|
||||||
|
// to apply the constraint with a big "commitIdentifier IN (%Ls)" clause.
|
||||||
|
// We're going to filter each page and hope we get a full result set
|
||||||
|
// before the query overheats.
|
||||||
|
|
||||||
|
$ancestor_list = mpull($commits, 'getCommitIdentifier');
|
||||||
|
$ancestor_list = array_values($ancestor_list);
|
||||||
|
|
||||||
|
foreach ($this->ancestorsOf as $ref) {
|
||||||
|
try {
|
||||||
|
$ancestor_list = DiffusionQuery::callConduitWithDiffusionRequest(
|
||||||
|
$viewer,
|
||||||
|
DiffusionRequest::newFromDictionary(
|
||||||
|
array(
|
||||||
|
'repository' => $this->refRepository,
|
||||||
|
'user' => $viewer,
|
||||||
|
)),
|
||||||
|
'diffusion.internal.ancestors',
|
||||||
|
array(
|
||||||
|
'ref' => $ref,
|
||||||
|
'commits' => $ancestor_list,
|
||||||
|
));
|
||||||
|
} catch (ConduitClientException $ex) {
|
||||||
|
throw new PhabricatorSearchConstraintException(
|
||||||
|
$ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ancestor_list) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ancestor_list = array_fuse($ancestor_list);
|
||||||
|
foreach ($commits as $key => $commit) {
|
||||||
|
$identifier = $commit->getCommitIdentifier();
|
||||||
|
if (!isset($ancestor_list[$identifier])) {
|
||||||
|
$this->didRejectResult($commit);
|
||||||
|
unset($commits[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$commits) {
|
||||||
|
return $commits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->needCommitData) {
|
if ($this->needCommitData) {
|
||||||
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
|
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
|
||||||
'commitID in (%Ld)',
|
'commitID in (%Ld)',
|
||||||
|
@ -364,6 +421,95 @@ final class DiffusionCommitQuery
|
||||||
$this->withRepositoryIDs($repository_ids);
|
$this->withRepositoryIDs($repository_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->ancestorsOf !== null) {
|
||||||
|
if (count($this->repositoryIDs) !== 1) {
|
||||||
|
throw new PhabricatorSearchConstraintException(
|
||||||
|
pht(
|
||||||
|
'To search for commits which are ancestors of particular refs, '.
|
||||||
|
'you must constrain the search to exactly one repository.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository_id = head($this->repositoryIDs);
|
||||||
|
$history_limit = $this->getRawResultLimit() * 32;
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$repository = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($repository_id))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$repository) {
|
||||||
|
throw new PhabricatorEmptyQueryException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($repository->isSVN()) {
|
||||||
|
throw new PhabricatorSearchConstraintException(
|
||||||
|
pht(
|
||||||
|
'Subversion does not support searching for ancestors of '.
|
||||||
|
'a particular ref. This operation is not meaningful in '.
|
||||||
|
'Subversion.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($repository->isHg()) {
|
||||||
|
throw new PhabricatorSearchConstraintException(
|
||||||
|
pht(
|
||||||
|
'Mercurial does not currently support searching for ancestors of '.
|
||||||
|
'a particular ref.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$can_constrain = true;
|
||||||
|
$history_identifiers = array();
|
||||||
|
foreach ($this->ancestorsOf as $key => $ref) {
|
||||||
|
try {
|
||||||
|
$raw_history = DiffusionQuery::callConduitWithDiffusionRequest(
|
||||||
|
$viewer,
|
||||||
|
DiffusionRequest::newFromDictionary(
|
||||||
|
array(
|
||||||
|
'repository' => $repository,
|
||||||
|
'user' => $viewer,
|
||||||
|
)),
|
||||||
|
'diffusion.historyquery',
|
||||||
|
array(
|
||||||
|
'commit' => $ref,
|
||||||
|
'limit' => $history_limit,
|
||||||
|
));
|
||||||
|
} catch (ConduitClientException $ex) {
|
||||||
|
throw new PhabricatorSearchConstraintException(
|
||||||
|
$ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$ref_identifiers = array();
|
||||||
|
foreach ($raw_history['pathChanges'] as $change) {
|
||||||
|
$ref_identifiers[] = $change['commitIdentifier'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this ref had fewer total commits than the limit, we're safe to
|
||||||
|
// apply the constraint as a large `IN (...)` query for a list of
|
||||||
|
// commit identifiers. This is efficient.
|
||||||
|
if ($history_limit) {
|
||||||
|
if (count($ref_identifiers) >= $history_limit) {
|
||||||
|
$can_constrain = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$history_identifiers += array_fuse($ref_identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all refs had a small number of ancestors, we can just put the
|
||||||
|
// constraint into the query here and we're done. Otherwise, we need
|
||||||
|
// to filter each page after it comes out of the MySQL layer.
|
||||||
|
if ($can_constrain) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'commit.commitIdentifier IN (%Ls)',
|
||||||
|
$history_identifiers);
|
||||||
|
} else {
|
||||||
|
$this->mustFilterRefs = true;
|
||||||
|
$this->refRepository = $repository;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
|
|
|
@ -516,7 +516,7 @@ final class ManiphestTaskSearchEngine
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ManiphestTaskPoints::getIsEnabled()) {
|
if (ManiphestTaskPoints::getIsEnabled()) {
|
||||||
$fields[] = id(new PhabricatorIntExportField())
|
$fields[] = id(new PhabricatorDoubleExportField())
|
||||||
->setKey('points')
|
->setKey('points')
|
||||||
->setLabel('Points');
|
->setLabel('Points');
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,13 +162,17 @@ EOTEXT
|
||||||
->setIsConduitOnly(true)
|
->setIsConduitOnly(true)
|
||||||
->setValue($object->getStatus())
|
->setValue($object->getStatus())
|
||||||
->setOptions($object->getStatusNameMap()),
|
->setOptions($object->getStatusNameMap()),
|
||||||
id(new PhabricatorStringListEditField())
|
id(new PhabricatorCheckboxesEditField())
|
||||||
->setKey('ignored')
|
->setKey('ignored')
|
||||||
->setLabel(pht('Ignored Attributes'))
|
->setLabel(pht('Ignored Attributes'))
|
||||||
->setDescription(pht('Ignore paths with any of these attributes.'))
|
->setDescription(pht('Ignore paths with any of these attributes.'))
|
||||||
->setTransactionType(
|
->setTransactionType(
|
||||||
PhabricatorOwnersPackageIgnoredTransaction::TRANSACTIONTYPE)
|
PhabricatorOwnersPackageIgnoredTransaction::TRANSACTIONTYPE)
|
||||||
->setValue(array_keys($object->getIgnoredPathAttributes())),
|
->setValue(array_keys($object->getIgnoredPathAttributes()))
|
||||||
|
->setOptions(
|
||||||
|
array(
|
||||||
|
'generated' => pht('Ignore generated files (review only).'),
|
||||||
|
)),
|
||||||
id(new PhabricatorConduitEditField())
|
id(new PhabricatorConduitEditField())
|
||||||
->setKey('paths.set')
|
->setKey('paths.set')
|
||||||
->setLabel(pht('Paths'))
|
->setLabel(pht('Paths'))
|
||||||
|
|
|
@ -64,9 +64,12 @@ final class PasteCreateConduitAPIMethod extends PasteConduitAPIMethod {
|
||||||
->setTransactionType(PhabricatorPasteTitleTransaction::TRANSACTIONTYPE)
|
->setTransactionType(PhabricatorPasteTitleTransaction::TRANSACTIONTYPE)
|
||||||
->setNewValue($title);
|
->setNewValue($title);
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPasteTransaction())
|
if (strlen($language)) {
|
||||||
->setTransactionType(PhabricatorPasteLanguageTransaction::TRANSACTIONTYPE)
|
$xactions[] = id(new PhabricatorPasteTransaction())
|
||||||
->setNewValue($language);
|
->setTransactionType(
|
||||||
|
PhabricatorPasteLanguageTransaction::TRANSACTIONTYPE)
|
||||||
|
->setNewValue($language);
|
||||||
|
}
|
||||||
|
|
||||||
$editor = id(new PhabricatorPasteEditor())
|
$editor = id(new PhabricatorPasteEditor())
|
||||||
->setActor($viewer)
|
->setActor($viewer)
|
||||||
|
|
|
@ -38,4 +38,20 @@ final class PhabricatorPasteLanguageTransaction
|
||||||
$this->renderLanguageValue($this->getNewValue()));
|
$this->renderLanguageValue($this->getNewValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function validateTransactions($object, array $xactions) {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$new = $xaction->getNewValue();
|
||||||
|
|
||||||
|
if ($new !== null && !strlen($new)) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht('Paste language must be null or a nonempty string.'),
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,7 +364,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
if (!strlen($name)) {
|
if (!strlen($name)) {
|
||||||
$name = $this->getName();
|
$name = $this->getName();
|
||||||
$name = phutil_utf8_strtolower($name);
|
$name = phutil_utf8_strtolower($name);
|
||||||
$name = preg_replace('@[/ -:<>]+@', '-', $name);
|
$name = preg_replace('@[ -/:->]+@', '-', $name);
|
||||||
$name = trim($name, '-');
|
$name = trim($name, '-');
|
||||||
if (!strlen($name)) {
|
if (!strlen($name)) {
|
||||||
$name = $this->getCallsign();
|
$name = $this->getCallsign();
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorCheckboxesEditField
|
||||||
|
extends PhabricatorEditField {
|
||||||
|
|
||||||
|
private $options;
|
||||||
|
|
||||||
|
protected function newControl() {
|
||||||
|
$options = $this->getOptions();
|
||||||
|
|
||||||
|
return id(new AphrontFormCheckboxControl())
|
||||||
|
->setOptions($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newConduitParameterType() {
|
||||||
|
return new ConduitStringListParameterType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newHTTPParameterType() {
|
||||||
|
return new AphrontStringListHTTPParameterType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOptions(array $options) {
|
||||||
|
$this->options = $options;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions() {
|
||||||
|
if ($this->options === null) {
|
||||||
|
throw new PhutilInvalidStateException('setOptions');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -302,6 +302,14 @@ abstract class PhabricatorEditField extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreviewPanel() {
|
public function getPreviewPanel() {
|
||||||
|
if ($this->getIsHidden()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getIsLocked()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->previewPanel;
|
return $this->previewPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,21 @@ behavior. If you want more powerful auditing behavior, you can use Herald to
|
||||||
write more sophisticated rules.
|
write more sophisticated rules.
|
||||||
|
|
||||||
|
|
||||||
|
Ignored Attributes
|
||||||
|
==================
|
||||||
|
|
||||||
|
You can automatically exclude certain types of files, like generated files,
|
||||||
|
with **Ignored Attributes**.
|
||||||
|
|
||||||
|
When a package is marked as ignoring files with a particular attribute, and
|
||||||
|
a file in a particular change has that attribute, the file will be ignored when
|
||||||
|
computing ownership.
|
||||||
|
|
||||||
|
(This feature is currently rough, only works for Differential revisions, and
|
||||||
|
may not always compute the correct set of owning packages in some complex
|
||||||
|
cases where it interacts with dominion rules.)
|
||||||
|
|
||||||
|
|
||||||
Files in Multiple Packages
|
Files in Multiple Packages
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorDoubleExportField
|
||||||
|
extends PhabricatorExportField {
|
||||||
|
|
||||||
|
public function getNaturalValue($value) {
|
||||||
|
if ($value === null) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (double)$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phutil-external-symbol class PHPExcel_Cell_DataType
|
||||||
|
*/
|
||||||
|
public function formatPHPExcelCell($cell, $style) {
|
||||||
|
$cell->setDataType(PHPExcel_Cell_DataType::TYPE_NUMERIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCharacterWidth() {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -155,8 +155,12 @@ EOHELP
|
||||||
return $this->sheet;
|
return $this->sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phutil-external-symbol class PHPExcel_Cell
|
||||||
|
*/
|
||||||
private function getCellName($col, $row = null) {
|
private function getCellName($col, $row = null) {
|
||||||
$col_name = chr(ord('A') + $col);
|
$col_name = PHPExcel_Cell::stringFromColumnIndex($col);
|
||||||
|
|
||||||
if ($row === null) {
|
if ($row === null) {
|
||||||
return $col_name;
|
return $col_name;
|
||||||
|
|
|
@ -34,6 +34,20 @@ final class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
return 'aphront-form-control-checkbox';
|
return 'aphront-form-control-checkbox';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setOptions(array $options) {
|
||||||
|
$boxes = array();
|
||||||
|
foreach ($options as $key => $value) {
|
||||||
|
$boxes[] = array(
|
||||||
|
'value' => $key,
|
||||||
|
'label' => $value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->boxes = $boxes;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function renderInput() {
|
protected function renderInput() {
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($this->boxes as $box) {
|
foreach ($this->boxes as $box) {
|
||||||
|
@ -41,14 +55,28 @@ final class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
if ($id === null) {
|
if ($id === null) {
|
||||||
$id = celerity_generate_unique_node_id();
|
$id = celerity_generate_unique_node_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$name = idx($box, 'name');
|
||||||
|
if ($name === null) {
|
||||||
|
$name = $this->getName().'[]';
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $box['value'];
|
||||||
|
|
||||||
|
if (array_key_exists('checked', $box)) {
|
||||||
|
$checked = $box['checked'];
|
||||||
|
} else {
|
||||||
|
$checked = in_array($value, $this->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
$checkbox = phutil_tag(
|
$checkbox = phutil_tag(
|
||||||
'input',
|
'input',
|
||||||
array(
|
array(
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'type' => 'checkbox',
|
'type' => 'checkbox',
|
||||||
'name' => $box['name'],
|
'name' => $name,
|
||||||
'value' => $box['value'],
|
'value' => $box['value'],
|
||||||
'checked' => $box['checked'] ? 'checked' : null,
|
'checked' => $checked ? 'checked' : null,
|
||||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
));
|
));
|
||||||
$label = phutil_tag(
|
$label = phutil_tag(
|
||||||
|
|
|
@ -8,6 +8,7 @@ final class PHUICrumbView extends AphrontView {
|
||||||
private $isLastCrumb;
|
private $isLastCrumb;
|
||||||
private $workflow;
|
private $workflow;
|
||||||
private $aural;
|
private $aural;
|
||||||
|
private $alwaysVisible;
|
||||||
|
|
||||||
public function setAural($aural) {
|
public function setAural($aural) {
|
||||||
$this->aural = $aural;
|
$this->aural = $aural;
|
||||||
|
@ -18,6 +19,22 @@ final class PHUICrumbView extends AphrontView {
|
||||||
return $this->aural;
|
return $this->aural;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make this crumb always visible, even on devices where it would normally
|
||||||
|
* be hidden.
|
||||||
|
*
|
||||||
|
* @param bool True to make the crumb always visible.
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public function setAlwaysVisible($always_visible) {
|
||||||
|
$this->alwaysVisible = $always_visible;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAlwaysVisible() {
|
||||||
|
return $this->alwaysVisible;
|
||||||
|
}
|
||||||
|
|
||||||
public function setWorkflow($workflow) {
|
public function setWorkflow($workflow) {
|
||||||
$this->workflow = $workflow;
|
$this->workflow = $workflow;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -98,6 +115,10 @@ final class PHUICrumbView extends AphrontView {
|
||||||
$classes[] = 'phabricator-last-crumb';
|
$classes[] = 'phabricator-last-crumb';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->getAlwaysVisible()) {
|
||||||
|
$classes[] = 'phui-crumb-always-visible';
|
||||||
|
}
|
||||||
|
|
||||||
$tag = javelin_tag(
|
$tag = javelin_tag(
|
||||||
$this->href ? 'a' : 'span',
|
$this->href ? 'a' : 'span',
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-phone .phui-crumb-view.phabricator-last-crumb .phui-crumb-name,
|
.device-phone .phui-crumb-view.phabricator-last-crumb .phui-crumb-name,
|
||||||
|
.device-phone .phui-crumb-view.phui-crumb-always-visible .phui-crumb-name,
|
||||||
|
.device-phone .phui-crumb-view.phui-crumb-always-visible + .phui-crumb-divider,
|
||||||
.device-phone .phui-crumb-view.phui-crumb-has-icon,
|
.device-phone .phui-crumb-view.phui-crumb-has-icon,
|
||||||
.device-phone .phui-crumb-has-icon + .phui-crumb-divider {
|
.device-phone .phui-crumb-has-icon + .phui-crumb-divider {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -395,8 +395,12 @@ JX.install('Tokenizer', {
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
if (!this._focus.value.length) {
|
if (!this._focus.value.length) {
|
||||||
|
// In unusual cases, it's possible for us to end up with a token
|
||||||
|
// that has the empty string ("") as a value. Support removal of
|
||||||
|
// this unusual token.
|
||||||
|
|
||||||
var tok;
|
var tok;
|
||||||
while ((tok = this._tokens.pop())) {
|
while ((tok = this._tokens.pop()) !== null) {
|
||||||
if (this._remove(tok, true)) {
|
if (this._remove(tok, true)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue