mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 18:10:53 +01:00
(stable) Promote 2017 Week 22
This commit is contained in:
commit
557c432794
87 changed files with 1489 additions and 1667 deletions
|
@ -93,6 +93,7 @@ return array(
|
|||
'phabricator-core-css',
|
||||
'phabricator-zindex-css',
|
||||
'phui-button-css',
|
||||
'phui-button-simple-css',
|
||||
'phui-theme-css',
|
||||
'phabricator-standard-page-view',
|
||||
'aphront-dialog-view-css',
|
||||
|
@ -203,9 +204,6 @@ return array(
|
|||
'javelin-behavior-differential-user-select',
|
||||
'javelin-behavior-aphront-more',
|
||||
|
||||
'phabricator-scroll-objective',
|
||||
'phabricator-scroll-objective-list',
|
||||
|
||||
'phabricator-diff-inline',
|
||||
'phabricator-diff-changeset',
|
||||
'phabricator-diff-changeset-list',
|
||||
|
|
|
@ -728,8 +728,10 @@ phutil_register_library_map(array(
|
|||
'DiffusionGitSSHWorkflow' => 'applications/diffusion/ssh/DiffusionGitSSHWorkflow.php',
|
||||
'DiffusionGitUploadPackSSHWorkflow' => 'applications/diffusion/ssh/DiffusionGitUploadPackSSHWorkflow.php',
|
||||
'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
|
||||
'DiffusionHistoryListView' => 'applications/diffusion/view/DiffusionHistoryListView.php',
|
||||
'DiffusionHistoryQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionHistoryQueryConduitAPIMethod.php',
|
||||
'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
|
||||
'DiffusionHistoryView' => 'applications/diffusion/view/DiffusionHistoryView.php',
|
||||
'DiffusionHovercardEngineExtension' => 'applications/diffusion/engineextension/DiffusionHovercardEngineExtension.php',
|
||||
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
|
||||
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
|
||||
|
@ -1393,10 +1395,6 @@ phutil_register_library_map(array(
|
|||
'HeraldTranscriptTestCase' => 'applications/herald/storage/__tests__/HeraldTranscriptTestCase.php',
|
||||
'HeraldUtilityActionGroup' => 'applications/herald/action/HeraldUtilityActionGroup.php',
|
||||
'Javelin' => 'infrastructure/javelin/Javelin.php',
|
||||
'JavelinReactorUIExample' => 'applications/uiexample/examples/JavelinReactorUIExample.php',
|
||||
'JavelinUIExample' => 'applications/uiexample/examples/JavelinUIExample.php',
|
||||
'JavelinViewExampleServerView' => 'applications/uiexample/examples/JavelinViewExampleServerView.php',
|
||||
'JavelinViewUIExample' => 'applications/uiexample/examples/JavelinViewUIExample.php',
|
||||
'LegalpadController' => 'applications/legalpad/controller/LegalpadController.php',
|
||||
'LegalpadCreateDocumentsCapability' => 'applications/legalpad/capability/LegalpadCreateDocumentsCapability.php',
|
||||
'LegalpadDAO' => 'applications/legalpad/storage/LegalpadDAO.php',
|
||||
|
@ -1808,6 +1806,7 @@ phutil_register_library_map(array(
|
|||
'PHUIUserAvailabilityView' => 'applications/calendar/view/PHUIUserAvailabilityView.php',
|
||||
'PHUIWorkboardView' => 'view/phui/PHUIWorkboardView.php',
|
||||
'PHUIWorkpanelView' => 'view/phui/PHUIWorkpanelView.php',
|
||||
'PHUIXComponentsExample' => 'applications/uiexample/examples/PHUIXComponentsExample.php',
|
||||
'PassphraseAbstractKey' => 'applications/passphrase/keys/PassphraseAbstractKey.php',
|
||||
'PassphraseConduitAPIMethod' => 'applications/passphrase/conduit/PassphraseConduitAPIMethod.php',
|
||||
'PassphraseController' => 'applications/passphrase/controller/PassphraseController.php',
|
||||
|
@ -2144,7 +2143,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBadgesTransactionComment' => 'applications/badges/storage/PhabricatorBadgesTransactionComment.php',
|
||||
'PhabricatorBadgesTransactionQuery' => 'applications/badges/query/PhabricatorBadgesTransactionQuery.php',
|
||||
'PhabricatorBadgesViewController' => 'applications/badges/controller/PhabricatorBadgesViewController.php',
|
||||
'PhabricatorBarePageUIExample' => 'applications/uiexample/examples/PhabricatorBarePageUIExample.php',
|
||||
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
|
||||
'PhabricatorBaseURISetupCheck' => 'applications/config/check/PhabricatorBaseURISetupCheck.php',
|
||||
'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
|
||||
|
@ -2159,7 +2157,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBuiltinDraftEngine' => 'applications/transactions/draft/PhabricatorBuiltinDraftEngine.php',
|
||||
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
|
||||
'PhabricatorBulkContentSource' => 'infrastructure/daemon/contentsource/PhabricatorBulkContentSource.php',
|
||||
'PhabricatorBusyUIExample' => 'applications/uiexample/examples/PhabricatorBusyUIExample.php',
|
||||
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
|
||||
'PhabricatorCacheEngine' => 'applications/system/engine/PhabricatorCacheEngine.php',
|
||||
'PhabricatorCacheEngineExtension' => 'applications/system/engine/PhabricatorCacheEngineExtension.php',
|
||||
|
@ -2522,6 +2519,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCustomFieldStorageQuery' => 'infrastructure/customfield/query/PhabricatorCustomFieldStorageQuery.php',
|
||||
'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php',
|
||||
'PhabricatorCustomLogoConfigType' => 'applications/config/custom/PhabricatorCustomLogoConfigType.php',
|
||||
'PhabricatorCustomUIFooterConfigType' => 'applications/config/custom/PhabricatorCustomUIFooterConfigType.php',
|
||||
'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php',
|
||||
'PhabricatorDaemonBulkJobController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobController.php',
|
||||
'PhabricatorDaemonBulkJobListController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobListController.php',
|
||||
|
@ -3027,7 +3025,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorLiskFulltextEngineExtension' => 'applications/search/engineextension/PhabricatorLiskFulltextEngineExtension.php',
|
||||
'PhabricatorLiskSearchEngineExtension' => 'applications/search/engineextension/PhabricatorLiskSearchEngineExtension.php',
|
||||
'PhabricatorLiskSerializer' => 'infrastructure/storage/lisk/PhabricatorLiskSerializer.php',
|
||||
'PhabricatorListFilterUIExample' => 'applications/uiexample/examples/PhabricatorListFilterUIExample.php',
|
||||
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
|
||||
'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
|
||||
'PhabricatorLocaleScopeGuard' => 'infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php',
|
||||
|
@ -3993,7 +3990,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSlowvoteVoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteVoteController.php',
|
||||
'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php',
|
||||
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
|
||||
'PhabricatorSortTableUIExample' => 'applications/uiexample/examples/PhabricatorSortTableUIExample.php',
|
||||
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
|
||||
'PhabricatorSpaceEditField' => 'applications/transactions/editfield/PhabricatorSpaceEditField.php',
|
||||
'PhabricatorSpacesApplication' => 'applications/spaces/application/PhabricatorSpacesApplication.php',
|
||||
|
@ -4157,7 +4153,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorTokensCurtainExtension' => 'applications/tokens/engineextension/PhabricatorTokensCurtainExtension.php',
|
||||
'PhabricatorTokensSettingsPanel' => 'applications/settings/panel/PhabricatorTokensSettingsPanel.php',
|
||||
'PhabricatorTokensToken' => 'applications/tokens/storage/PhabricatorTokensToken.php',
|
||||
'PhabricatorTooltipUIExample' => 'applications/uiexample/examples/PhabricatorTooltipUIExample.php',
|
||||
'PhabricatorTransactionChange' => 'applications/transactions/data/PhabricatorTransactionChange.php',
|
||||
'PhabricatorTransactionRemarkupChange' => 'applications/transactions/data/PhabricatorTransactionRemarkupChange.php',
|
||||
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
|
||||
|
@ -5704,8 +5699,10 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'DiffusionGitUploadPackSSHWorkflow' => 'DiffusionGitSSHWorkflow',
|
||||
'DiffusionHistoryController' => 'DiffusionController',
|
||||
'DiffusionHistoryListView' => 'DiffusionHistoryView',
|
||||
'DiffusionHistoryQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
'DiffusionHistoryTableView' => 'DiffusionView',
|
||||
'DiffusionHistoryTableView' => 'DiffusionHistoryView',
|
||||
'DiffusionHistoryView' => 'DiffusionView',
|
||||
'DiffusionHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
|
||||
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
||||
|
@ -6478,10 +6475,6 @@ phutil_register_library_map(array(
|
|||
'HeraldTranscriptTestCase' => 'PhabricatorTestCase',
|
||||
'HeraldUtilityActionGroup' => 'HeraldActionGroup',
|
||||
'Javelin' => 'Phobject',
|
||||
'JavelinReactorUIExample' => 'PhabricatorUIExample',
|
||||
'JavelinUIExample' => 'PhabricatorUIExample',
|
||||
'JavelinViewExampleServerView' => 'AphrontView',
|
||||
'JavelinViewUIExample' => 'PhabricatorUIExample',
|
||||
'LegalpadController' => 'PhabricatorController',
|
||||
'LegalpadCreateDocumentsCapability' => 'PhabricatorPolicyCapability',
|
||||
'LegalpadDAO' => 'PhabricatorLiskDAO',
|
||||
|
@ -6946,6 +6939,7 @@ phutil_register_library_map(array(
|
|||
'PHUIUserAvailabilityView' => 'AphrontTagView',
|
||||
'PHUIWorkboardView' => 'AphrontTagView',
|
||||
'PHUIWorkpanelView' => 'AphrontTagView',
|
||||
'PHUIXComponentsExample' => 'PhabricatorUIExample',
|
||||
'PassphraseAbstractKey' => 'Phobject',
|
||||
'PassphraseConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'PassphraseController' => 'PhabricatorController',
|
||||
|
@ -7337,7 +7331,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBadgesTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorBadgesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorBadgesViewController' => 'PhabricatorBadgesProfileController',
|
||||
'PhabricatorBarePageUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorBarePageView' => 'AphrontPageView',
|
||||
'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
|
||||
|
@ -7352,7 +7345,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBuiltinDraftEngine' => 'PhabricatorDraftEngine',
|
||||
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
|
||||
'PhabricatorBulkContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorBusyUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorCacheEngine' => 'Phobject',
|
||||
'PhabricatorCacheEngineExtension' => 'Phobject',
|
||||
|
@ -7779,6 +7771,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCustomFieldStorageQuery' => 'Phobject',
|
||||
'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage',
|
||||
'PhabricatorCustomLogoConfigType' => 'PhabricatorConfigOptionType',
|
||||
'PhabricatorCustomUIFooterConfigType' => 'PhabricatorConfigJSONOptionType',
|
||||
'PhabricatorDaemon' => 'PhutilDaemon',
|
||||
'PhabricatorDaemonBulkJobController' => 'PhabricatorDaemonController',
|
||||
'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonBulkJobController',
|
||||
|
@ -8352,7 +8345,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorLiskFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension',
|
||||
'PhabricatorLiskSearchEngineExtension' => 'PhabricatorSearchEngineExtension',
|
||||
'PhabricatorLiskSerializer' => 'Phobject',
|
||||
'PhabricatorListFilterUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
|
||||
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorLocaleScopeGuard' => 'Phobject',
|
||||
|
@ -9517,7 +9509,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSlowvoteVoteController' => 'PhabricatorSlowvoteController',
|
||||
'PhabricatorSlug' => 'Phobject',
|
||||
'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorSortTableUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorSourceCodeView' => 'AphrontView',
|
||||
'PhabricatorSpaceEditField' => 'PhabricatorEditField',
|
||||
'PhabricatorSpacesApplication' => 'PhabricatorApplication',
|
||||
|
@ -9698,7 +9689,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
),
|
||||
'PhabricatorTooltipUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorTransactionChange' => 'Phobject',
|
||||
'PhabricatorTransactionRemarkupChange' => 'PhabricatorTransactionChange',
|
||||
'PhabricatorTransactions' => 'Phobject',
|
||||
|
|
|
@ -103,7 +103,7 @@ final class PhabricatorAuthListController
|
|||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->setHref($this->getApplicationURI('config/new/'))
|
||||
->setIcon('fa-plus')
|
||||
->setDisabled(!$can_manage)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCustomUIFooterConfigType
|
||||
extends PhabricatorConfigJSONOptionType {
|
||||
|
||||
public function validateOption(PhabricatorConfigOption $option, $value) {
|
||||
if (!is_array($value)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Footer configuration is not valid: value must be a list of '.
|
||||
'items.'));
|
||||
}
|
||||
|
||||
foreach ($value as $idx => $item) {
|
||||
if (!is_array($item)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Footer item with index "%s" is invalid: each item must be a '.
|
||||
'dictionary describing a footer item.',
|
||||
$idx));
|
||||
}
|
||||
|
||||
try {
|
||||
PhutilTypeSpec::checkMap(
|
||||
$item,
|
||||
array(
|
||||
'name' => 'string',
|
||||
'href' => 'optional string',
|
||||
));
|
||||
} catch (Exception $ex) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Footer item with index "%s" is invalid: %s',
|
||||
$idx,
|
||||
$ex->getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -46,6 +46,7 @@ final class PhabricatorUIConfigOptions
|
|||
EOJSON;
|
||||
|
||||
$logo_type = 'custom:PhabricatorCustomLogoConfigType';
|
||||
$footer_type = 'custom:PhabricatorCustomUIFooterConfigType';
|
||||
|
||||
return array(
|
||||
$this->newOption('ui.header-color', 'enum', 'blindigo')
|
||||
|
@ -63,7 +64,7 @@ EOJSON;
|
|||
"Phabricator logo in the site header.\n\n".
|
||||
" - **Wordmark**: Choose new text to display next to the logo. ".
|
||||
"By default, the header displays //Phabricator//.\n\n")),
|
||||
$this->newOption('ui.footer-items', 'list<wild>', array())
|
||||
$this->newOption('ui.footer-items', $footer_type, array())
|
||||
->setSummary(
|
||||
pht(
|
||||
'Allows you to add footer links on most pages.'))
|
||||
|
|
|
@ -204,7 +204,6 @@ final class DifferentialChangesetDetailView extends AphrontView {
|
|||
'loaded' => $this->getLoaded(),
|
||||
'undoTemplates' => hsprintf('%s', $renderer->renderUndoTemplates()),
|
||||
'displayPath' => hsprintf('%s', $display_parts),
|
||||
'objectiveName' => basename($display_filename),
|
||||
'icon' => $display_icon,
|
||||
),
|
||||
'class' => $class,
|
||||
|
|
|
@ -203,15 +203,11 @@ final class DifferentialChangesetListView extends AphrontView {
|
|||
|
||||
$this->requireResource('aphront-tooltip-css');
|
||||
|
||||
$show_objectives =
|
||||
PhabricatorEnv::getEnvConfig('phabricator.show-prototypes');
|
||||
|
||||
$this->initBehavior(
|
||||
'differential-populate',
|
||||
array(
|
||||
'changesetViewIDs' => $ids,
|
||||
'inlineURI' => $this->inlineURI,
|
||||
'showObjectives' => $show_objectives,
|
||||
'pht' => array(
|
||||
'Open in Editor' => pht('Open in Editor'),
|
||||
'Show All Context' => pht('Show All Context'),
|
||||
|
|
|
@ -26,11 +26,6 @@ final class DiffusionHistoryController extends DiffusionController {
|
|||
'limit' => $pager->getPageSize() + 1,
|
||||
);
|
||||
|
||||
if (!$request->getBool('copies')) {
|
||||
$params['needDirectChanges'] = true;
|
||||
$params['needChildChanges'] = true;
|
||||
}
|
||||
|
||||
$history_results = $this->callConduitWithDiffusionRequest(
|
||||
'diffusion.historyquery',
|
||||
$params);
|
||||
|
@ -39,27 +34,12 @@ final class DiffusionHistoryController extends DiffusionController {
|
|||
|
||||
$history = $pager->sliceResults($history);
|
||||
|
||||
$show_graph = !strlen($drequest->getPath());
|
||||
$history_table = id(new DiffusionHistoryTableView())
|
||||
->setUser($request->getUser())
|
||||
$history_list = id(new DiffusionHistoryListView())
|
||||
->setViewer($viewer)
|
||||
->setDiffusionRequest($drequest)
|
||||
->setHistory($history);
|
||||
|
||||
$history_table->loadRevisions();
|
||||
|
||||
if ($show_graph) {
|
||||
$history_table->setParents($history_results['parents']);
|
||||
$history_table->setIsHead(!$pager->getOffset());
|
||||
$history_table->setIsTail(!$pager->getHasMorePages());
|
||||
}
|
||||
|
||||
$history_header = $this->buildHistoryHeader($drequest);
|
||||
$history_panel = id(new PHUIObjectBoxView())
|
||||
->setHeader($history_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($history_table)
|
||||
->setPager($pager);
|
||||
|
||||
$history_list->loadRevisions();
|
||||
$header = $this->buildHeader($drequest);
|
||||
|
||||
$crumbs = $this->buildCrumbs(
|
||||
|
@ -70,44 +50,32 @@ final class DiffusionHistoryController extends DiffusionController {
|
|||
));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$title = array(
|
||||
pht('History'),
|
||||
$repository->getDisplayName(),
|
||||
);
|
||||
|
||||
$pager = id(new PHUIBoxView())
|
||||
->addClass('mlb')
|
||||
->appendChild($pager);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$history_panel,
|
||||
$history_list,
|
||||
$pager,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(
|
||||
array(
|
||||
pht('History'),
|
||||
$repository->getDisplayName(),
|
||||
))
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild(
|
||||
array(
|
||||
$view,
|
||||
));
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildHeader(DiffusionRequest $drequest) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$tag = $this->renderCommitHashTag($drequest);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($drequest->getRepository())
|
||||
->addTag($tag)
|
||||
->setHeader($this->renderPathLinks($drequest, $mode = 'history'))
|
||||
->setHeaderIcon('fa-clock-o');
|
||||
|
||||
return $header;
|
||||
|
||||
}
|
||||
|
||||
private function buildHistoryHeader(DiffusionRequest $drequest) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$browse_uri = $drequest->generateURI(
|
||||
array(
|
||||
'action' => 'browse',
|
||||
|
@ -117,36 +85,18 @@ final class DiffusionHistoryController extends DiffusionController {
|
|||
->setTag('a')
|
||||
->setText(pht('Browse'))
|
||||
->setHref($browse_uri)
|
||||
->setIcon('fa-files-o');
|
||||
|
||||
// TODO: Sometimes we do have a change view, we need to look at the most
|
||||
// recent history entry to figure it out.
|
||||
|
||||
$request = $this->getRequest();
|
||||
if ($request->getBool('copies')) {
|
||||
$branch_name = pht('Hide Copies/Branches');
|
||||
$branch_uri = $request->getRequestURI()
|
||||
->alter('offset', null)
|
||||
->alter('copies', null);
|
||||
} else {
|
||||
$branch_name = pht('Show Copies/Branches');
|
||||
$branch_uri = $request->getRequestURI()
|
||||
->alter('offset', null)
|
||||
->alter('copies', true);
|
||||
}
|
||||
|
||||
$branch_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText($branch_name)
|
||||
->setIcon('fa-code-fork')
|
||||
->setHref($branch_uri);
|
||||
->setIcon('fa-code');
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('History'))
|
||||
->addActionLink($browse_button)
|
||||
->addActionLink($branch_button);
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($drequest->getRepository())
|
||||
->addTag($tag)
|
||||
->setHeader($this->renderPathLinks($drequest, $mode = 'history'))
|
||||
->setHeaderIcon('fa-clock-o')
|
||||
->addActionLink($browse_button);
|
||||
|
||||
return $header;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,28 @@ final class DiffusionCommitListView extends AphrontView {
|
|||
return $this->commits;
|
||||
}
|
||||
|
||||
public function setHandles(array $handles) {
|
||||
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||
$this->handles = $handles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getRequiredHandlePHIDs() {
|
||||
$phids = array();
|
||||
foreach ($this->history as $item) {
|
||||
$data = $item->getCommitData();
|
||||
if ($data) {
|
||||
if ($data->getCommitDetail('authorPHID')) {
|
||||
$phids[$data->getCommitDetail('authorPHID')] = true;
|
||||
}
|
||||
if ($data->getCommitDetail('committerPHID')) {
|
||||
$phids[$data->getCommitDetail('committerPHID')] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_keys($phids);
|
||||
}
|
||||
|
||||
private function getCommitDescription($phid) {
|
||||
if ($this->commits === null) {
|
||||
return pht('(Unknown Commit)');
|
||||
|
@ -114,12 +136,10 @@ final class DiffusionCommitListView extends AphrontView {
|
|||
if ($author_phid) {
|
||||
$author_name = $handles[$author_phid]->renderLink();
|
||||
$author_image_uri = $handles[$author_phid]->getImageURI();
|
||||
$author_image_href = $handles[$author_phid]->getURI();
|
||||
} else {
|
||||
$author_name = $commit->getCommitData()->getAuthorName();
|
||||
$author_image_uri =
|
||||
celerity_get_resource_uri('/rsrc/image/people/user0.png');
|
||||
$author_image_href = null;
|
||||
}
|
||||
|
||||
$commit_tag = id(new PHUITagView())
|
||||
|
@ -134,7 +154,6 @@ final class DiffusionCommitListView extends AphrontView {
|
|||
->setDisabled($commit->isUnreachable())
|
||||
->setDescription($message)
|
||||
->setImageURI($author_image_uri)
|
||||
->setImageHref($author_image_href)
|
||||
->addByline(pht('Author: %s', $author_name))
|
||||
->addIcon('none', $committed)
|
||||
->addAttribute($commit_tag);
|
||||
|
|
181
src/applications/diffusion/view/DiffusionHistoryListView.php
Normal file
181
src/applications/diffusion/view/DiffusionHistoryListView.php
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionHistoryListView extends DiffusionHistoryView {
|
||||
|
||||
public function render() {
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
$viewer = $this->getUser();
|
||||
$repository = $drequest->getRepository();
|
||||
|
||||
require_celerity_resource('diffusion-history-css');
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
$buildables = $this->loadBuildables(
|
||||
mpull($this->getHistory(), 'getCommit'));
|
||||
|
||||
$show_revisions = PhabricatorApplication::isClassInstalledForViewer(
|
||||
'PhabricatorDifferentialApplication',
|
||||
$viewer);
|
||||
|
||||
$handles = $viewer->loadHandles($this->getRequiredHandlePHIDs());
|
||||
|
||||
$show_builds = PhabricatorApplication::isClassInstalledForViewer(
|
||||
'PhabricatorHarbormasterApplication',
|
||||
$this->getUser());
|
||||
|
||||
$cur_date = null;
|
||||
$view = array();
|
||||
foreach ($this->getHistory() as $history) {
|
||||
$epoch = $history->getEpoch();
|
||||
$new_date = phabricator_date($history->getEpoch(), $viewer);
|
||||
if ($cur_date !== $new_date) {
|
||||
$date = ucfirst(
|
||||
phabricator_relative_date($history->getEpoch(), $viewer));
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($date);
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setFlush(true)
|
||||
->addClass('diffusion-history-list');
|
||||
|
||||
$view[] = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
}
|
||||
|
||||
if ($epoch) {
|
||||
$committed = $viewer->formatShortDateTime($epoch);
|
||||
} else {
|
||||
$committed = null;
|
||||
}
|
||||
|
||||
$data = $history->getCommitData();
|
||||
$author_phid = $committer = $committer_phid = null;
|
||||
if ($data) {
|
||||
$author_phid = $data->getCommitDetail('authorPHID');
|
||||
$committer_phid = $data->getCommitDetail('committerPHID');
|
||||
$committer = $data->getCommitDetail('committer');
|
||||
}
|
||||
|
||||
if ($author_phid && isset($handles[$author_phid])) {
|
||||
$author_name = $handles[$author_phid]->renderLink();
|
||||
$author_image = $handles[$author_phid]->getImageURI();
|
||||
} else {
|
||||
$author_name = self::renderName($history->getAuthorName());
|
||||
$author_image =
|
||||
celerity_get_resource_uri('/rsrc/image/people/user0.png');
|
||||
}
|
||||
|
||||
$different_committer = false;
|
||||
if ($committer_phid) {
|
||||
$different_committer = ($committer_phid != $author_phid);
|
||||
} else if ($committer != '') {
|
||||
$different_committer = ($committer != $history->getAuthorName());
|
||||
}
|
||||
if ($different_committer) {
|
||||
if ($committer_phid && isset($handles[$committer_phid])) {
|
||||
$committer = $handles[$committer_phid]->renderLink();
|
||||
} else {
|
||||
$committer = self::renderName($committer);
|
||||
}
|
||||
$author_name = hsprintf('%s / %s', $author_name, $committer);
|
||||
}
|
||||
|
||||
// We can show details once the message and change have been imported.
|
||||
$partial_import = PhabricatorRepositoryCommit::IMPORTED_MESSAGE |
|
||||
PhabricatorRepositoryCommit::IMPORTED_CHANGE;
|
||||
|
||||
$commit = $history->getCommit();
|
||||
if ($commit && $commit->isPartiallyImported($partial_import) && $data) {
|
||||
$commit_desc = $history->getSummary();
|
||||
} else {
|
||||
$commit_desc = phutil_tag('em', array(), pht("Importing\xE2\x80\xA6"));
|
||||
}
|
||||
|
||||
$browse_button = $this->linkBrowse(
|
||||
$history->getPath(),
|
||||
array(
|
||||
'commit' => $history->getCommitIdentifier(),
|
||||
'branch' => $drequest->getBranch(),
|
||||
'type' => $history->getFileType(),
|
||||
),
|
||||
true);
|
||||
|
||||
$diff_tag = null;
|
||||
if ($show_revisions && $commit) {
|
||||
$d_id = idx($this->getRevisions(), $commit->getPHID());
|
||||
if ($d_id) {
|
||||
$diff_tag = id(new PHUITagView())
|
||||
->setName('D'.$d_id)
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setColor(PHUITagView::COLOR_BLUE)
|
||||
->setHref('/D'.$d_id)
|
||||
->addClass('diffusion-differential-tag')
|
||||
->setSlimShady(true);
|
||||
}
|
||||
}
|
||||
|
||||
$build_view = null;
|
||||
if ($show_builds) {
|
||||
$buildable = idx($buildables, $commit->getPHID());
|
||||
if ($buildable !== null) {
|
||||
$status = $buildable->getBuildableStatus();
|
||||
$icon = HarbormasterBuildable::getBuildableStatusIcon($status);
|
||||
$color = HarbormasterBuildable::getBuildableStatusColor($status);
|
||||
$name = HarbormasterBuildable::getBuildableStatusName($status);
|
||||
$build_view = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText($name)
|
||||
->setIcon($icon)
|
||||
->setColor($color)
|
||||
->setHref('/'.$buildable->getMonogram())
|
||||
->addClass('mmr')
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->addClass('diffusion-list-build-status');
|
||||
}
|
||||
}
|
||||
|
||||
$message = null;
|
||||
$commit_link = $repository->getCommitURI(
|
||||
$history->getCommitIdentifier());
|
||||
|
||||
$commit_name = $repository->formatCommitName(
|
||||
$history->getCommitIdentifier(), $local = true);
|
||||
|
||||
$committed = phabricator_datetime($commit->getEpoch(), $viewer);
|
||||
$author_name = phutil_tag(
|
||||
'strong',
|
||||
array(
|
||||
'class' => 'diffusion-history-author-name',
|
||||
),
|
||||
$author_name);
|
||||
$authored = pht('%s on %s.', $author_name, $committed);
|
||||
|
||||
$commit_tag = id(new PHUITagView())
|
||||
->setName($commit_name)
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setColor(PHUITagView::COLOR_INDIGO)
|
||||
->setSlimShady(true);
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($commit_desc)
|
||||
->setHref($commit_link)
|
||||
->setDisabled($commit->isUnreachable())
|
||||
->setDescription($message)
|
||||
->setImageURI($author_image)
|
||||
->addAttribute(array($commit_tag, ' ', $diff_tag)) // For Copy Pasta
|
||||
->addAttribute($authored)
|
||||
->setSideColumn(array(
|
||||
$build_view,
|
||||
$browse_button,
|
||||
));
|
||||
|
||||
$list->addItem($item);
|
||||
$cur_date = $new_date;
|
||||
}
|
||||
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,87 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionHistoryTableView extends DiffusionView {
|
||||
|
||||
private $history;
|
||||
private $revisions = array();
|
||||
private $handles = array();
|
||||
private $isHead;
|
||||
private $isTail;
|
||||
private $parents;
|
||||
private $filterParents;
|
||||
|
||||
public function setHistory(array $history) {
|
||||
assert_instances_of($history, 'DiffusionPathChange');
|
||||
$this->history = $history;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function loadRevisions() {
|
||||
$commit_phids = array();
|
||||
foreach ($this->history as $item) {
|
||||
if ($item->getCommit()) {
|
||||
$commit_phids[] = $item->getCommit()->getPHID();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get rid of this.
|
||||
$this->revisions = id(new DifferentialRevision())
|
||||
->loadIDsByCommitPHIDs($commit_phids);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHandles(array $handles) {
|
||||
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||
$this->handles = $handles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getRequiredHandlePHIDs() {
|
||||
$phids = array();
|
||||
foreach ($this->history as $item) {
|
||||
$data = $item->getCommitData();
|
||||
if ($data) {
|
||||
if ($data->getCommitDetail('authorPHID')) {
|
||||
$phids[$data->getCommitDetail('authorPHID')] = true;
|
||||
}
|
||||
if ($data->getCommitDetail('committerPHID')) {
|
||||
$phids[$data->getCommitDetail('committerPHID')] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_keys($phids);
|
||||
}
|
||||
|
||||
public function setParents(array $parents) {
|
||||
$this->parents = $parents;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIsHead($is_head) {
|
||||
$this->isHead = $is_head;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIsTail($is_tail) {
|
||||
$this->isTail = $is_tail;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFilterParents($filter_parents) {
|
||||
$this->filterParents = $filter_parents;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFilterParents() {
|
||||
return $this->filterParents;
|
||||
}
|
||||
final class DiffusionHistoryTableView extends DiffusionHistoryView {
|
||||
|
||||
public function render() {
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
|
||||
$viewer = $this->getUser();
|
||||
|
||||
$buildables = $this->loadBuildables(mpull($this->history, 'getCommit'));
|
||||
$buildables = $this->loadBuildables(
|
||||
mpull($this->getHistory(), 'getCommit'));
|
||||
$has_any_build = false;
|
||||
|
||||
$show_revisions = PhabricatorApplication::isClassInstalledForViewer(
|
||||
|
@ -91,14 +18,14 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
$handles = $viewer->loadHandles($this->getRequiredHandlePHIDs());
|
||||
|
||||
$graph = null;
|
||||
if ($this->parents) {
|
||||
$parents = $this->parents;
|
||||
if ($this->getParents()) {
|
||||
$parents = $this->getParents();
|
||||
|
||||
// If we're filtering parents, remove relationships which point to
|
||||
// commits that are not part of the visible graph. Otherwise, we get
|
||||
// a big tree of nonsense when viewing release branches like "stable"
|
||||
// versus "master".
|
||||
if ($this->filterParents) {
|
||||
if ($this->getFilterParents()) {
|
||||
foreach ($parents as $key => $nodes) {
|
||||
foreach ($nodes as $nkey => $node) {
|
||||
if (empty($parents[$node])) {
|
||||
|
@ -109,8 +36,8 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
}
|
||||
|
||||
$graph = id(new PHUIDiffGraphView())
|
||||
->setIsHead($this->isHead)
|
||||
->setIsTail($this->isTail)
|
||||
->setIsHead($this->getIsHead())
|
||||
->setIsTail($this->getIsTail())
|
||||
->renderGraph($parents);
|
||||
}
|
||||
|
||||
|
@ -120,7 +47,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
|
||||
$rows = array();
|
||||
$ii = 0;
|
||||
foreach ($this->history as $history) {
|
||||
foreach ($this->getHistory() as $history) {
|
||||
$epoch = $history->getEpoch();
|
||||
|
||||
if ($epoch) {
|
||||
|
@ -209,7 +136,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
$build,
|
||||
$audit_view,
|
||||
($commit ?
|
||||
self::linkRevision(idx($this->revisions, $commit->getPHID())) :
|
||||
self::linkRevision(idx($this->getRevisions(), $commit->getPHID())) :
|
||||
null),
|
||||
$author,
|
||||
$summary,
|
||||
|
|
101
src/applications/diffusion/view/DiffusionHistoryView.php
Normal file
101
src/applications/diffusion/view/DiffusionHistoryView.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
abstract class DiffusionHistoryView extends DiffusionView {
|
||||
|
||||
private $history;
|
||||
private $revisions = array();
|
||||
private $handles = array();
|
||||
private $isHead;
|
||||
private $isTail;
|
||||
private $parents;
|
||||
private $filterParents;
|
||||
|
||||
public function setHistory(array $history) {
|
||||
assert_instances_of($history, 'DiffusionPathChange');
|
||||
$this->history = $history;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHistory() {
|
||||
return $this->history;
|
||||
}
|
||||
|
||||
public function loadRevisions() {
|
||||
$commit_phids = array();
|
||||
foreach ($this->history as $item) {
|
||||
if ($item->getCommit()) {
|
||||
$commit_phids[] = $item->getCommit()->getPHID();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get rid of this.
|
||||
$this->revisions = id(new DifferentialRevision())
|
||||
->loadIDsByCommitPHIDs($commit_phids);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRevisions() {
|
||||
return $this->revisions;
|
||||
}
|
||||
|
||||
public function setHandles(array $handles) {
|
||||
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||
$this->handles = $handles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = array();
|
||||
foreach ($this->history as $item) {
|
||||
$data = $item->getCommitData();
|
||||
if ($data) {
|
||||
if ($data->getCommitDetail('authorPHID')) {
|
||||
$phids[$data->getCommitDetail('authorPHID')] = true;
|
||||
}
|
||||
if ($data->getCommitDetail('committerPHID')) {
|
||||
$phids[$data->getCommitDetail('committerPHID')] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_keys($phids);
|
||||
}
|
||||
|
||||
public function setParents(array $parents) {
|
||||
$this->parents = $parents;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParents() {
|
||||
return $this->parents;
|
||||
}
|
||||
|
||||
public function setIsHead($is_head) {
|
||||
$this->isHead = $is_head;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsHead() {
|
||||
return $this->isHead;
|
||||
}
|
||||
|
||||
public function setIsTail($is_tail) {
|
||||
$this->isTail = $is_tail;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsTail() {
|
||||
return $this->isTail;
|
||||
}
|
||||
|
||||
public function setFilterParents($filter_parents) {
|
||||
$this->filterParents = $filter_parents;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFilterParents() {
|
||||
return $this->filterParents;
|
||||
}
|
||||
|
||||
public function render() {}
|
||||
|
||||
}
|
|
@ -58,7 +58,10 @@ abstract class DiffusionView extends AphrontView {
|
|||
id(new PHUIIconView())->setIcon('fa-history bluegrey'));
|
||||
}
|
||||
|
||||
final public function linkBrowse($path, array $details = array()) {
|
||||
final public function linkBrowse(
|
||||
$path,
|
||||
array $details = array(),
|
||||
$button = false) {
|
||||
require_celerity_resource('diffusion-icons-css');
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
|
@ -111,6 +114,15 @@ abstract class DiffusionView extends AphrontView {
|
|||
);
|
||||
}
|
||||
|
||||
if ($button) {
|
||||
return id(new PHUIButtonView())
|
||||
->setText(pht('Browse'))
|
||||
->setIcon('fa-code')
|
||||
->setHref($href)
|
||||
->setTag('a')
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE);
|
||||
}
|
||||
|
||||
return javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
|
@ -168,7 +180,7 @@ abstract class DiffusionView extends AphrontView {
|
|||
'sigil' => 'has-tooltip',
|
||||
'meta' => array(
|
||||
'tip' => $email->getAddress(),
|
||||
'align' => 'E',
|
||||
'align' => 'S',
|
||||
'size' => 'auto',
|
||||
),
|
||||
),
|
||||
|
@ -177,30 +189,24 @@ abstract class DiffusionView extends AphrontView {
|
|||
return hsprintf('%s', $name);
|
||||
}
|
||||
|
||||
final protected function renderBuildable(HarbormasterBuildable $buildable) {
|
||||
final protected function renderBuildable(
|
||||
HarbormasterBuildable $buildable) {
|
||||
$status = $buildable->getBuildableStatus();
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
$icon = HarbormasterBuildable::getBuildableStatusIcon($status);
|
||||
$color = HarbormasterBuildable::getBuildableStatusColor($status);
|
||||
$name = HarbormasterBuildable::getBuildableStatusName($status);
|
||||
|
||||
$icon_view = id(new PHUIIconView())
|
||||
->setIcon($icon.' '.$color);
|
||||
return id(new PHUIIconView())
|
||||
->setIcon($icon.' '.$color)
|
||||
->addSigil('has-tooltip')
|
||||
->setHref('/'.$buildable->getMonogram())
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => $name,
|
||||
));
|
||||
|
||||
$tooltip_view = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'sigil' => 'has-tooltip',
|
||||
'meta' => array('tip' => $name),
|
||||
),
|
||||
$icon_view);
|
||||
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
return phutil_tag(
|
||||
'a',
|
||||
array('href' => '/'.$buildable->getMonogram()),
|
||||
$tooltip_view);
|
||||
}
|
||||
|
||||
final protected function loadBuildables(array $commits) {
|
||||
|
|
|
@ -30,7 +30,7 @@ final class PhabricatorGuideListView extends AphrontView {
|
|||
->setText(pht('Skip'))
|
||||
->setTag('a')
|
||||
->setHref($skip_href)
|
||||
->setColor(PHUIButtonView::SIMPLE);
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE);
|
||||
$list_item->setSideColumn($skip);
|
||||
}
|
||||
$list->addItem($list_item);
|
||||
|
|
|
@ -40,6 +40,22 @@ final class ManiphestTransaction
|
|||
return parent::shouldGenerateOldValue();
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
// NOTE: Modular transactions don't currently support this, and it has
|
||||
// very few callsites, and it's publish-time rather than display-time.
|
||||
// This should probably become a supported, display-time behavior. For
|
||||
// discussion, see T12787.
|
||||
|
||||
// Hide "alice created X, a task blocking Y." from feed because it
|
||||
// will almost always appear adjacent to "alice created Y".
|
||||
$is_new = $this->getMetadataValue('blocker.new');
|
||||
if ($is_new) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::shouldHideForFeed();
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
|
||||
|
|
|
@ -17,10 +17,6 @@ final class ManiphestTaskPointsTransaction
|
|||
$object->setPoints($value);
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
if (!ManiphestTaskPoints::getIsEnabled()) {
|
||||
return true;
|
||||
|
|
|
@ -9,15 +9,6 @@ final class ManiphestTaskUnblockTransaction
|
|||
return null;
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
// Hide "alice created X, a task blocking Y." from feed because it
|
||||
// will almost always appear adjacent to "alice created Y".
|
||||
$is_new = $this->getMetadataValue('blocker.new');
|
||||
if ($is_new) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function getActionName() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
|
|
@ -85,12 +85,12 @@ final class PhabricatorNotificationSearchEngine
|
|||
$viewer = $this->requireViewer();
|
||||
|
||||
$image = id(new PHUIIconView())
|
||||
->setIcon('fa-eye-slash');
|
||||
->setIcon('fa-bell-o');
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->addSigil('workflow')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setIcon($image)
|
||||
->setText(pht('Mark All Read'));
|
||||
|
||||
|
|
|
@ -18,11 +18,6 @@ final class PhabricatorNuanceApplication extends PhabricatorApplication {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function isLaunchable() {
|
||||
// Try to hide this even more for now.
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/nuance/';
|
||||
}
|
||||
|
|
|
@ -398,13 +398,36 @@ final class PhabricatorOwnersPackageQuery
|
|||
}
|
||||
}
|
||||
|
||||
// At each strength level, drop weak packages if there are also strong
|
||||
// packages of the same strength.
|
||||
$strength_map = igroup($matches, 'strength');
|
||||
foreach ($strength_map as $strength => $package_list) {
|
||||
$any_strong = false;
|
||||
foreach ($package_list as $package_id => $package) {
|
||||
if (!$package['weak']) {
|
||||
$any_strong = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($any_strong) {
|
||||
foreach ($package_list as $package_id => $package) {
|
||||
if ($package['weak']) {
|
||||
unset($matches[$package_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$matches = isort($matches, 'strength');
|
||||
$matches = array_reverse($matches);
|
||||
|
||||
$first_id = null;
|
||||
$strongest = null;
|
||||
foreach ($matches as $package_id => $match) {
|
||||
if ($first_id === null) {
|
||||
$first_id = $package_id;
|
||||
if ($strongest === null) {
|
||||
$strongest = $match['strength'];
|
||||
}
|
||||
|
||||
if ($match['strength'] === $strongest) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -297,27 +297,54 @@ final class PhabricatorOwnersPackage
|
|||
// a more specific package.
|
||||
if ($weak) {
|
||||
foreach ($path_packages as $match => $packages) {
|
||||
|
||||
// Group packages by length.
|
||||
$length_map = array();
|
||||
foreach ($packages as $package_id => $package) {
|
||||
$length_map[$package['length']][$package_id] = $package;
|
||||
}
|
||||
|
||||
// For each path length, remove all weak packages if there are any
|
||||
// strong packages of the same length. This makes sure that if there
|
||||
// are one or more strong claims on a particular path, only those
|
||||
// claims stand.
|
||||
foreach ($length_map as $package_list) {
|
||||
$any_strong = false;
|
||||
foreach ($package_list as $package_id => $package) {
|
||||
if (!isset($weak[$package_id])) {
|
||||
$any_strong = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($any_strong) {
|
||||
foreach ($package_list as $package_id => $package) {
|
||||
if (isset($weak[$package_id])) {
|
||||
unset($packages[$package_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$packages = isort($packages, 'length');
|
||||
$packages = array_reverse($packages, true);
|
||||
|
||||
$first = null;
|
||||
$best_length = null;
|
||||
foreach ($packages as $package_id => $package) {
|
||||
// If this is the first package we've encountered, note it and
|
||||
// continue. We're iterating over the packages from longest to
|
||||
// shortest match, so this package always has the strongest claim
|
||||
// on the path.
|
||||
if ($first === null) {
|
||||
$first = $package_id;
|
||||
// If this is the first package we've encountered, note its length.
|
||||
// We're iterating over the packages from longest to shortest match,
|
||||
// so packages of this length always have the best claim on the path.
|
||||
if ($best_length === null) {
|
||||
$best_length = $package['length'];
|
||||
}
|
||||
|
||||
// If this package has the same length as the best length, its claim
|
||||
// stands.
|
||||
if ($package['length'] === $best_length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the first package we saw, its claim stands even if it
|
||||
// is a weak package.
|
||||
if ($first === $package_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is a weak package and not the first package we saw,
|
||||
// If this is a weak package and does not have the best length,
|
||||
// cede its claim to the stronger package.
|
||||
if (isset($weak[$package_id])) {
|
||||
unset($packages[$package_id]);
|
||||
|
|
|
@ -100,6 +100,95 @@ final class PhabricatorOwnersPackageTestCase extends PhabricatorTestCase {
|
|||
PhabricatorOwnersPackage::findLongestPathsPerPackage($rows, $paths));
|
||||
|
||||
|
||||
// Test cases where multiple packages own the same path, with various
|
||||
// dominion rules.
|
||||
|
||||
$main_c = 'src/applications/main/main.c';
|
||||
|
||||
$rules = array(
|
||||
// All claims strong.
|
||||
array(
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
),
|
||||
// All claims weak.
|
||||
array(
|
||||
PhabricatorOwnersPackage::DOMINION_WEAK,
|
||||
PhabricatorOwnersPackage::DOMINION_WEAK,
|
||||
PhabricatorOwnersPackage::DOMINION_WEAK,
|
||||
),
|
||||
// Mixture of strong and weak claims, strong first.
|
||||
array(
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
PhabricatorOwnersPackage::DOMINION_WEAK,
|
||||
),
|
||||
// Mixture of strong and weak claims, weak first.
|
||||
array(
|
||||
PhabricatorOwnersPackage::DOMINION_WEAK,
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
PhabricatorOwnersPackage::DOMINION_STRONG,
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($rules as $rule_idx => $rule) {
|
||||
$rows = array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'excluded' => 0,
|
||||
'dominion' => $rule[0],
|
||||
'path' => $main_c,
|
||||
),
|
||||
array(
|
||||
'id' => 2,
|
||||
'excluded' => 0,
|
||||
'dominion' => $rule[1],
|
||||
'path' => $main_c,
|
||||
),
|
||||
array(
|
||||
'id' => 3,
|
||||
'excluded' => 0,
|
||||
'dominion' => $rule[2],
|
||||
'path' => $main_c,
|
||||
),
|
||||
);
|
||||
|
||||
$paths = array(
|
||||
$main_c => $pvalue,
|
||||
);
|
||||
|
||||
// If one or more packages have strong dominion, they should own the
|
||||
// path. If not, all the packages with weak dominion should own the
|
||||
// path.
|
||||
$strong = array();
|
||||
$weak = array();
|
||||
foreach ($rule as $idx => $dominion) {
|
||||
if ($dominion == PhabricatorOwnersPackage::DOMINION_STRONG) {
|
||||
$strong[] = $idx + 1;
|
||||
} else {
|
||||
$weak[] = $idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($strong) {
|
||||
$expect = $strong;
|
||||
} else {
|
||||
$expect = $weak;
|
||||
}
|
||||
|
||||
$expect = array_fill_keys($expect, strlen($main_c));
|
||||
$actual = PhabricatorOwnersPackage::findLongestPathsPerPackage(
|
||||
$rows,
|
||||
$paths);
|
||||
|
||||
ksort($actual);
|
||||
|
||||
$this->assertEqual(
|
||||
$expect,
|
||||
$actual,
|
||||
pht('Ruleset "%s" for Identical Ownership', $rule_idx));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ final class PhabricatorPeopleProfileTasksController
|
|||
->withStatuses($open)
|
||||
->needProjectPHIDs(true)
|
||||
->setLimit(100)
|
||||
->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY)
|
||||
->execute();
|
||||
|
||||
$handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
|
||||
|
|
|
@ -98,7 +98,7 @@ final class PhameBlogSearchEngine
|
|||
->setTag('a')
|
||||
->setText('New Post')
|
||||
->setHref($this->getApplicationURI('/post/edit/?blog='.$id))
|
||||
->setColor(PHUIButtonView::SIMPLE);
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE);
|
||||
$item->setSideColumn($button);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,19 @@ final class PholioImageReplaceTransaction
|
|||
}
|
||||
|
||||
public function extractFilePHIDs($object, $value) {
|
||||
return array($value);
|
||||
$file_phids = array();
|
||||
|
||||
$editor = $this->getEditor();
|
||||
$images = $editor->getNewImages();
|
||||
foreach ($images as $image) {
|
||||
if ($image->getPHID() !== $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file_phids[] = $image->getFilePHID();
|
||||
}
|
||||
|
||||
return $file_phids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,6 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isLaunchable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
$panel_pattern = '(?:page/(?P<pageKey>[^/]+)/(?:(?P<formSaved>saved)/)?)?';
|
||||
|
||||
|
|
|
@ -17,9 +17,14 @@ final class PhabricatorUIExampleRenderController extends PhabricatorController {
|
|||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI('view/')));
|
||||
|
||||
foreach ($classes as $class => $obj) {
|
||||
$name = $obj->getName();
|
||||
$nav->addFilter($class, $name);
|
||||
$groups = mgroup($classes, 'getCategory');
|
||||
ksort($groups);
|
||||
foreach ($groups as $group => $group_classes) {
|
||||
$nav->addLabel($group);
|
||||
foreach ($group_classes as $class => $obj) {
|
||||
$name = $obj->getName();
|
||||
$nav->addFilter($class, $name);
|
||||
}
|
||||
}
|
||||
|
||||
$selected = $nav->selectFilter($id, head_key($classes));
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class JavelinReactorUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Javelin Reactor');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Lots of code');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$rows = array();
|
||||
|
||||
$examples = array(
|
||||
array(
|
||||
pht('Reactive button only generates a stream of events'),
|
||||
'ReactorButtonExample',
|
||||
'phabricator-uiexample-reactor-button',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht('Reactive checkbox generates a boolean dynamic value'),
|
||||
'ReactorCheckboxExample',
|
||||
'phabricator-uiexample-reactor-checkbox',
|
||||
array('checked' => true),
|
||||
),
|
||||
array(
|
||||
pht('Reactive focus detector generates a boolean dynamic value'),
|
||||
'ReactorFocusExample',
|
||||
'phabricator-uiexample-reactor-focus',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht('Reactive input box, with normal and calmed output'),
|
||||
'ReactorInputExample',
|
||||
'phabricator-uiexample-reactor-input',
|
||||
array('init' => 'Initial value'),
|
||||
),
|
||||
array(
|
||||
pht('Reactive mouseover detector generates a boolean dynamic value'),
|
||||
'ReactorMouseoverExample',
|
||||
'phabricator-uiexample-reactor-mouseover',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht('Reactive radio buttons generate a string dynamic value'),
|
||||
'ReactorRadioExample',
|
||||
'phabricator-uiexample-reactor-radio',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht('Reactive select box generates a string dynamic value'),
|
||||
'ReactorSelectExample',
|
||||
'phabricator-uiexample-reactor-select',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht(
|
||||
'%s makes the class of an element a string dynamic value',
|
||||
'sendclass'),
|
||||
'ReactorSendClassExample',
|
||||
'phabricator-uiexample-reactor-sendclass',
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
pht(
|
||||
'%s makes some properties of an object into dynamic values',
|
||||
'sendproperties'),
|
||||
'ReactorSendPropertiesExample',
|
||||
'phabricator-uiexample-reactor-sendproperties',
|
||||
array(),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($examples as $example) {
|
||||
list($desc, $name, $resource, $params) = $example;
|
||||
$template = new AphrontJavelinView();
|
||||
$template
|
||||
->setName($name)
|
||||
->setParameters($params)
|
||||
->setCelerityResource($resource);
|
||||
$rows[] = array($desc, $template->render());
|
||||
}
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
|
||||
$panel = new PHUIObjectBoxView();
|
||||
$panel->setHeaderText(pht('Example'));
|
||||
$panel->appendChild($table);
|
||||
|
||||
return $panel;
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class JavelinUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Javelin UI');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Here are some Javelin UI elements that you could use.');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
// toggle-class
|
||||
|
||||
$container_id = celerity_generate_unique_node_id();
|
||||
$button_red_id = celerity_generate_unique_node_id();
|
||||
$button_blue_id = celerity_generate_unique_node_id();
|
||||
|
||||
$button_red = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'button',
|
||||
'sigil' => 'jx-toggle-class',
|
||||
'href' => '#',
|
||||
'id' => $button_red_id,
|
||||
'meta' => array(
|
||||
'map' => array(
|
||||
$container_id => 'jxui-red-border',
|
||||
$button_red_id => 'jxui-active',
|
||||
),
|
||||
),
|
||||
),
|
||||
pht('Toggle Red Border'));
|
||||
|
||||
$button_blue = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'button jxui-active',
|
||||
'sigil' => 'jx-toggle-class',
|
||||
'href' => '#',
|
||||
'id' => $button_blue_id,
|
||||
'meta' => array(
|
||||
'state' => true,
|
||||
'map' => array(
|
||||
$container_id => 'jxui-blue-background',
|
||||
$button_blue_id => 'jxui-active',
|
||||
),
|
||||
),
|
||||
),
|
||||
pht('Toggle Blue Background'));
|
||||
|
||||
$div = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $container_id,
|
||||
'class' => 'jxui-example-container jxui-blue-background',
|
||||
),
|
||||
array($button_red, $button_blue));
|
||||
|
||||
return array($div);
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class JavelinViewExampleServerView extends AphrontView {
|
||||
|
||||
public function render() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'server-view',
|
||||
),
|
||||
$this->renderChildren());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class JavelinViewUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Javelin Views');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Mix and match client and server views.');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$init = $request->getStr('init');
|
||||
|
||||
$parent_server_template = new JavelinViewExampleServerView();
|
||||
|
||||
$parent_client_template = new AphrontJavelinView();
|
||||
$parent_client_template
|
||||
->setName('JavelinViewExample')
|
||||
->setCelerityResource('phabricator-uiexample-javelin-view');
|
||||
|
||||
$child_server_template = new JavelinViewExampleServerView();
|
||||
|
||||
$child_client_template = new AphrontJavelinView();
|
||||
$child_client_template
|
||||
->setName('JavelinViewExample')
|
||||
->setCelerityResource('phabricator-uiexample-javelin-view');
|
||||
|
||||
$parent_server_template->appendChild($parent_client_template);
|
||||
$parent_client_template->appendChild($child_server_template);
|
||||
$child_server_template->appendChild($child_client_template);
|
||||
$child_client_template->appendChild(pht('Hey, it worked.'));
|
||||
|
||||
$panel = new PHUIObjectBoxView();
|
||||
$panel->setHeaderText(pht('Example'));
|
||||
$panel->appendChild(
|
||||
phutil_tag_div('ml', $parent_server_template));
|
||||
|
||||
return $panel;
|
||||
}
|
||||
}
|
|
@ -3,11 +3,15 @@
|
|||
final class MacroEmojiExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Emoji Support');
|
||||
return pht('Emoji');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Shiny happy people holding hands');
|
||||
return pht('Shiny happy people holding hands.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Catalogs');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
|
|
@ -10,6 +10,10 @@ final class PHUIBadgeExample extends PhabricatorUIExample {
|
|||
return pht('Celebrate the moments of your life.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Single Use');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$badges1 = array();
|
||||
|
|
|
@ -62,11 +62,11 @@ final class PHUIBoxExample extends PhabricatorUIExample {
|
|||
);
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setIcon('fa-heart')
|
||||
->setText(pht('Such Wow'))
|
||||
->addClass(PHUI::MARGIN_SMALL_RIGHT);
|
||||
->setTag('a')
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->setIcon('fa-heart')
|
||||
->setText(pht('Such Wow'))
|
||||
->addClass(PHUI::MARGIN_SMALL_RIGHT);
|
||||
|
||||
$badge1 = id(new PHUIBadgeMiniView())
|
||||
->setIcon('fa-bug')
|
||||
|
|
|
@ -36,7 +36,7 @@ final class PHUIButtonBarExample extends PhabricatorUIExample {
|
|||
foreach ($icons as $text => $icon) {
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->setTitle($text)
|
||||
->setText($text);
|
||||
|
||||
|
@ -47,7 +47,7 @@ final class PHUIButtonBarExample extends PhabricatorUIExample {
|
|||
foreach ($icons as $text => $icon) {
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->setTitle($text)
|
||||
->setTooltip($text)
|
||||
->setIcon($icon);
|
||||
|
|
|
@ -106,18 +106,61 @@ final class PHUIButtonExample extends PhabricatorUIExample {
|
|||
|
||||
$column = array();
|
||||
$icons = array(
|
||||
'Comment' => 'fa-comment',
|
||||
'Give Token' => 'fa-trophy',
|
||||
'Reverse Time' => 'fa-clock-o',
|
||||
'Implode Earth' => 'fa-exclamation-triangle red',
|
||||
array(
|
||||
'text' => pht('Comment'),
|
||||
'icon' => 'fa-comment',
|
||||
),
|
||||
array(
|
||||
'text' => pht('Give Token'),
|
||||
'icon' => 'fa-trophy',
|
||||
),
|
||||
array(
|
||||
'text' => pht('Reverse Time'),
|
||||
'icon' => 'fa-clock-o',
|
||||
),
|
||||
array(
|
||||
'text' => pht('Implode Earth'),
|
||||
'icon' => 'fa-exclamation-triangle',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-rocket',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-clipboard',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-upload',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-street-view',
|
||||
),
|
||||
array(
|
||||
'text' => pht('Copy "Quack" to Clipboard'),
|
||||
'icon' => 'fa-clipboard',
|
||||
'copy' => pht('Quack'),
|
||||
),
|
||||
);
|
||||
foreach ($icons as $text => $icon) {
|
||||
$column[] = id(new PHUIButtonView())
|
||||
foreach ($icons as $text => $spec) {
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setIcon($icon)
|
||||
->setText($text)
|
||||
->setIcon(idx($spec, 'icon'))
|
||||
->setText(idx($spec, 'text'))
|
||||
->addClass(PHUI::MARGIN_SMALL_RIGHT);
|
||||
|
||||
$copy = idx($spec, 'copy');
|
||||
if ($copy !== null) {
|
||||
Javelin::initBehavior('phabricator-clipboard-copy');
|
||||
|
||||
$button->addClass('clipboard-copy');
|
||||
$button->addSigil('clipboard-copy');
|
||||
$button->setMetadata(
|
||||
array(
|
||||
'text' => $copy,
|
||||
));
|
||||
}
|
||||
|
||||
$column[] = $button;
|
||||
}
|
||||
|
||||
$layout3 = id(new AphrontMultiColumnView())
|
||||
|
@ -129,18 +172,22 @@ final class PHUIButtonExample extends PhabricatorUIExample {
|
|||
'Subscribe' => 'fa-check-circle bluegrey',
|
||||
'Edit' => 'fa-pencil bluegrey',
|
||||
);
|
||||
$colors = array(
|
||||
PHUIButtonView::SIMPLE,
|
||||
$designs = array(
|
||||
PHUIButtonView::BUTTONTYPE_SIMPLE,
|
||||
);
|
||||
$colors = array('', 'red', 'green', 'yellow');
|
||||
$column = array();
|
||||
foreach ($colors as $color) {
|
||||
foreach ($icons as $text => $icon) {
|
||||
$column[] = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor($color)
|
||||
->setIcon($icon)
|
||||
->setText($text)
|
||||
->addClass(PHUI::MARGIN_SMALL_RIGHT);
|
||||
foreach ($designs as $design) {
|
||||
foreach ($colors as $color) {
|
||||
foreach ($icons as $text => $icon) {
|
||||
$column[] = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setButtonType($design)
|
||||
->setColor($color)
|
||||
->setIcon($icon)
|
||||
->setText($text)
|
||||
->addClass(PHUI::MARGIN_SMALL_RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ final class PHUIColorPalletteExample extends PhabricatorUIExample {
|
|||
return pht('A Standard Palette of Colors for use.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Catalogs');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$colors = array(
|
||||
|
|
|
@ -8,7 +8,11 @@ final class PHUIFeedStoryExample extends PhabricatorUIExample {
|
|||
|
||||
public function getDescription() {
|
||||
return pht(
|
||||
'An outlandish exaggeration of intricate tales from around the realm');
|
||||
'An outlandish exaggeration of intricate tales from around the realm.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Single Use');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
|
|
@ -12,6 +12,10 @@ final class PHUIHovercardUIExample extends PhabricatorUIExample {
|
|||
phutil_tag('tt', array(), 'PHUIHovercardView'));
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Single Use');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
|
|
@ -10,6 +10,10 @@ final class PHUIIconExample extends PhabricatorUIExample {
|
|||
return pht('Easily render icons or images with links and sprites.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Catalogs');
|
||||
}
|
||||
|
||||
private function listTransforms() {
|
||||
return array(
|
||||
'ph-rotate-90',
|
||||
|
|
139
src/applications/uiexample/examples/PHUIXComponentsExample.php
Normal file
139
src/applications/uiexample/examples/PHUIXComponentsExample.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
final class PHUIXComponentsExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('PHUIX Components');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Copy/paste to make design maintenance twice as difficult.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('PHUIX');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$content = array();
|
||||
|
||||
$icons = array(
|
||||
array(
|
||||
'icon' => 'fa-rocket',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-cloud',
|
||||
'color' => 'indigo',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($icons as $spec) {
|
||||
$icon = new PHUIIconView();
|
||||
|
||||
$icon->setIcon(idx($spec, 'icon'), idx($spec, 'color'));
|
||||
|
||||
$client_id = celerity_generate_unique_node_id();
|
||||
|
||||
$server_view = $icon;
|
||||
$client_view = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $client_id,
|
||||
));
|
||||
|
||||
Javelin::initBehavior(
|
||||
'phuix-example',
|
||||
array(
|
||||
'type' => 'icon',
|
||||
'id' => $client_id,
|
||||
'spec' => $spec,
|
||||
));
|
||||
|
||||
$content[] = id(new AphrontMultiColumnView())
|
||||
->addColumn($server_view)
|
||||
->addColumn($client_view);
|
||||
}
|
||||
|
||||
|
||||
$buttons = array(
|
||||
array(
|
||||
'text' => pht('Submit'),
|
||||
),
|
||||
array(
|
||||
'text' => pht('Activate'),
|
||||
'icon' => 'fa-rocket',
|
||||
),
|
||||
array(
|
||||
'type' => PHUIButtonView::BUTTONTYPE_SIMPLE,
|
||||
'text' => pht('3 / 5 Comments'),
|
||||
'icon' => 'fa-comment',
|
||||
),
|
||||
array(
|
||||
'color' => PHUIButtonView::GREEN,
|
||||
'text' => pht('Environmental!'),
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-cog',
|
||||
),
|
||||
array(
|
||||
'icon' => 'fa-cog',
|
||||
'type' => PHUIButtonView::BUTTONTYPE_SIMPLE,
|
||||
),
|
||||
array(
|
||||
'text' => array('2 + 2', ' ', '=', ' ', '4'),
|
||||
),
|
||||
array(
|
||||
'color' => PHUIButtonView::GREY,
|
||||
'text' => pht('Cancel'),
|
||||
),
|
||||
array(
|
||||
'text' => array('<strong />'),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($buttons as $spec) {
|
||||
$button = new PHUIButtonView();
|
||||
|
||||
if (idx($spec, 'text') !== null) {
|
||||
$button->setText($spec['text']);
|
||||
}
|
||||
|
||||
if (idx($spec, 'icon') !== null) {
|
||||
$button->setIcon($spec['icon']);
|
||||
}
|
||||
|
||||
if (idx($spec, 'type') !== null) {
|
||||
$button->setButtonType($spec['type']);
|
||||
}
|
||||
|
||||
if (idx($spec, 'color') !== null) {
|
||||
$button->setColor($spec['color']);
|
||||
}
|
||||
|
||||
$client_id = celerity_generate_unique_node_id();
|
||||
|
||||
$server_view = $button;
|
||||
$client_view = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $client_id,
|
||||
));
|
||||
|
||||
Javelin::initBehavior(
|
||||
'phuix-example',
|
||||
array(
|
||||
'type' => 'button',
|
||||
'id' => $client_id,
|
||||
'spec' => $spec,
|
||||
));
|
||||
|
||||
$content[] = id(new AphrontMultiColumnView())
|
||||
->addColumn($server_view)
|
||||
->addColumn($client_view);
|
||||
}
|
||||
|
||||
return id(new PHUIBoxView())
|
||||
->appendChild($content)
|
||||
->addMargin(PHUI::MARGIN_LARGE);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBarePageUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Bare Page');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('This is a bare page.');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$view = new PhabricatorBarePageView();
|
||||
$view->appendChild(
|
||||
phutil_tag(
|
||||
'h1',
|
||||
array(),
|
||||
$this->getDescription()));
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($view->render());
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBusyUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Busy');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Busy.');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
Javelin::initBehavior('phabricator-busy-example');
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -3,13 +3,17 @@
|
|||
final class PhabricatorFilesComposeAvatarExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Generate Avatar Images');
|
||||
return pht('Avatars');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Tests various color palettes and sizes.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Technical');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorGestureUIExample extends PhabricatorUIExample {
|
|||
phutil_tag('tt', array(), 'touchable'));
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Technical');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$id = celerity_generate_unique_node_id();
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorListFilterUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('ListFilter');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht(
|
||||
'Use %s to layout controls for filtering '.
|
||||
'and manipulating lists of objects.',
|
||||
phutil_tag('tt', array(), 'AphrontListFilterView'));
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$filter = new AphrontListFilterView();
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form->setUser($this->getRequest()->getUser());
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Query')))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Search')));
|
||||
|
||||
$filter->appendChild($form);
|
||||
|
||||
|
||||
return $filter;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,10 @@ final class PhabricatorNotificationUIExample extends PhabricatorUIExample {
|
|||
phutil_tag('tt', array(), 'JX.Notification'));
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Technical');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
require_celerity_resource('phabricator-notification-css');
|
||||
Javelin::initBehavior('phabricator-notification-example');
|
||||
|
|
|
@ -11,6 +11,10 @@ final class PhabricatorRemarkupUIExample extends PhabricatorUIExample {
|
|||
'Demonstrates the visual appearance of various Remarkup elements.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Technical');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ final class PhabricatorSetupIssueUIExample extends PhabricatorUIExample {
|
|||
return pht('Setup errors and warnings.');
|
||||
}
|
||||
|
||||
public function getCategory() {
|
||||
return pht('Single Use');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSortTableUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Sortable Tables');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Using sortable tables.');
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$rows = array(
|
||||
array(
|
||||
'make' => 'Honda',
|
||||
'model' => 'Civic',
|
||||
'year' => 2004,
|
||||
'price' => 3199,
|
||||
'color' => pht('Blue'),
|
||||
),
|
||||
array(
|
||||
'make' => 'Ford',
|
||||
'model' => 'Focus',
|
||||
'year' => 2001,
|
||||
'price' => 2549,
|
||||
'color' => pht('Red'),
|
||||
),
|
||||
array(
|
||||
'make' => 'Toyota',
|
||||
'model' => 'Camry',
|
||||
'year' => 2009,
|
||||
'price' => 4299,
|
||||
'color' => pht('Black'),
|
||||
),
|
||||
array(
|
||||
'make' => 'NASA',
|
||||
'model' => 'Shuttle',
|
||||
'year' => 1998,
|
||||
'price' => 1000000000,
|
||||
'color' => pht('White'),
|
||||
),
|
||||
);
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$orders = array(
|
||||
'make',
|
||||
'model',
|
||||
'year',
|
||||
'price',
|
||||
);
|
||||
|
||||
$sort = $request->getStr('sort');
|
||||
list($sort, $reverse) = AphrontTableView::parseSort($sort);
|
||||
if (!in_array($sort, $orders)) {
|
||||
$sort = 'make';
|
||||
}
|
||||
|
||||
$rows = isort($rows, $sort);
|
||||
if ($reverse) {
|
||||
$rows = array_reverse($rows);
|
||||
}
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
pht('Make'),
|
||||
pht('Model'),
|
||||
pht('Year'),
|
||||
pht('Price'),
|
||||
pht('Color'),
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'',
|
||||
'wide',
|
||||
'n',
|
||||
'n',
|
||||
'',
|
||||
));
|
||||
$table->makeSortable(
|
||||
$request->getRequestURI(),
|
||||
'sort',
|
||||
$sort,
|
||||
$reverse,
|
||||
$orders);
|
||||
|
||||
$panel = new PHUIObjectBoxView();
|
||||
$panel->setHeaderText(pht('Sortable Table of Vehicles'));
|
||||
$panel->setTable($table);
|
||||
|
||||
return $panel;
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorTooltipUIExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return pht('Tooltips');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht(
|
||||
'Use %s to create tooltips.',
|
||||
phutil_tag('tt', array(), 'JX.Tooltip'));
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
require_celerity_resource('aphront-tooltip-css');
|
||||
|
||||
$style = 'width: 200px; '.
|
||||
'text-align: center; '.
|
||||
'margin: 20px; '.
|
||||
'background: #dfdfdf; '.
|
||||
'padding: 20px 10px; '.
|
||||
'border: 1px solid black; ';
|
||||
|
||||
$lorem = <<<EOTEXT
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
EOTEXT;
|
||||
|
||||
$overflow = str_repeat('M', 1024);
|
||||
|
||||
$metas = array(
|
||||
'hi' => array(
|
||||
'tip' => 'Hi',
|
||||
),
|
||||
'lorem (north)' => array(
|
||||
'tip' => $lorem,
|
||||
),
|
||||
'lorem (east)' => array(
|
||||
'tip' => $lorem,
|
||||
'align' => 'E',
|
||||
),
|
||||
'lorem (south)' => array(
|
||||
'tip' => $lorem,
|
||||
'align' => 'S',
|
||||
),
|
||||
'lorem (west)' => array(
|
||||
'tip' => $lorem,
|
||||
'align' => 'W',
|
||||
),
|
||||
'lorem (large, north)' => array(
|
||||
'tip' => $lorem,
|
||||
'size' => 300,
|
||||
),
|
||||
'lorem (large, east)' => array(
|
||||
'tip' => $lorem,
|
||||
'size' => 300,
|
||||
'align' => 'E',
|
||||
),
|
||||
'lorem (large, west)' => array(
|
||||
'tip' => $lorem,
|
||||
'size' => 300,
|
||||
'align' => 'W',
|
||||
),
|
||||
'lorem (large, south)' => array(
|
||||
'tip' => $lorem,
|
||||
'size' => 300,
|
||||
'align' => 'S',
|
||||
),
|
||||
'overflow (north)' => array(
|
||||
'tip' => $overflow,
|
||||
),
|
||||
'overflow (east)' => array(
|
||||
'tip' => $overflow,
|
||||
'align' => 'E',
|
||||
),
|
||||
'overflow (south)' => array(
|
||||
'tip' => $overflow,
|
||||
'align' => 'S',
|
||||
),
|
||||
'overflow (west)' => array(
|
||||
'tip' => $overflow,
|
||||
'align' => 'W',
|
||||
),
|
||||
);
|
||||
|
||||
$content = array();
|
||||
foreach ($metas as $key => $meta) {
|
||||
$content[] = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'sigil' => 'has-tooltip',
|
||||
'meta' => $meta,
|
||||
'style' => $style,
|
||||
),
|
||||
$key);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,10 @@ abstract class PhabricatorUIExample extends Phobject {
|
|||
abstract public function getDescription();
|
||||
abstract public function renderExample();
|
||||
|
||||
public function getCategory() {
|
||||
return pht('General');
|
||||
}
|
||||
|
||||
protected function createBasicDummyHandle($name, $type, $fullname = null,
|
||||
$uri = null) {
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ final class AphrontFormPolicyControl extends AphrontFormControl {
|
|||
javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'grey button dropdown has-icon policy-control',
|
||||
'class' => 'grey button dropdown has-icon has-text policy-control',
|
||||
'href' => '#',
|
||||
'mustcapture' => true,
|
||||
'sigil' => 'policy-control',
|
||||
|
|
|
@ -29,7 +29,7 @@ final class PHUIButtonBarView extends AphrontTagView {
|
|||
}
|
||||
|
||||
protected function getTagContent() {
|
||||
require_celerity_resource('phui-button-css');
|
||||
require_celerity_resource('phui-button-bar-css');
|
||||
|
||||
$i = 1;
|
||||
$j = count($this->buttons);
|
||||
|
|
|
@ -5,11 +5,13 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
const GREEN = 'green';
|
||||
const GREY = 'grey';
|
||||
const DISABLED = 'disabled';
|
||||
const SIMPLE = 'simple';
|
||||
|
||||
const SMALL = 'small';
|
||||
const BIG = 'big';
|
||||
|
||||
const BUTTONTYPE_DEFAULT = 'buttontype.default';
|
||||
const BUTTONTYPE_SIMPLE = 'buttontype.simple';
|
||||
|
||||
private $size;
|
||||
private $text;
|
||||
private $subtext;
|
||||
|
@ -25,6 +27,7 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
private $tooltip;
|
||||
private $noCSS;
|
||||
private $hasCaret;
|
||||
private $buttonType = self::BUTTONTYPE_DEFAULT;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
|
@ -103,6 +106,15 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
return $this->hasCaret;
|
||||
}
|
||||
|
||||
public function setButtonType($button_type) {
|
||||
$this->buttonType = $button_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getButtonType() {
|
||||
return $this->buttonType;
|
||||
}
|
||||
|
||||
public function setIcon($icon, $first = true) {
|
||||
if (!($icon instanceof PHUIIconView)) {
|
||||
$icon = id(new PHUIIconView())
|
||||
|
@ -141,6 +153,7 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
protected function getTagAttributes() {
|
||||
|
||||
require_celerity_resource('phui-button-css');
|
||||
require_celerity_resource('phui-button-simple-css');
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'button';
|
||||
|
@ -161,6 +174,10 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
$classes[] = 'has-icon';
|
||||
}
|
||||
|
||||
if ($this->text !== null) {
|
||||
$classes[] = 'has-text';
|
||||
}
|
||||
|
||||
if ($this->iconFirst == false) {
|
||||
$classes[] = 'icon-last';
|
||||
}
|
||||
|
@ -169,6 +186,15 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
$classes[] = 'disabled';
|
||||
}
|
||||
|
||||
switch ($this->getButtonType()) {
|
||||
case self::BUTTONTYPE_DEFAULT:
|
||||
// Nothing special for default buttons.
|
||||
break;
|
||||
case self::BUTTONTYPE_SIMPLE:
|
||||
$classes[] = 'simple';
|
||||
break;
|
||||
}
|
||||
|
||||
$sigil = null;
|
||||
$meta = null;
|
||||
if ($this->tooltip) {
|
||||
|
@ -204,10 +230,24 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
$subtext = null;
|
||||
if ($this->subtext) {
|
||||
$subtext = phutil_tag(
|
||||
'div', array('class' => 'phui-button-subtext'), $this->subtext);
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-button-subtext',
|
||||
),
|
||||
$this->subtext);
|
||||
}
|
||||
|
||||
if ($this->text !== null) {
|
||||
$text = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-button-text',
|
||||
),
|
||||
array(
|
||||
$text,
|
||||
$subtext,
|
||||
));
|
||||
}
|
||||
$text = phutil_tag(
|
||||
'div', array('class' => 'phui-button-text'), array($text, $subtext));
|
||||
}
|
||||
|
||||
$caret = null;
|
||||
|
|
|
@ -79,7 +79,7 @@ final class PHUIDocumentViewPro extends AphrontTagView {
|
|||
$toc[] = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-align-left')
|
||||
->setColor(PHUIButtonView::SIMPLE)
|
||||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->addClass('phui-document-toc')
|
||||
->addSigil('jx-toggle-class')
|
||||
->setMetaData(array(
|
||||
|
|
|
@ -181,4 +181,5 @@ a.jx-tokenizer-token-invalid:hover {
|
|||
.button.tokenizer-browse-button .phui-icon-view {
|
||||
top: 7px;
|
||||
left: 9px;
|
||||
position: absolute;
|
||||
}
|
||||
|
|
|
@ -247,6 +247,7 @@ a.phabricator-core-user-menu .caret:before {
|
|||
font-size: 15px;
|
||||
top: 4px;
|
||||
left: 8px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search-dropdown .caret {
|
||||
|
|
|
@ -409,36 +409,7 @@ tr.differential-inline-loading {
|
|||
color: {$greytext};
|
||||
}
|
||||
|
||||
.scroll-objective-list {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 24px;
|
||||
top: 48px;
|
||||
bottom: 48px;
|
||||
background: rgba(255, 255, 255, 0.50);
|
||||
border-style: solid;
|
||||
border-color: rgba(255, 255, 255, 0.95);
|
||||
border-width: 1px 0 1px 1px;
|
||||
box-shadow: -1px 0 2px rgba(255, 255, 255, 0.10);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scroll-objective-list.has-aesthetic-scrollbar {
|
||||
/* For now, hide this element on systems with aesthetic scrollbars. */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scroll-objective {
|
||||
display: block;
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
text-align: middle;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
.scroll-objective .phui-icon-view {
|
||||
text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.25);
|
||||
display: block;
|
||||
height: 14px;
|
||||
.diff-banner-has-unsaved,
|
||||
.diff-banner-has-unsubmitted {
|
||||
background: {$sh-yellowbackground};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
.diffusion-history-list .phui-oi-link {
|
||||
color: {$darkbluetext};
|
||||
color: #000;
|
||||
font-size: {$biggerfontsize};
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,10 @@
|
|||
border-color: transparent;
|
||||
}
|
||||
|
||||
.diffusion-history-list .phui-oi-attribute .phui-tag-indigo a {
|
||||
color: {$indigo};
|
||||
}
|
||||
|
||||
.diffusion-history-message {
|
||||
background-color: {$bluebackground};
|
||||
padding: 16px;
|
||||
|
@ -18,3 +22,21 @@
|
|||
border-radius: 5px;
|
||||
color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.diffusion-history-list .phui-oi-attribute {
|
||||
font-size: {$smallerfontsize};
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.diffusion-history-author-name a {
|
||||
color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.diffusion-history-list .diffusion-differential-tag {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
a.phui-tag-view:hover.diffusion-differential-tag .phui-tag-core {
|
||||
border-color: transparent;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
@ -173,3 +173,16 @@ hr {
|
|||
height: 2px;
|
||||
background: {$sky};
|
||||
}
|
||||
|
||||
.clipboard-copy {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.supports-clipboard .clipboard-copy {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.clipboard-buffer {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
|
|
|
@ -97,10 +97,6 @@ div.phui-calendar-day-event {
|
|||
z-index: 6;
|
||||
}
|
||||
|
||||
.scroll-objective-list {
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.conpherence-durable-column {
|
||||
z-index: 7;
|
||||
}
|
||||
|
|
61
webroot/rsrc/css/phui/button/phui-button-bar.css
Normal file
61
webroot/rsrc/css/phui/button/phui-button-bar.css
Normal file
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @provides phui-button-bar-css
|
||||
* @requires phui-button-css
|
||||
* @requires phui-button-simple-css
|
||||
*/
|
||||
|
||||
.phui-button-bar-borderless .button {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button .phui-icon-view {
|
||||
font-size: 15px;
|
||||
color: rgba({$alphagrey},.4);
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button:hover {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button:hover .phui-icon-view {
|
||||
color: rgba({$alphagrey},.9);
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-first {
|
||||
border-top-right-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-middle {
|
||||
border-radius: 0;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-last {
|
||||
border-left: none;
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.phui-button-bar .button.simple:hover {
|
||||
border-color: {$lightblueborder};
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
color: {$sky};
|
||||
}
|
||||
|
||||
.phui-button-bar .button.simple:hover .phui-icon-view {
|
||||
border-color: {$lightblueborder};
|
||||
color: {$sky};
|
||||
background-image: none;
|
||||
}
|
131
webroot/rsrc/css/phui/button/phui-button-simple.css
Normal file
131
webroot/rsrc/css/phui/button/phui-button-simple.css
Normal file
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* @provides phui-button-simple-css
|
||||
* @requires phui-button-css
|
||||
*/
|
||||
|
||||
|
||||
/* - Basic -------------------------------------------------------------------*/
|
||||
|
||||
button.simple,
|
||||
input[type="submit"].simple,
|
||||
a.simple,
|
||||
a.simple:visited {
|
||||
background: #fff;
|
||||
color: {$bluetext};
|
||||
border: 1px solid {$lightblueborder};
|
||||
}
|
||||
|
||||
button.simple .phui-icon-view,
|
||||
input[type="submit"].simple .phui-icon-view,
|
||||
a.simple .phui-icon-view,
|
||||
a.simple:visited .phui-icon-view {
|
||||
color: {$lightbluetext};
|
||||
}
|
||||
|
||||
a.button.simple:hover,
|
||||
button.simple:hover {
|
||||
border-color: {$blueborder};
|
||||
background-image: none;
|
||||
background-color: #fff;
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
a.simple.current {
|
||||
background: {$lightblue};
|
||||
}
|
||||
|
||||
|
||||
/* - Red --------------------------------------------------------------------*/
|
||||
|
||||
button.simple.red,
|
||||
input[type="submit"].simple.red,
|
||||
a.simple.red,
|
||||
a.simple.red:visited {
|
||||
background: {$sh-redbackground};
|
||||
color: {$redtext};
|
||||
border: 1px solid {$sh-redborder};
|
||||
}
|
||||
|
||||
button.simple.red .phui-icon-view,
|
||||
input[type="submit"].simple.red .phui-icon-view,
|
||||
a.simple.red .phui-icon-view,
|
||||
a.simple.red:visited .phui-icon-view {
|
||||
color: {$redtext};
|
||||
}
|
||||
|
||||
a.button.simple.red:hover,
|
||||
button.simple.red:hover {
|
||||
border-color: {$sh-redtext};
|
||||
background-image: none;
|
||||
background-color: {$sh-redbackground};
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
/* - Green ------------------------------------------------------------------*/
|
||||
|
||||
button.simple.green,
|
||||
input[type="submit"].simple.green,
|
||||
a.simple.green,
|
||||
a.simple.green:visited {
|
||||
background: {$sh-greenbackground};
|
||||
color: {$greentext};
|
||||
border: 1px solid {$sh-greenborder};
|
||||
}
|
||||
|
||||
button.simple.green .phui-icon-view,
|
||||
input[type="submit"].simple.green .phui-icon-view,
|
||||
a.simple.green .phui-icon-view,
|
||||
a.simple.green:visited .phui-icon-view {
|
||||
color: {$greentext};
|
||||
}
|
||||
|
||||
a.button.simple.green:hover,
|
||||
button.simple.green:hover {
|
||||
border-color: {$sh-greentext};
|
||||
background-image: none;
|
||||
background-color: {$sh-greenbackground};
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
/* - Yellow -----------------------------------------------------------------*/
|
||||
|
||||
button.simple.yellow,
|
||||
input[type="submit"].simple.yellow,
|
||||
a.simple.yellow,
|
||||
a.simple.yellow:visited {
|
||||
background-color: {$sh-yellowbackground};
|
||||
color: {$sh-yellowtext};
|
||||
border: 1px solid {$sh-yellowborder};
|
||||
}
|
||||
|
||||
button.simple.yellow .phui-icon-view,
|
||||
input[type="submit"].simple.yellow .phui-icon-view,
|
||||
a.simple.yellow .phui-icon-view,
|
||||
a.simple.yellow:visited .phui-icon-view {
|
||||
color: {$sh-yellowicon};
|
||||
}
|
||||
|
||||
a.button.simple.yellow:hover,
|
||||
button.simple.yellow:hover {
|
||||
border-color: {$sh-yellowtext};
|
||||
background-image: none;
|
||||
background-color: {$sh-yellowbackground};
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
|
||||
/* - Misc -------------------------------------------------------------------*/
|
||||
|
||||
a.button.simple .phui-icon-view {
|
||||
border: none;
|
||||
}
|
||||
|
||||
a.button.simple.phuix-dropdown-open {
|
||||
background-color: #fff;
|
||||
color: {$blue};
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
a.button.simple.phuix-dropdown-open:hover .phui-icon-view {
|
||||
color: {$blue};
|
||||
}
|
|
@ -41,7 +41,7 @@ input[type="submit"] {
|
|||
font-weight: bold;
|
||||
font-size: {$normalfontsize};
|
||||
display: inline-block;
|
||||
padding: 4px 16px 5px;
|
||||
padding: 4px 14px 5px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border-radius: 3px;
|
||||
|
@ -69,8 +69,8 @@ a.icon:visited {
|
|||
}
|
||||
|
||||
button.green,
|
||||
a.green,
|
||||
a.green:visited {
|
||||
a.green.button,
|
||||
a.green.button:visited {
|
||||
background-color: {$green};
|
||||
border-color: {$green};
|
||||
background-image: linear-gradient(to bottom, #23BB5B, #139543);
|
||||
|
@ -86,26 +86,6 @@ a.grey:visited {
|
|||
color: {$darkgreytext};
|
||||
}
|
||||
|
||||
button.simple,
|
||||
input[type="submit"].simple,
|
||||
a.simple,
|
||||
a.simple:visited {
|
||||
background: #fff;
|
||||
color: {$bluetext};
|
||||
border: 1px solid {$lightblueborder};
|
||||
}
|
||||
|
||||
a.simple.current {
|
||||
background: {$lightblue};
|
||||
}
|
||||
|
||||
button.simple .phui-icon-view,
|
||||
input[type="submit"].simple .phui-icon-view,
|
||||
a.simple .phui-icon-view,
|
||||
a.simple:visited .phui-icon-view {
|
||||
color: {$lightbluetext};
|
||||
}
|
||||
|
||||
a.disabled,
|
||||
button.disabled,
|
||||
button[disabled] {
|
||||
|
@ -143,34 +123,6 @@ button.green:hover {
|
|||
transition: 0.1s;
|
||||
}
|
||||
|
||||
a.button.simple:hover,
|
||||
button.simple:hover {
|
||||
background-color: {$lightblue};
|
||||
background-image: linear-gradient(to bottom, {$blue}, {$blue});
|
||||
color: #fff;
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
a.button.simple:hover .phui-icon-view,
|
||||
button.simple:hover .phui-icon-view {
|
||||
color: #fff;
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
||||
a.button.simple .phui-icon-view {
|
||||
border: none;
|
||||
}
|
||||
|
||||
a.button.simple.phuix-dropdown-open {
|
||||
background-color: #fff;
|
||||
color: {$blue};
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
a.button.simple.phuix-dropdown-open:hover .phui-icon-view {
|
||||
color: {$blue};
|
||||
}
|
||||
|
||||
body a.button.disabled:hover,
|
||||
body button.disabled:hover,
|
||||
body a.button.disabled:active,
|
||||
|
@ -301,7 +253,7 @@ a.policy-control .phui-button-text {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.button .phui-icon-view {
|
||||
.button.has-text .phui-icon-view {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
|
@ -313,10 +265,6 @@ a.policy-control .phui-button-text {
|
|||
right: 10px;
|
||||
}
|
||||
|
||||
.phui-button-bar .button .phui-icon-view {
|
||||
left: 14px;
|
||||
}
|
||||
|
||||
.button.has-icon .phui-button-text {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
@ -345,66 +293,3 @@ a.policy-control .phui-button-text {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* PHUI Button Bar */
|
||||
|
||||
.phui-button-bar-borderless .button {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button .phui-icon-view {
|
||||
font-size: 15px;
|
||||
color: rgba({$alphagrey},.4);
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button:hover {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button:hover .phui-icon-view {
|
||||
color: rgba({$alphagrey},.9);
|
||||
}
|
||||
|
||||
.phui-button-bar-borderless .button {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.phui-button-bar a.button.has-icon {
|
||||
display: inline-block;
|
||||
height: 18px;
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-first {
|
||||
border-top-right-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-middle {
|
||||
border-radius: 0;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.phui-button-bar .phui-button-bar-last {
|
||||
border-left: none;
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.phui-button-bar .button.simple:hover {
|
||||
border-color: {$lightblueborder};
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
color: {$sky};
|
||||
}
|
||||
|
||||
.phui-button-bar .button.simple:hover .phui-icon-view {
|
||||
border-color: {$lightblueborder};
|
||||
color: {$sky};
|
||||
background-image: none;
|
||||
}
|
|
@ -182,6 +182,10 @@ ul.phui-oi-list-view {
|
|||
vertical-align: top;
|
||||
}
|
||||
|
||||
.phui-oi-col2.phui-oi-side-column {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.device-phone .phui-oi-col1,
|
||||
.device-phone .phui-oi-col2 {
|
||||
display: block;
|
||||
|
|
|
@ -144,7 +144,7 @@ a.phui-icon-circle.hover-red:hover .phui-icon-view {
|
|||
color: {$red};
|
||||
}
|
||||
|
||||
a.phui-icon-circle .phui-icon-view.phui-icon-circle-state-icon {
|
||||
.phui-icon-circle .phui-icon-view.phui-icon-circle-state-icon {
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
|
|
|
@ -32,7 +32,6 @@ JX.install('DiffChangeset', {
|
|||
this._rightID = data.right;
|
||||
|
||||
this._displayPath = JX.$H(data.displayPath);
|
||||
this._objectiveName = data.objectiveName;
|
||||
this._icon = data.icon;
|
||||
|
||||
this._inlines = [];
|
||||
|
@ -62,8 +61,6 @@ JX.install('DiffChangeset', {
|
|||
_displayPath: null,
|
||||
|
||||
_changesetList: null,
|
||||
_objective: null,
|
||||
_objectiveName: null,
|
||||
_icon: null,
|
||||
|
||||
getLeftChangesetID: function() {
|
||||
|
@ -76,23 +73,9 @@ JX.install('DiffChangeset', {
|
|||
|
||||
setChangesetList: function(list) {
|
||||
this._changesetList = list;
|
||||
|
||||
var objectives = list.getObjectives();
|
||||
this._objective = objectives.newObjective()
|
||||
.setAnchor(this._node);
|
||||
|
||||
this._updateObjective();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_updateObjective: function() {
|
||||
this._objective
|
||||
.setIcon(this.getIcon())
|
||||
.setColor(this.getColor())
|
||||
.setTooltip(this.getObjectiveName());
|
||||
},
|
||||
|
||||
getIcon: function() {
|
||||
if (!this._visible) {
|
||||
return 'fa-file-o';
|
||||
|
@ -109,10 +92,6 @@ JX.install('DiffChangeset', {
|
|||
return 'blue';
|
||||
},
|
||||
|
||||
getObjectiveName: function() {
|
||||
return this._objectiveName;
|
||||
},
|
||||
|
||||
getChangesetList: function() {
|
||||
return this._changesetList;
|
||||
},
|
||||
|
@ -501,12 +480,17 @@ JX.install('DiffChangeset', {
|
|||
// diff with a large number of changes don't constantly have the text
|
||||
// area scrolled off the bottom of the screen until the entire diff loads.
|
||||
//
|
||||
// There are two three major cases here:
|
||||
// There are several major cases here:
|
||||
//
|
||||
// - If we're near the top of the document, never scroll.
|
||||
// - If we're near the bottom of the document, always scroll.
|
||||
// - Otherwise, scroll if the changes were above the midline of the
|
||||
// viewport.
|
||||
// - If we're near the bottom of the document, always scroll, unless
|
||||
// we have an anchor.
|
||||
// - Otherwise, scroll if the changes were above (or, at least,
|
||||
// almost entirely above) the viewport.
|
||||
//
|
||||
// We don't scroll if the changes were just near the top of the viewport
|
||||
// because this makes us scroll incorrectly when an anchored change is
|
||||
// visible. See T12779.
|
||||
|
||||
var target = this._node;
|
||||
|
||||
|
@ -529,17 +513,39 @@ JX.install('DiffChangeset', {
|
|||
|
||||
var target_pos = JX.Vector.getPos(target);
|
||||
var target_dim = JX.Vector.getDim(target);
|
||||
var target_mid = (target_pos.y + (target_dim.y / 2));
|
||||
var target_bot = (target_pos.y + target_dim.y);
|
||||
|
||||
var view_mid = (old_pos.y + (old_view.y / 2));
|
||||
var above_mid = (target_mid < view_mid);
|
||||
// Detect if the changeset is entirely (or, at least, almost entirely)
|
||||
// above us. The height here is roughly the height of the persistent
|
||||
// banner.
|
||||
var above_screen = (target_bot < old_pos.y + 64);
|
||||
|
||||
// If we have a URL anchor and are currently nearby, stick to it
|
||||
// no matter what.
|
||||
var on_target = null;
|
||||
if (window.location.hash) {
|
||||
try {
|
||||
var anchor = JX.$(window.location.hash.replace('#', ''));
|
||||
if (anchor) {
|
||||
var anchor_pos = JX.$V(anchor);
|
||||
if ((anchor_pos.y > old_pos.y) &&
|
||||
(anchor_pos.y < old_pos.y + 96)) {
|
||||
on_target = anchor;
|
||||
}
|
||||
}
|
||||
} catch (ignored) {
|
||||
// If we have a bogus anchor, just ignore it.
|
||||
}
|
||||
}
|
||||
|
||||
var frame = this._getContentFrame();
|
||||
JX.DOM.setContent(frame, JX.$H(response.changeset));
|
||||
|
||||
if (this._stabilize) {
|
||||
if (!near_top) {
|
||||
if (near_bot || above_mid) {
|
||||
if (on_target) {
|
||||
JX.DOM.scrollToPosition(old_pos.x, JX.$V(on_target).y - 60);
|
||||
} else if (!near_top) {
|
||||
if (near_bot || above_screen) {
|
||||
// Figure out how much taller the document got.
|
||||
var delta = (JX.Vector.getDocument().y - old_dim.y);
|
||||
JX.DOM.scrollToPosition(old_pos.x, old_pos.y + delta);
|
||||
|
@ -570,7 +576,6 @@ JX.install('DiffChangeset', {
|
|||
|
||||
JX.Stratcom.invoke('differential-inline-comment-refresh');
|
||||
|
||||
this._objective.show();
|
||||
this._rebuildAllInlines();
|
||||
|
||||
JX.Stratcom.invoke('resize');
|
||||
|
@ -695,6 +700,11 @@ JX.install('DiffChangeset', {
|
|||
return null;
|
||||
},
|
||||
|
||||
getInlines: function() {
|
||||
this._rebuildAllInlines();
|
||||
return this._inlines;
|
||||
},
|
||||
|
||||
_rebuildAllInlines: function() {
|
||||
var rows = JX.DOM.scry(this._node, 'tr');
|
||||
for (var ii = 0; ii < rows.length; ii++) {
|
||||
|
@ -723,11 +733,6 @@ JX.install('DiffChangeset', {
|
|||
JX.DOM.appendContent(diff.parentNode, undo);
|
||||
}
|
||||
|
||||
this._updateObjective();
|
||||
for (var ii = 0; ii < this._inlines.length; ii++) {
|
||||
this._inlines[ii].updateObjective();
|
||||
}
|
||||
|
||||
JX.Stratcom.invoke('resize');
|
||||
},
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/**
|
||||
* @provides phabricator-diff-changeset-list
|
||||
* @requires javelin-install
|
||||
* phabricator-scroll-objective-list
|
||||
* @javelin
|
||||
*/
|
||||
|
||||
|
@ -9,7 +8,6 @@ JX.install('DiffChangesetList', {
|
|||
|
||||
construct: function() {
|
||||
this._changesets = [];
|
||||
this._objectives = new JX.ScrollObjectiveList();
|
||||
|
||||
var onload = JX.bind(this, this._ifawake, this._onload);
|
||||
JX.Stratcom.listen('click', 'differential-load', onload);
|
||||
|
@ -70,7 +68,7 @@ JX.install('DiffChangesetList', {
|
|||
|
||||
var onrangedown = JX.bind(this, this._ifawake, this._onrangedown);
|
||||
JX.Stratcom.listen(
|
||||
['touchstart', 'mousedown'],
|
||||
'mousedown',
|
||||
['differential-changeset', 'tag:th'],
|
||||
onrangedown);
|
||||
|
||||
|
@ -80,15 +78,9 @@ JX.install('DiffChangesetList', {
|
|||
['differential-changeset', 'tag:th'],
|
||||
onrangemove);
|
||||
|
||||
var onrangetouchmove = JX.bind(this, this._ifawake, this._onrangetouchmove);
|
||||
JX.Stratcom.listen(
|
||||
'touchmove',
|
||||
null,
|
||||
onrangetouchmove);
|
||||
|
||||
var onrangeup = JX.bind(this, this._ifawake, this._onrangeup);
|
||||
JX.Stratcom.listen(
|
||||
['touchend', 'mouseup'],
|
||||
'mouseup',
|
||||
null,
|
||||
onrangeup);
|
||||
},
|
||||
|
@ -102,7 +94,6 @@ JX.install('DiffChangesetList', {
|
|||
_initialized: false,
|
||||
_asleep: true,
|
||||
_changesets: null,
|
||||
_objectives: null,
|
||||
|
||||
_cursorItem: null,
|
||||
|
||||
|
@ -120,7 +111,6 @@ JX.install('DiffChangesetList', {
|
|||
_rangeTarget: null,
|
||||
|
||||
_bannerNode: null,
|
||||
_showObjectives: false,
|
||||
|
||||
sleep: function() {
|
||||
this._asleep = true;
|
||||
|
@ -128,8 +118,6 @@ JX.install('DiffChangesetList', {
|
|||
this._redrawFocus();
|
||||
this._redrawSelection();
|
||||
this.resetHover();
|
||||
|
||||
this._objectives.hide();
|
||||
},
|
||||
|
||||
wake: function() {
|
||||
|
@ -138,10 +126,6 @@ JX.install('DiffChangesetList', {
|
|||
this._redrawFocus();
|
||||
this._redrawSelection();
|
||||
|
||||
if (this._showObjectives) {
|
||||
this._objectives.show();
|
||||
}
|
||||
|
||||
if (this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
@ -198,19 +182,10 @@ JX.install('DiffChangesetList', {
|
|||
this._installKey('q', label, this._onkeyhide);
|
||||
},
|
||||
|
||||
setShowObjectives: function(show) {
|
||||
this._showObjectives = show;
|
||||
return this;
|
||||
},
|
||||
|
||||
isAsleep: function() {
|
||||
return this._asleep;
|
||||
},
|
||||
|
||||
getObjectives: function() {
|
||||
return this._objectives;
|
||||
},
|
||||
|
||||
newChangesetForNode: function(node) {
|
||||
var changeset = JX.DiffChangeset.getForNode(node);
|
||||
|
||||
|
@ -538,24 +513,9 @@ JX.install('DiffChangesetList', {
|
|||
},
|
||||
|
||||
_setSelectionState: function(item, manager) {
|
||||
// If we had an inline selected before, we need to update it after
|
||||
// changing our selection to clear the selected state. Then, update the
|
||||
// new one to add the selected state.
|
||||
var old_inline = this.getSelectedInline();
|
||||
|
||||
this._cursorItem = item;
|
||||
this._redrawSelection(manager, true);
|
||||
|
||||
var new_inline = this.getSelectedInline();
|
||||
|
||||
if (old_inline) {
|
||||
old_inline.updateObjective();
|
||||
}
|
||||
|
||||
if (new_inline) {
|
||||
new_inline.updateObjective();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -858,6 +818,11 @@ JX.install('DiffChangesetList', {
|
|||
this._redrawSelection();
|
||||
this._redrawHover();
|
||||
|
||||
// Force a banner redraw after a resize event. Particularly, this makes
|
||||
// sure the inline state updates immediately after an inline edit
|
||||
// operation, even if the changeset itself has not changed.
|
||||
this._bannerChangeset = null;
|
||||
|
||||
this._redrawBanner();
|
||||
},
|
||||
|
||||
|
@ -1181,8 +1146,8 @@ JX.install('DiffChangesetList', {
|
|||
},
|
||||
|
||||
_onrangedown: function(e) {
|
||||
// NOTE: We're allowing touch events through, including "touchstart". We
|
||||
// need to kill the "touchstart" event so the page doesn't scroll.
|
||||
// NOTE: We're allowing "mousedown" from a touch event through so users
|
||||
// can leave inlines on a single line.
|
||||
if (e.isRightButton()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1272,31 +1237,6 @@ JX.install('DiffChangesetList', {
|
|||
this._setHoverRange(this._rangeOrigin, this._rangeTarget);
|
||||
},
|
||||
|
||||
_onrangetouchmove: function(e) {
|
||||
if (!this._rangeActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: The target of a "touchmove" event is bogus. Use dark magic to
|
||||
// identify the actual target. Some day, this might move into the core
|
||||
// libraries. If this doesn't work, just bail.
|
||||
|
||||
var target;
|
||||
try {
|
||||
var raw_event = e.getRawEvent();
|
||||
var touch = raw_event.touches[0];
|
||||
target = document.elementFromPoint(touch.clientX, touch.clientY);
|
||||
} catch (ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!JX.DOM.isType(target, 'th')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateRange(target, false);
|
||||
},
|
||||
|
||||
_onrangeup: function(e) {
|
||||
if (!this._rangeActive) {
|
||||
return;
|
||||
|
@ -1343,6 +1283,43 @@ JX.install('DiffChangesetList', {
|
|||
return;
|
||||
}
|
||||
|
||||
var changesets = this._changesets;
|
||||
var unsaved = [];
|
||||
var unsubmitted = [];
|
||||
var undone = [];
|
||||
var all = [];
|
||||
|
||||
for (var ii = 0; ii < changesets.length; ii++) {
|
||||
var inlines = changesets[ii].getInlines();
|
||||
for (var jj = 0; jj < inlines.length; jj++) {
|
||||
var inline = inlines[jj];
|
||||
|
||||
if (inline.isDeleted()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
all.push(inline);
|
||||
|
||||
if (inline.isEditing()) {
|
||||
unsaved.push(inline);
|
||||
} else if (inline.isDraft()) {
|
||||
unsubmitted.push(inline);
|
||||
} else if (!inline.isDone()) {
|
||||
undone.push(inline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JX.DOM.alterClass(
|
||||
node,
|
||||
'diff-banner-has-unsaved',
|
||||
!!unsaved.length);
|
||||
|
||||
JX.DOM.alterClass(
|
||||
node,
|
||||
'diff-banner-has-unsubmitted',
|
||||
!!unsubmitted.length);
|
||||
|
||||
var icon = new JX.PHUIXIconView()
|
||||
.setIcon(changeset.getIcon())
|
||||
.getNode();
|
||||
|
|
|
@ -29,7 +29,6 @@ JX.install('DiffInline', {
|
|||
_isLoading: false,
|
||||
|
||||
_changeset: null,
|
||||
_objective: null,
|
||||
|
||||
_isDraft: null,
|
||||
_isFixed: null,
|
||||
|
@ -38,7 +37,6 @@ JX.install('DiffInline', {
|
|||
|
||||
bindToRow: function(row) {
|
||||
this._row = row;
|
||||
this._objective.setAnchor(this._row);
|
||||
|
||||
var row_data = JX.Stratcom.getData(row);
|
||||
row_data.inline = this;
|
||||
|
@ -80,11 +78,25 @@ JX.install('DiffInline', {
|
|||
|
||||
this.setInvisible(false);
|
||||
|
||||
this.updateObjective();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
isDraft: function() {
|
||||
return this._isDraft;
|
||||
},
|
||||
|
||||
isDone: function() {
|
||||
return this._isFixed;
|
||||
},
|
||||
|
||||
isEditing: function() {
|
||||
return this._isEditing;
|
||||
},
|
||||
|
||||
isDeleted: function() {
|
||||
return this._isDeleted;
|
||||
},
|
||||
|
||||
bindToRange: function(data) {
|
||||
this._displaySide = data.displaySide;
|
||||
this._number = parseInt(data.number, 10);
|
||||
|
@ -171,14 +183,6 @@ JX.install('DiffInline', {
|
|||
|
||||
setChangeset: function(changeset) {
|
||||
this._changeset = changeset;
|
||||
|
||||
var objectives = changeset.getChangesetList().getObjectives();
|
||||
|
||||
// Create this inline's objective, but don't show it yet.
|
||||
this._objective = objectives.newObjective()
|
||||
.setCallback(JX.bind(this, this._onobjective))
|
||||
.hide();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -188,84 +192,9 @@ JX.install('DiffInline', {
|
|||
|
||||
setEditing: function(editing) {
|
||||
this._isEditing = editing;
|
||||
this.updateObjective();
|
||||
return this;
|
||||
},
|
||||
|
||||
_onobjective: function() {
|
||||
this.getChangeset().getChangesetList().selectInline(this);
|
||||
},
|
||||
|
||||
updateObjective: function() {
|
||||
var objective = this._objective;
|
||||
|
||||
if (this.isHidden() || this._isDeleted) {
|
||||
objective.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a new comment which we aren't editing, don't show anything:
|
||||
// the use started a comment or reply, then cancelled it.
|
||||
if (this._isNew && !this._isEditing) {
|
||||
objective.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var changeset = this.getChangeset();
|
||||
if (!changeset.isVisible()) {
|
||||
objective.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var pht = changeset.getChangesetList().getTranslations();
|
||||
|
||||
var icon = 'fa-comment';
|
||||
var color = 'bluegrey';
|
||||
var tooltip = this._snippet;
|
||||
var anchor = this._row;
|
||||
var should_stack = false;
|
||||
|
||||
if (this._isEditing) {
|
||||
icon = 'fa-star';
|
||||
color = 'pink';
|
||||
tooltip = pht('Editing Comment');
|
||||
|
||||
// If we're editing, anchor to the row with the editor instead of the
|
||||
// actual comment row (which is invisible and can have a misleading
|
||||
// position).
|
||||
anchor = this._row.nextSibling;
|
||||
} else if (this._isDraft) {
|
||||
// This inline is an unsubmitted draft.
|
||||
icon = 'fa-pencil';
|
||||
color = 'indigo';
|
||||
} else if (this._isFixed) {
|
||||
// This inline has been marked done.
|
||||
icon = 'fa-check';
|
||||
color = 'grey';
|
||||
} else if (this._isGhost) {
|
||||
icon = 'fa-comment-o';
|
||||
color = 'grey';
|
||||
} else if (this._replyToCommentPHID) {
|
||||
icon = 'fa-reply';
|
||||
should_stack = true;
|
||||
}
|
||||
|
||||
if (changeset.getChangesetList().getSelectedInline() === this) {
|
||||
// TODO: Maybe add some other kind of effect here, since we're only
|
||||
// using color to show this?
|
||||
color = 'yellow';
|
||||
}
|
||||
|
||||
|
||||
objective
|
||||
.setAnchor(anchor)
|
||||
.setIcon(icon)
|
||||
.setColor(color)
|
||||
.setTooltip(tooltip)
|
||||
.setShouldStack(should_stack)
|
||||
.show();
|
||||
},
|
||||
|
||||
canReply: function() {
|
||||
if (!this._hasAction('reply')) {
|
||||
return false;
|
||||
|
@ -316,7 +245,6 @@ JX.install('DiffInline', {
|
|||
|
||||
JX.Stratcom.getData(row).inline = this;
|
||||
this._row = row;
|
||||
this._objective.setAnchor(this._row);
|
||||
|
||||
this._id = null;
|
||||
this._phid = null;
|
||||
|
@ -759,8 +687,6 @@ JX.install('DiffInline', {
|
|||
this.getChangeset().getChangesetList().redrawPreview();
|
||||
}
|
||||
|
||||
this.updateObjective();
|
||||
|
||||
this.getChangeset().getChangesetList().redrawCursor();
|
||||
this.getChangeset().getChangesetList().resetHover();
|
||||
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-scroll-objective
|
||||
* @requires javelin-dom
|
||||
* javelin-util
|
||||
* javelin-stratcom
|
||||
* javelin-install
|
||||
* javelin-workflow
|
||||
* @javelin
|
||||
*/
|
||||
|
||||
|
||||
JX.install('ScrollObjective', {
|
||||
|
||||
construct : function() {
|
||||
var node = this.getNode();
|
||||
|
||||
var onclick = JX.bind(this, this._onclick);
|
||||
JX.DOM.listen(node, 'click', null, onclick);
|
||||
},
|
||||
|
||||
members: {
|
||||
_list: null,
|
||||
|
||||
_node: null,
|
||||
_anchor: null,
|
||||
|
||||
_visible: false,
|
||||
_callback: false,
|
||||
_stack: false,
|
||||
|
||||
getNode: function() {
|
||||
if (!this._node) {
|
||||
var attributes = {
|
||||
className: 'scroll-objective'
|
||||
};
|
||||
|
||||
var content = this._getIconObject().getNode();
|
||||
|
||||
var node = JX.$N('div', attributes, content);
|
||||
|
||||
this._node = node;
|
||||
}
|
||||
|
||||
return this._node;
|
||||
},
|
||||
|
||||
setCallback: function(callback) {
|
||||
this._callback = callback;
|
||||
return this;
|
||||
},
|
||||
|
||||
setObjectiveList: function(list) {
|
||||
this._list = list;
|
||||
return this;
|
||||
},
|
||||
|
||||
_getIconObject: function() {
|
||||
if (!this._iconObject) {
|
||||
this._iconObject = new JX.PHUIXIconView();
|
||||
}
|
||||
return this._iconObject;
|
||||
},
|
||||
|
||||
_onclick: function(e) {
|
||||
(this._callback && this._callback(e));
|
||||
|
||||
if (e.getPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.kill();
|
||||
|
||||
// This is magic to account for the banner, and should probably be made
|
||||
// less hard-coded.
|
||||
var buffer = 48;
|
||||
|
||||
JX.DOM.scrollToPosition(null, JX.$V(this.getAnchor()).y - buffer);
|
||||
},
|
||||
|
||||
setAnchor: function(node) {
|
||||
this._anchor = node;
|
||||
return this;
|
||||
},
|
||||
|
||||
getAnchor: function() {
|
||||
return this._anchor;
|
||||
},
|
||||
|
||||
setIcon: function(icon) {
|
||||
this._getIconObject().setIcon(icon);
|
||||
return this;
|
||||
},
|
||||
|
||||
setColor: function(color) {
|
||||
this._getIconObject().setColor(color);
|
||||
return this;
|
||||
},
|
||||
|
||||
setTooltip: function(tip) {
|
||||
var node = this._getIconObject().getNode();
|
||||
JX.Stratcom.addSigil(node, 'has-tooltip');
|
||||
JX.Stratcom.getData(node).tip = tip;
|
||||
JX.Stratcom.getData(node).align = 'W';
|
||||
JX.Stratcom.getData(node).size = 'auto';
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Should this objective always stack immediately under the previous
|
||||
* objective?
|
||||
*
|
||||
* This allows related objectives (like "comment, reply, reply") to be
|
||||
* rendered in a tight sequence.
|
||||
*/
|
||||
setShouldStack: function(stack) {
|
||||
this._stack = stack;
|
||||
return this;
|
||||
},
|
||||
|
||||
shouldStack: function() {
|
||||
return this._stack;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this._visible = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this._visible = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
isVisible: function() {
|
||||
return this._visible;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-scroll-objective-list
|
||||
* @requires javelin-dom
|
||||
* javelin-util
|
||||
* javelin-stratcom
|
||||
* javelin-install
|
||||
* javelin-workflow
|
||||
* javelin-scrollbar
|
||||
* phabricator-scroll-objective
|
||||
* @javelin
|
||||
*/
|
||||
|
||||
|
||||
JX.install('ScrollObjectiveList', {
|
||||
|
||||
construct : function() {
|
||||
this._objectives = [];
|
||||
|
||||
var onresize = JX.bind(this, this._dirty);
|
||||
JX.Stratcom.listen('resize', null, onresize);
|
||||
},
|
||||
|
||||
members: {
|
||||
_objectives: null,
|
||||
_visible: false,
|
||||
_trigger: null,
|
||||
|
||||
newObjective: function() {
|
||||
var objective = new JX.ScrollObjective()
|
||||
.setObjectiveList(this);
|
||||
|
||||
this._objectives.push(objective);
|
||||
this._getNode().appendChild(objective.getNode());
|
||||
|
||||
this._dirty();
|
||||
|
||||
return objective;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this._visible = true;
|
||||
this._dirty();
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this._visible = false;
|
||||
this._dirty();
|
||||
return this;
|
||||
},
|
||||
|
||||
_getNode: function() {
|
||||
if (!this._node) {
|
||||
var node = new JX.$N('div', {className: 'scroll-objective-list'});
|
||||
this._node = node;
|
||||
}
|
||||
return this._node;
|
||||
},
|
||||
|
||||
_dirty: function() {
|
||||
if (this._trigger !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._trigger = setTimeout(JX.bind(this, this._redraw), 0);
|
||||
},
|
||||
|
||||
_redraw: function() {
|
||||
this._trigger = null;
|
||||
|
||||
var node = this._getNode();
|
||||
|
||||
var is_visible =
|
||||
(this._visible) &&
|
||||
(JX.Device.getDevice() == 'desktop') &&
|
||||
(this._objectives.length);
|
||||
|
||||
if (!is_visible) {
|
||||
JX.DOM.remove(node);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.appendChild(node);
|
||||
|
||||
// If we're on OSX without a mouse or some other system with zero-width
|
||||
// trackpad-style scrollbars, adjust the display appropriately.
|
||||
var aesthetic = (JX.Scrollbar.getScrollbarControlWidth() === 0);
|
||||
JX.DOM.alterClass(node, 'has-aesthetic-scrollbar', aesthetic);
|
||||
|
||||
var d = JX.Vector.getDocument();
|
||||
|
||||
var list_dimensions = JX.Vector.getDim(node);
|
||||
var icon_height = 16;
|
||||
var list_y = (list_dimensions.y - icon_height);
|
||||
|
||||
var ii;
|
||||
var offset;
|
||||
|
||||
// First, build a list of all the items we're going to show.
|
||||
var items = [];
|
||||
for (ii = 0; ii < this._objectives.length; ii++) {
|
||||
var objective = this._objectives[ii];
|
||||
var objective_node = objective.getNode();
|
||||
|
||||
var anchor = objective.getAnchor();
|
||||
if (!anchor || !objective.isVisible()) {
|
||||
JX.DOM.remove(objective_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = (JX.$V(anchor).y / d.y) * (list_y);
|
||||
|
||||
items.push({
|
||||
offset: offset,
|
||||
node: objective_node,
|
||||
objective: objective
|
||||
});
|
||||
}
|
||||
|
||||
// Now, sort it from top to bottom.
|
||||
items.sort(function(u, v) {
|
||||
return u.offset - v.offset;
|
||||
});
|
||||
|
||||
// Lay out the items in the objective list, leaving a minimum amount
|
||||
// of space between them so they do not overlap.
|
||||
var min = null;
|
||||
for (ii = 0; ii < items.length; ii++) {
|
||||
var item = items[ii];
|
||||
|
||||
offset = item.offset;
|
||||
|
||||
if (min !== null) {
|
||||
if (item.objective.shouldStack()) {
|
||||
offset = min;
|
||||
} else {
|
||||
offset = Math.max(offset, min);
|
||||
}
|
||||
}
|
||||
min = offset + 15;
|
||||
|
||||
item.node.style.top = offset + 'px';
|
||||
node.appendChild(item.node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
|
@ -60,8 +60,7 @@ JX.behavior('differential-populate', function(config, statics) {
|
|||
|
||||
var changeset_list = new JX.DiffChangesetList()
|
||||
.setTranslations(JX.phtize(config.pht))
|
||||
.setInlineURI(config.inlineURI)
|
||||
.setShowObjectives(config.showObjectives);
|
||||
.setInlineURI(config.inlineURI);
|
||||
|
||||
// Install and activate the current page.
|
||||
var page_id = JX.Quicksand.getCurrentPageID();
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-javelin-view
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-view
|
||||
*/
|
||||
|
||||
JX.install('JavelinViewExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function(rendered_children) {
|
||||
return JX.$N(
|
||||
'div',
|
||||
{ className: 'client-view' },
|
||||
rendered_children
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-button
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-util
|
||||
* javelin-dynval
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorButtonExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var button = JX.$N('button', {}, 'Fun');
|
||||
var clicks = JX.RDOM.clickPulses(button);
|
||||
|
||||
var time = JX.RDOM.time();
|
||||
|
||||
// function snapshot(pulses, dynval) {
|
||||
// return new DynVal(
|
||||
// pulses.transform(JX.bind(dynval, dynval.getValueNow)),
|
||||
// dynval.getValueNow()
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// Below could be...
|
||||
// time.snapshot(clicks)
|
||||
// clicks.snapshot(time)
|
||||
|
||||
var snapshot_time = new JX.DynVal(
|
||||
clicks.transform(JX.bind(time, time.getValueNow)),
|
||||
time.getValueNow()
|
||||
);
|
||||
|
||||
return [button, JX.RDOM.$DT(snapshot_time)];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-checkbox
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorCheckboxExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var checkbox = JX.$N('input', {type: 'checkbox'});
|
||||
|
||||
return [checkbox, JX.RDOM.$DT(JX.RDOM.checkbox(checkbox))];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-focus
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorFocusExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var input = JX.$N('input');
|
||||
return [input, JX.RDOM.$DT(JX.RDOM.hasFocus(input))];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-input
|
||||
* @requires javelin-install
|
||||
* javelin-reactor-dom
|
||||
* javelin-view-html
|
||||
* javelin-view-interpreter
|
||||
* javelin-view-renderer
|
||||
*/
|
||||
|
||||
JX.install('ReactorInputExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var html = JX.HTMLView.registerToInterpreter(new JX.ViewInterpreter());
|
||||
|
||||
var raw_input = JX.ViewRenderer.render(
|
||||
html.input({ value: this.getAttr('init') })
|
||||
);
|
||||
var input = JX.RDOM.input(raw_input);
|
||||
|
||||
return JX.ViewRenderer.render(
|
||||
html.div(
|
||||
raw_input,
|
||||
html.br(),
|
||||
html.span(JX.RDOM.$DT(input)),
|
||||
html.br(),
|
||||
html.span(JX.RDOM.$DT(input.calm(500)))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-mouseover
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorMouseoverExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var target = JX.$N('span', 'mouseover me ');
|
||||
return [target, JX.RDOM.$DT(JX.RDOM.isMouseOver(target))];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,24 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-radio
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorRadioExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var radio_one = JX.$N('input', {type: 'radio', name: 'n', value: 'one'});
|
||||
var radio_two = JX.$N('input', {type: 'radio', name: 'n', value: 'two'});
|
||||
|
||||
radio_one.checked = true;
|
||||
|
||||
return [
|
||||
radio_one,
|
||||
radio_two,
|
||||
JX.RDOM.$DT(JX.RDOM.radio([radio_one, radio_two]))
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-select
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorSelectExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var select = JX.$N('select', {}, [
|
||||
JX.$N('option', { value: 'goat' }, 'Goat'),
|
||||
JX.$N('option', { value: 'bat' }, 'Bat'),
|
||||
JX.$N('option', { value: 'duck' }, 'Duck')
|
||||
]);
|
||||
|
||||
return [select, JX.RDOM.$DT(JX.RDOM.select(select))];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-sendclass
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorSendClassExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var input = JX.$N('input', { type: 'checkbox' });
|
||||
var span = JX.$N('a', 'Hey');
|
||||
JX.RDOM.sendClass(JX.RDOM.checkbox(input), span, 'disabled');
|
||||
return [input, span];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-uiexample-reactor-sendproperties
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* javelin-reactor-dom
|
||||
*/
|
||||
|
||||
JX.install('ReactorSendPropertiesExample', {
|
||||
extend: 'View',
|
||||
members: {
|
||||
render: function() {
|
||||
var color = JX.$N('input', {value: '#fff000'});
|
||||
var title = JX.$N('input', {value: 'seen on hover'});
|
||||
var target = JX.$N('span', 'Change my color and title');
|
||||
|
||||
JX.RDOM.sendProps(target, {
|
||||
style: {
|
||||
backgroundColor: JX.RDOM.input(color)
|
||||
},
|
||||
title: JX.RDOM.input(title)
|
||||
});
|
||||
|
||||
return [color, title, target];
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,9 +0,0 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phabricator-busy-example
|
||||
* @requires phabricator-busy
|
||||
* javelin-behavior
|
||||
*/
|
||||
|
||||
JX.behavior('phabricator-busy-example', function() {
|
||||
JX.Busy.start();
|
||||
});
|
43
webroot/rsrc/js/core/behavior-copy.js
Normal file
43
webroot/rsrc/js/core/behavior-copy.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phabricator-clipboard-copy
|
||||
* @requires javelin-behavior
|
||||
* javelin-dom
|
||||
* javelin-stratcom
|
||||
* @javelin
|
||||
*/
|
||||
|
||||
JX.behavior('phabricator-clipboard-copy', function() {
|
||||
|
||||
if (!document.queryCommandSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!document.queryCommandSupported('copy')) {
|
||||
return;
|
||||
}
|
||||
|
||||
JX.DOM.alterClass(document.body, 'supports-clipboard', true);
|
||||
|
||||
JX.Stratcom.listen('click', 'clipboard-copy', function(e) {
|
||||
e.kill();
|
||||
|
||||
var data = e.getNodeData('clipboard-copy');
|
||||
var attr = {
|
||||
value: data.text || '',
|
||||
className: 'clipboard-buffer'
|
||||
};
|
||||
|
||||
var node = JX.$N('textarea', attr);
|
||||
document.body.appendChild(node);
|
||||
|
||||
try {
|
||||
node.select();
|
||||
document.execCommand('copy');
|
||||
} catch (ignored) {
|
||||
// Ignore any errors we hit.
|
||||
}
|
||||
|
||||
JX.DOM.remove(node);
|
||||
});
|
||||
|
||||
});
|
110
webroot/rsrc/js/phuix/PHUIXButtonView.js
Normal file
110
webroot/rsrc/js/phuix/PHUIXButtonView.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* @provides phuix-button-view
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
*/
|
||||
JX.install('PHUIXButtonView', {
|
||||
|
||||
statics: {
|
||||
BUTTONTYPE_DEFAULT: 'buttontype.default',
|
||||
BUTTONTYPE_SIMPLE: 'buttontype.simple'
|
||||
},
|
||||
|
||||
members: {
|
||||
_node: null,
|
||||
_textNode: null,
|
||||
|
||||
_iconView: null,
|
||||
_color: null,
|
||||
_buttonType: null,
|
||||
|
||||
setIcon: function(icon) {
|
||||
this.getIconView().setIcon(icon);
|
||||
return this;
|
||||
},
|
||||
|
||||
getIconView: function() {
|
||||
if (!this._iconView) {
|
||||
this._iconView = new JX.PHUIXIconView();
|
||||
this._redraw();
|
||||
}
|
||||
return this._iconView;
|
||||
},
|
||||
|
||||
setColor: function(color) {
|
||||
var node = this.getNode();
|
||||
|
||||
if (this._color) {
|
||||
JX.DOM.alterClass(node, this._color, false);
|
||||
}
|
||||
this._color = color;
|
||||
JX.DOM.alterClass(node, this._color, true);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setButtonType: function(button_type) {
|
||||
var self = JX.PHUIXButtonView;
|
||||
|
||||
this._buttonType = button_type;
|
||||
var node = this.getNode();
|
||||
|
||||
var is_simple = (this._buttonType == self.BUTTONTYPE_SIMPLE);
|
||||
JX.DOM.alterClass(node, 'simple', is_simple);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setText: function(text) {
|
||||
JX.DOM.setContent(this._getTextNode(), text);
|
||||
return this;
|
||||
},
|
||||
|
||||
getNode: function() {
|
||||
if (!this._node) {
|
||||
var attrs = {
|
||||
className: 'button'
|
||||
};
|
||||
|
||||
this._node = JX.$N('button', attrs);
|
||||
|
||||
this._redraw();
|
||||
}
|
||||
|
||||
return this._node;
|
||||
},
|
||||
|
||||
_getTextNode: function() {
|
||||
if (!this._textNode) {
|
||||
var attrs = {
|
||||
className: 'phui-button-text'
|
||||
};
|
||||
|
||||
this._textNode = JX.$N('div', attrs);
|
||||
}
|
||||
|
||||
return this._textNode;
|
||||
},
|
||||
|
||||
_redraw: function() {
|
||||
var node = this.getNode();
|
||||
|
||||
var icon = this._iconView;
|
||||
var text = this._textNode;
|
||||
|
||||
var content = [];
|
||||
if (icon) {
|
||||
content.push(icon.getNode());
|
||||
}
|
||||
|
||||
if (text) {
|
||||
content.push(text);
|
||||
}
|
||||
|
||||
JX.DOM.alterClass(node, 'has-icon', !!icon);
|
||||
JX.DOM.alterClass(node, 'has-text', !!text);
|
||||
JX.DOM.setContent(node, content);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
65
webroot/rsrc/js/phuix/PHUIXExample.js
Normal file
65
webroot/rsrc/js/phuix/PHUIXExample.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phuix-example
|
||||
* @requires javelin-install
|
||||
* javelin-dom
|
||||
* phuix-button-view
|
||||
*/
|
||||
|
||||
JX.behavior('phuix-example', function(config) {
|
||||
var node;
|
||||
var spec;
|
||||
var defaults;
|
||||
|
||||
switch (config.type) {
|
||||
case 'button':
|
||||
var button = new JX.PHUIXButtonView();
|
||||
defaults = {
|
||||
text: null,
|
||||
icon: null,
|
||||
type: null,
|
||||
color: null
|
||||
};
|
||||
|
||||
spec = JX.copy(defaults, config.spec);
|
||||
|
||||
if (spec.text !== null) {
|
||||
button.setText(spec.text);
|
||||
}
|
||||
|
||||
if (spec.icon !== null) {
|
||||
button.setIcon(spec.icon);
|
||||
}
|
||||
|
||||
if (spec.type !== null) {
|
||||
button.setButtonType(spec.type);
|
||||
}
|
||||
|
||||
if (spec.color !== null) {
|
||||
button.setColor(spec.color);
|
||||
}
|
||||
|
||||
node = button.getNode();
|
||||
break;
|
||||
case 'icon':
|
||||
var icon = new JX.PHUIXIconView();
|
||||
defaults = {
|
||||
icon: null,
|
||||
color: null
|
||||
};
|
||||
|
||||
spec = JX.copy(defaults, config.spec);
|
||||
|
||||
if (spec.icon !== null) {
|
||||
icon.setIcon(spec.icon);
|
||||
}
|
||||
|
||||
if (spec.color !== null) {
|
||||
icon.setColor(spec.color);
|
||||
}
|
||||
|
||||
node = icon.getNode();
|
||||
break;
|
||||
}
|
||||
|
||||
JX.DOM.setContent(JX.$(config.id), node);
|
||||
});
|
Loading…
Reference in a new issue