diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index e0c37a9931..4251523438 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -138,6 +138,7 @@ $app_map = array( 'countdown' => array(7, 5), 'conduit' => array(7, 30), 'feed' => array(3, 11), + 'paste' => array(9, 2), ); $xadj = -1; @@ -152,6 +153,22 @@ foreach ($app_map as $icon => $coords) { } } +$action_template = id(new PhutilSprite()) + ->setSourcePosition(0, 0) + ->setSourceSize(16, 16); + +$action_map = array( + 'file' => 'icon/page_white_text.png', + 'fork' => 'icon/arrow_branch.png', +); + +foreach ($action_map as $icon => $source) { + $sheet->addSprite( + id(clone $action_template) + ->setSourceFile($srcroot.$source) + ->setTargetCSS('.action-'.$icon)); +} + $sheet->generateImage($webroot.'/image/autosprite.png'); $sheet->generateCSS($webroot.'/css/autosprite.css'); diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 5ed5040c3d..151006f871 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -65,8 +65,8 @@ celerity_register_resource_map(array( ), '/rsrc/image/autosprite.png' => array( - 'hash' => 'e3a103473dad6161a7be5369c2e21276', - 'uri' => '/res/e3a10347/rsrc/image/autosprite.png', + 'hash' => '08fb34fc4ce0cd3be882a3177423ad49', + 'uri' => '/res/08fb34fc/rsrc/image/autosprite.png', 'disk' => '/rsrc/image/autosprite.png', 'type' => 'png', ), @@ -643,7 +643,7 @@ celerity_register_resource_map(array( ), 'autosprite-css' => array( - 'uri' => '/res/e09ec93c/rsrc/css/autosprite.css', + 'uri' => '/res/07043fce/rsrc/css/autosprite.css', 'type' => 'css', 'requires' => array( @@ -2215,6 +2215,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/herald/PathTypeahead.js', ), + 'phabricator-action-list-view-css' => + array( + 'uri' => '/res/f70fbcd4/rsrc/css/layout/phabricator-action-list-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/layout/phabricator-action-list-view.css', + ), 'phabricator-app-buttons-css' => array( 'uri' => '/res/1e153463/rsrc/css/application/directory/phabricator-app-buttons.css', @@ -2262,7 +2271,7 @@ celerity_register_resource_map(array( ), 'phabricator-core-css' => array( - 'uri' => '/res/f912ffab/rsrc/css/core/core.css', + 'uri' => '/res/f3c6e0b5/rsrc/css/core/core.css', 'type' => 'css', 'requires' => array( @@ -2334,6 +2343,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/flag/flag.css', ), + 'phabricator-header-view-css' => + array( + 'uri' => '/res/c89cc14d/rsrc/css/layout/phabricator-header-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/layout/phabricator-header-view.css', + ), 'phabricator-jump-nav' => array( 'uri' => '/res/8bdc0fc3/rsrc/css/application/directory/phabricator-jump-nav.css', @@ -2429,6 +2447,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/base/notification-menu.css', ), + 'phabricator-object-item-list-view-css' => + array( + 'uri' => '/res/7a31c016/rsrc/css/layout/phabricator-object-item-list-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/layout/phabricator-object-item-list-view.css', + ), 'phabricator-object-list-view-css' => array( 'uri' => '/res/4f183668/rsrc/css/application/projects/phabricator-object-list-view.css', @@ -2508,6 +2535,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/projects/project-tag.css', ), + 'phabricator-property-list-view-css' => + array( + 'uri' => '/res/4a2b2d85/rsrc/css/layout/phabricator-property-list-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/layout/phabricator-property-list-view.css', + ), 'phabricator-remarkup-css' => array( 'uri' => '/res/3b93a50d/rsrc/css/core/remarkup.css', @@ -2547,9 +2583,18 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/css/application/slowvote/slowvote.css', ), + 'phabricator-source-code-view-css' => + array( + 'uri' => '/res/631aa90a/rsrc/css/layout/phabricator-source-code-view.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/layout/phabricator-source-code-view.css', + ), 'phabricator-standard-page-view' => array( - 'uri' => '/res/678262d4/rsrc/css/application/base/standard-page-view.css', + 'uri' => '/res/13470ac6/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( @@ -2831,7 +2876,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - 'edf6b149' => + 'dd49ed34' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -2860,7 +2905,7 @@ celerity_register_resource_map(array( 21 => 'phabricator-flag-css', 22 => 'aphront-error-view-css', ), - 'uri' => '/res/pkg/edf6b149/core.pkg.css', + 'uri' => '/res/pkg/dd49ed34/core.pkg.css', 'type' => 'css', ), '971b021e' => @@ -3027,20 +3072,20 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => '7839ae2d', - 'aphront-crumbs-view-css' => 'edf6b149', - 'aphront-dialog-view-css' => 'edf6b149', - 'aphront-error-view-css' => 'edf6b149', - 'aphront-form-view-css' => 'edf6b149', + 'aphront-crumbs-view-css' => 'dd49ed34', + 'aphront-dialog-view-css' => 'dd49ed34', + 'aphront-error-view-css' => 'dd49ed34', + 'aphront-form-view-css' => 'dd49ed34', 'aphront-headsup-action-list-view-css' => '19ebcc79', - 'aphront-headsup-view-css' => 'edf6b149', - 'aphront-list-filter-view-css' => 'edf6b149', - 'aphront-pager-view-css' => 'edf6b149', - 'aphront-panel-view-css' => 'edf6b149', - 'aphront-side-nav-view-css' => 'edf6b149', - 'aphront-table-view-css' => 'edf6b149', - 'aphront-tokenizer-control-css' => 'edf6b149', - 'aphront-tooltip-css' => 'edf6b149', - 'aphront-typeahead-control-css' => 'edf6b149', + 'aphront-headsup-view-css' => 'dd49ed34', + 'aphront-list-filter-view-css' => 'dd49ed34', + 'aphront-pager-view-css' => 'dd49ed34', + 'aphront-panel-view-css' => 'dd49ed34', + 'aphront-side-nav-view-css' => 'dd49ed34', + 'aphront-table-view-css' => 'dd49ed34', + 'aphront-tokenizer-control-css' => 'dd49ed34', + 'aphront-tooltip-css' => 'dd49ed34', + 'aphront-typeahead-control-css' => 'dd49ed34', 'differential-changeset-view-css' => '19ebcc79', 'differential-core-view-css' => '19ebcc79', 'differential-inline-comment-editor' => '26972e06', @@ -3106,15 +3151,15 @@ celerity_register_resource_map(array( 'javelin-workflow' => '971b021e', 'maniphest-task-summary-css' => '7839ae2d', 'maniphest-transaction-detail-css' => '7839ae2d', - 'phabricator-app-buttons-css' => 'edf6b149', + 'phabricator-app-buttons-css' => 'dd49ed34', 'phabricator-content-source-view-css' => '19ebcc79', - 'phabricator-core-buttons-css' => 'edf6b149', - 'phabricator-core-css' => 'edf6b149', - 'phabricator-directory-css' => 'edf6b149', + 'phabricator-core-buttons-css' => 'dd49ed34', + 'phabricator-core-css' => 'dd49ed34', + 'phabricator-directory-css' => 'dd49ed34', 'phabricator-drag-and-drop-file-upload' => '26972e06', 'phabricator-dropdown-menu' => '971b021e', - 'phabricator-flag-css' => 'edf6b149', - 'phabricator-jump-nav' => 'edf6b149', + 'phabricator-flag-css' => 'dd49ed34', + 'phabricator-jump-nav' => 'dd49ed34', 'phabricator-keyboard-shortcut' => '971b021e', 'phabricator-keyboard-shortcut-manager' => '971b021e', 'phabricator-menu-item' => '971b021e', @@ -3122,11 +3167,11 @@ celerity_register_resource_map(array( 'phabricator-paste-file-upload' => '971b021e', 'phabricator-prefab' => '971b021e', 'phabricator-project-tag-css' => '7839ae2d', - 'phabricator-remarkup-css' => 'edf6b149', + 'phabricator-remarkup-css' => 'dd49ed34', 'phabricator-shaped-request' => '26972e06', - 'phabricator-standard-page-view' => 'edf6b149', + 'phabricator-standard-page-view' => 'dd49ed34', 'phabricator-tooltip' => '971b021e', - 'phabricator-transaction-view-css' => 'edf6b149', - 'syntax-highlighting-css' => 'edf6b149', + 'phabricator-transaction-view-css' => 'dd49ed34', + 'syntax-highlighting-css' => 'dd49ed34', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 889838b867..6ea74a139c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -545,6 +545,8 @@ phutil_register_library_map(array( 'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php', 'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php', 'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php', + 'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php', + 'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php', 'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php', 'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php', 'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php', @@ -559,6 +561,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationMailingLists' => 'applications/mailinglists/application/PhabricatorApplicationMailingLists.php', 'PhabricatorApplicationManiphest' => 'applications/maniphest/application/PhabricatorApplicationManiphest.php', 'PhabricatorApplicationMetaMTA' => 'applications/metamta/application/PhabricatorApplicationMetaMTA.php', + 'PhabricatorApplicationPaste' => 'applications/paste/application/PhabricatorApplicationPaste.php', 'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php', 'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php', 'PhabricatorApplicationPonder' => 'applications/ponder/application/PhabricatorApplicationPonder.php', @@ -747,6 +750,7 @@ phutil_register_library_map(array( 'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/PhabricatorGoodForNothingWorker.php', 'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php', 'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php', + 'PhabricatorHeaderView' => 'view/layout/PhabricatorHeaderView.php', 'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php', 'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php', 'PhabricatorIRCBot' => 'infrastructure/daemon/irc/PhabricatorIRCBot.php', @@ -865,6 +869,8 @@ phutil_register_library_map(array( 'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/PhabricatorObjectHandleConstants.php', 'PhabricatorObjectHandleData' => 'applications/phid/handle/PhabricatorObjectHandleData.php', 'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/PhabricatorObjectHandleStatus.php', + 'PhabricatorObjectItemListView' => 'view/layout/PhabricatorObjectItemListView.php', + 'PhabricatorObjectItemView' => 'view/layout/PhabricatorObjectItemView.php', 'PhabricatorObjectListView' => 'view/control/PhabricatorObjectListView.php', 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', 'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php', @@ -886,6 +892,7 @@ phutil_register_library_map(array( 'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php', 'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php', 'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php', + 'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php', 'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php', 'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php', 'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php', @@ -925,6 +932,7 @@ phutil_register_library_map(array( 'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php', 'PhabricatorProjectTransactionType' => 'applications/project/constants/PhabricatorProjectTransactionType.php', 'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php', + 'PhabricatorPropertyListView' => 'view/layout/PhabricatorPropertyListView.php', 'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php', 'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php', 'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php', @@ -1034,6 +1042,7 @@ phutil_register_library_map(array( 'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php', 'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php', 'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php', + 'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php', 'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php', 'PhabricatorStatusController' => 'applications/status/PhabricatorStatusController.php', 'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php', @@ -1673,6 +1682,8 @@ phutil_register_library_map(array( 'PackageDeleteMail' => 'PackageMail', 'PackageModifyMail' => 'PackageMail', 'Phabricator404Controller' => 'PhabricatorController', + 'PhabricatorActionListView' => 'AphrontView', + 'PhabricatorActionView' => 'AphrontView', 'PhabricatorApplicationApplications' => 'PhabricatorApplication', 'PhabricatorApplicationAudit' => 'PhabricatorApplication', 'PhabricatorApplicationAuth' => 'PhabricatorApplication', @@ -1686,6 +1697,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationMailingLists' => 'PhabricatorApplication', 'PhabricatorApplicationManiphest' => 'PhabricatorApplication', 'PhabricatorApplicationMetaMTA' => 'PhabricatorApplication', + 'PhabricatorApplicationPaste' => 'PhabricatorApplication', 'PhabricatorApplicationPeople' => 'PhabricatorApplication', 'PhabricatorApplicationPhriction' => 'PhabricatorApplication', 'PhabricatorApplicationPonder' => 'PhabricatorApplication', @@ -1855,6 +1867,7 @@ phutil_register_library_map(array( 'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon', 'PhabricatorGlobalLock' => 'PhutilLock', 'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker', + 'PhabricatorHeaderView' => 'AphrontView', 'PhabricatorHelpController' => 'PhabricatorController', 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', 'PhabricatorIRCBot' => 'PhabricatorDaemon', @@ -1952,6 +1965,8 @@ phutil_register_library_map(array( 'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController', 'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController', 'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants', + 'PhabricatorObjectItemListView' => 'AphrontView', + 'PhabricatorObjectItemView' => 'AphrontView', 'PhabricatorObjectListView' => 'AphrontView', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', 'PhabricatorOwnersController' => 'PhabricatorController', @@ -1977,6 +1992,7 @@ phutil_register_library_map(array( ), 'PhabricatorPasteController' => 'PhabricatorController', 'PhabricatorPasteDAO' => 'PhabricatorLiskDAO', + 'PhabricatorPasteEditController' => 'PhabricatorPasteController', 'PhabricatorPasteListController' => 'PhabricatorPasteController', 'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyQuery', 'PhabricatorPasteViewController' => 'PhabricatorPasteController', @@ -2014,6 +2030,7 @@ phutil_register_library_map(array( 'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO', 'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants', 'PhabricatorProjectUpdateController' => 'PhabricatorProjectController', + 'PhabricatorPropertyListView' => 'AphrontView', 'PhabricatorRedirectController' => 'PhabricatorController', 'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController', 'PhabricatorRemarkupRuleCountdown' => 'PhutilRemarkupRule', @@ -2108,6 +2125,7 @@ phutil_register_library_map(array( 'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController', 'PhabricatorSlugTestCase' => 'PhabricatorTestCase', 'PhabricatorSortTableExample' => 'PhabricatorUIExample', + 'PhabricatorSourceCodeView' => 'AphrontView', 'PhabricatorStandardPageView' => 'AphrontPageView', 'PhabricatorStatusController' => 'PhabricatorController', 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', diff --git a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php index d4086c0300..a665f40c20 100644 --- a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php @@ -196,11 +196,6 @@ class AphrontDefaultApplicationConfiguration '/status/' => 'PhabricatorStatusController', - '/paste/' => array( - '' => 'PhabricatorPasteListController', - 'filter/(?P\w+)/' => 'PhabricatorPasteListController', - ), - '/P(?P\d+)' => 'PhabricatorPasteViewController', '/help/' => array( 'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController', diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index 142fb2595c..dcfd3d072c 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -18,6 +18,8 @@ abstract class PhabricatorController extends AphrontController { + private $handles; + public function shouldRequireLogin() { return true; } @@ -163,6 +165,11 @@ abstract class PhabricatorController extends AphrontController { $page->appendChild($view); + if (idx($options, 'device')) { + $page->setDeviceReady(true); + $view->appendChild($page->renderFooter()); + } + $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } @@ -200,4 +207,19 @@ abstract class PhabricatorController extends AphrontController { return $response; } + protected function getHandle($phid) { + if (empty($this->handles[$phid])) { + throw new Exception( + "Attempting to access handle which wasn't loaded: {$phid}"); + } + return $this->handles[$phid]; + } + + protected function loadHandles(array $phids) { + $phids = array_filter($phids); + $this->handles = id(new PhabricatorObjectHandleData($phids)) + ->setViewer($this->getRequest()->getUser()) + ->loadHandles(); + return $this; + } } diff --git a/src/applications/paste/application/PhabricatorApplicationPaste.php b/src/applications/paste/application/PhabricatorApplicationPaste.php new file mode 100644 index 0000000000..c0e7aa61ea --- /dev/null +++ b/src/applications/paste/application/PhabricatorApplicationPaste.php @@ -0,0 +1,43 @@ +\d+)' => 'PhabricatorPasteViewController', + '/paste/' => array( + '' => 'PhabricatorPasteListController', + 'filter/(?P\w+)/' => 'PhabricatorPasteListController', + ), + ); + } + +} diff --git a/src/applications/paste/controller/PhabricatorPasteController.php b/src/applications/paste/controller/PhabricatorPasteController.php index 97a5fae593..80b1733c4a 100644 --- a/src/applications/paste/controller/PhabricatorPasteController.php +++ b/src/applications/paste/controller/PhabricatorPasteController.php @@ -1,7 +1,7 @@ setBaseURI(new PhutilURI($this->getApplicationURI('filter/'))); + + if ($paste) { + $nav->addFilter('paste', 'P'.$paste->getID(), '/P'.$paste->getID()); + $nav->addSpacer(); + } + + $nav->addLabel('Create'); + $nav->addFilter('create', 'New Paste'); + + $nav->addSpacer(); + $nav->addLabel('Pastes'); + $nav->addFilter('my', 'My Pastes'); + $nav->addFilter('all', 'All Pastes'); + + return $nav; + } + public function buildStandardPageResponse($view, array $data) { $page = $this->buildStandardPageView(); diff --git a/src/applications/paste/controller/PhabricatorPasteListController.php b/src/applications/paste/controller/PhabricatorPasteListController.php index 12c4b91e2c..19fc51fda2 100644 --- a/src/applications/paste/controller/PhabricatorPasteListController.php +++ b/src/applications/paste/controller/PhabricatorPasteListController.php @@ -102,31 +102,9 @@ final class PhabricatorPasteListController extends PhabricatorPasteController { break; } - $filters = array( - 'create' => array( - 'name' => 'Create Paste', - ), - 'my' => array( - 'name' => 'My Pastes', - ), - 'all' => array( - 'name' => 'All Pastes', - ), - ); + $side_nav = $this->buildSideNavView(); + $side_nav->selectFilter($this->getFilter()); - $side_nav = new AphrontSideNavView(); - foreach ($filters as $filter_key => $filter) { - $selected = $filter_key == $this->getFilter(); - $side_nav->addNavItem( - phutil_render_tag( - 'a', - array( - 'href' => '/paste/filter/'.$filter_key.'/', - 'class' => $selected ? 'aphront-side-nav-selected': null, - ), - $filter['name']) - ); - } if ($this->getErrorView()) { $side_nav->appendChild($this->getErrorView()); @@ -142,7 +120,7 @@ final class PhabricatorPasteListController extends PhabricatorPasteController { 'href' => '/paste/filter/all', ), 'See all Pastes'); - $header = "Recent Pastes · {$see_all}"; + $header = "Recent Pastes"; break; case 'my': $header = 'Your Pastes'; @@ -152,14 +130,17 @@ final class PhabricatorPasteListController extends PhabricatorPasteController { break; } + $this->loadHandles(mpull($paste_list, 'getAuthorPHID')); + $side_nav->appendChild( $this->renderPasteList($paste_list, $header, $pager)); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( $side_nav, array( 'title' => 'Paste', + 'device' => true, ) ); } @@ -310,95 +291,26 @@ final class PhabricatorPasteListController extends PhabricatorPasteController { private function renderPasteList(array $pastes, $header, $pager) { assert_instances_of($pastes, 'PhabricatorPaste'); - $phids = mpull($pastes, 'getAuthorPHID'); - $handles = array(); - if ($phids) { - $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); - } + $user = $this->getRequest()->getUser(); - $phids = mpull($pastes, 'getFilePHID'); - $file_uris = array(); - if ($phids) { - $files = id(new PhabricatorFile())->loadAllWhere( - 'phid in (%Ls)', - $phids); - if ($files) { - $file_uris = mpull($files, 'getBestURI', 'getPHID'); - } - } - - $paste_list_rows = array(); + $list = new PhabricatorObjectItemListView(); + $list->setHeader($header); foreach ($pastes as $paste) { + $created = phabricator_datetime($paste->getDateCreated(), $user); - $handle = $handles[$paste->getAuthorPHID()]; - $file_uri = $file_uris[$paste->getFilePHID()]; + $item = id(new PhabricatorObjectItemView()) + ->setHeader('P'.$paste->getID().' '.$paste->getTitle()) + ->setHref('/P'.$paste->getID()) + ->addDetail( + pht('Author'), + $this->getHandle($paste->getAuthorPHID())->renderLink()) + ->addAttribute(pht('Created %s', $created)); - $paste_list_rows[] = array( - phutil_escape_html('P'.$paste->getID()), - - // TODO: Make this filter by user instead of going to their profile. - phutil_render_tag( - 'a', - array( - 'href' => '/p/'.$handle->getName().'/', - ), - phutil_escape_html($handle->getName())), - - phutil_escape_html($paste->getLanguage()), - - phutil_render_tag( - 'a', - array( - 'href' => '/P'.$paste->getID(), - ), - phutil_escape_html( - nonempty( - $paste->getTitle(), - 'Untitled Masterwork P'.$paste->getID()))), - - phutil_render_tag( - 'a', - array( - 'href' => $file_uri, - ), - phutil_escape_html($paste->getFilePHID())), - - phabricator_datetime( - $paste->getDateCreated(), - $this->getRequest()->getUser()), - ); + $list->addItem($item); } + $list->setPager($pager); - $table = new AphrontTableView($paste_list_rows); - $table->setHeaders( - array( - 'Paste ID', - 'Author', - 'Language', - 'Title', - 'File', - 'Created', - )); - - $table->setColumnClasses( - array( - null, - null, - null, - 'wide pri', - null, - 'right', - )); - - $panel = new AphrontPanelView(); - $panel->setWidth(AphrontPanelView::WIDTH_FULL); - $panel->setHeader($header); - $panel->appendChild($table); - if ($pager) { - $panel->appendChild($pager); - } - - return $panel; + return $list; } } diff --git a/src/applications/paste/controller/PhabricatorPasteViewController.php b/src/applications/paste/controller/PhabricatorPasteViewController.php index 216753bbb3..c9baf94b47 100644 --- a/src/applications/paste/controller/PhabricatorPasteViewController.php +++ b/src/applications/paste/controller/PhabricatorPasteViewController.php @@ -19,21 +19,20 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController { private $id; + private $handles; public function willProcessRequest(array $data) { $this->id = $data['id']; } public function processRequest() { - $request = $this->getRequest(); $user = $request->getUser(); $paste = id(new PhabricatorPasteQuery()) ->setViewer($user) - ->withPasteIDs(array($this->id)) + ->withIDs(array($this->id)) ->executeOne(); - if (!$paste) { return new Aphront404Response(); } @@ -45,94 +44,87 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController { return new Aphront400Response(); } - $corpus = $this->buildCorpus($paste, $file); - $paste_panel = new AphrontPanelView(); - - $author_phid = $paste->getAuthorPHID(); - $header = 'Viewing Paste '.$paste->getID().' by '. - PhabricatorObjectHandleData::loadOneHandle($author_phid)->renderLink(); - if (strlen($paste->getTitle())) { - $header .= ' - '.phutil_escape_html($paste->getTitle()); - } - $paste_panel->setHeader($header); - - $paste_panel->setWidth(AphrontPanelView::WIDTH_FULL); - $paste_panel->addButton( - phutil_render_tag( - 'a', - array( - 'href' => '/paste/?fork='.$paste->getID(), - 'class' => 'green button', - ), - 'Fork This')); - - $raw_uri = $file->getBestURI(); - $paste_panel->addButton( - phutil_render_tag( - 'a', - array( - 'href' => $raw_uri, - 'class' => 'button', - ), - 'View Raw Text')); - - $paste_panel->appendChild($corpus); - - $forks_panel = null; - $forks_of_this_paste = id(new PhabricatorPaste())->loadAllWhere( - 'parentPHID = %s', - $paste->getPHID()); - - if ($forks_of_this_paste) { - $forks_panel = new AphrontPanelView(); - $forks_panel->setHeader("Forks of this paste"); - $forks = array(); - foreach ($forks_of_this_paste as $fork) { - $forks[] = array( - $fork->getID(), - phutil_render_tag( - 'a', - array( - 'href' => '/P'.$fork->getID(), - ), - phutil_escape_html($fork->getTitle()) - ) - ); - } - $forks_table = new AphrontTableView($forks); - $forks_table->setHeaders( - array( - 'Paste ID', - 'Title', - ) - ); - $forks_table->setColumnClasses( - array( - null, - 'wide pri', - ) - ); - $forks_panel->appendChild($forks_table); - } - - return $this->buildStandardPageResponse( + $this->loadHandles( array( - $paste_panel, - $forks_panel, - ), + $paste->getAuthorPHID(), + $paste->getParentPHID(), + )); + + $header = $this->buildHeaderView($paste); + $actions = $this->buildActionView($paste, $file); + $properties = $this->buildPropertyView($paste); + $source_code = $this->buildSourceCodeView($paste, $file); + + $nav = $this->buildSideNavView($paste); + $nav->selectFilter('paste'); + $nav->appendChild( array( - 'title' => 'Paste: '.nonempty($paste->getTitle(), 'P'.$paste->getID()), + $header, + $actions, + $properties, + $source_code, +// $forks_panel, + )); + + return $this->buildApplicationPage( + $nav, + array( + 'title' => 'P'.$paste->getID().' '.$paste->getTitle(), + 'device' => true, )); } - private function buildCorpus($paste, $file) { - // Blantently copied from DiffusionBrowseFileController + private function buildHeaderView(PhabricatorPaste $paste) { + return id(new PhabricatorHeaderView()) + ->setObjectName('P'.$paste->getID()) + ->setHeader($paste->getTitle()); + } - require_celerity_resource('diffusion-source-css'); - require_celerity_resource('syntax-highlighting-css'); + private function buildActionView( + PhabricatorPaste $paste, + PhabricatorFile $file) { + + return id(new PhabricatorActionListView()) + ->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Fork This Paste')) + ->setIcon('fork') + ->setHref($this->getApplicationURI('?fork='.$paste->getID()))) + ->addAction( + id(new PhabricatorActionView()) + ->setName(pht('View Raw File')) + ->setIcon('file') + ->setHref($file->getBestURI())); + } + + private function buildPropertyView(PhabricatorPaste $paste) { + $user = $this->getRequest()->getUser(); + $properties = new PhabricatorPropertyListView(); + + $properties->addProperty( + pht('Author'), + $this->getHandle($paste->getAuthorPHID())->renderLink()); + + $properties->addProperty( + pht('Created'), + phabricator_datetime($paste->getDateCreated(), $user)); + + if ($paste->getParentPHID()) { + $properties->addProperty( + pht('Forked From'), + $this->getHandle($paste->getParentPHID())->renderLink()); + } + + return $properties; + } + + private function buildSourceCodeView( + PhabricatorPaste $paste, + PhabricatorFile $file) { $language = $paste->getLanguage(); $source = $file->loadFileData(); + if (empty($language)) { $source = PhabricatorSyntaxHighlighter::highlightWithFilename( $paste->getTitle(), @@ -143,63 +135,10 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController { $source); } - $text_list = explode("\n", $source); + $lines = explode("\n", $source); - Javelin::initBehavior('phabricator-oncopy', array()); - $rows = $this->buildDisplayRows($text_list); - - // TODO: Split the "one-up source listing" view into its own class and - // share it properly between Paste and Diffusion. - - $corpus_table = phutil_render_tag( - 'table', - array( - 'class' => 'diffusion-source remarkup-code PhabricatorMonospaced', - ), - implode("\n", $rows)); - - $corpus = phutil_render_tag( - 'div', - array( - 'style' => 'padding: 0pt 2em;', - ), - $corpus_table); - - return $corpus; - } - - private function buildDisplayRows($text_list) { - $rows = array(); - $n = 1; - - foreach ($text_list as $k => $line) { - // Pardon the ugly for the time being. - // And eventually this will highlight a line that you click - // like diffusion does. Or maybe allow for line comments - // like differential. Either way it will be better than it is now. - $anchor = 'L'.$n; - $link = phutil_render_tag( - 'a', - array( - 'name' => $anchor, - 'href' => '#'.$anchor, - ), - $n); - $link = phutil_render_tag( - 'th', - array( - 'class' => 'diffusion-line-link', - ), - $link); - $rows[] = ''.$link. - ''. - // NOTE: See the 'phabricator-oncopy' behavior. - "\xE2\x80\x8B". - $line.''; - ++$n; - } - - return $rows; + return id(new PhabricatorSourceCodeView()) + ->setLines($lines); } } diff --git a/src/applications/paste/query/PhabricatorPasteQuery.php b/src/applications/paste/query/PhabricatorPasteQuery.php index e6492c3b9e..2a40eb528c 100644 --- a/src/applications/paste/query/PhabricatorPasteQuery.php +++ b/src/applications/paste/query/PhabricatorPasteQuery.php @@ -18,11 +18,17 @@ final class PhabricatorPasteQuery extends PhabricatorCursorPagedPolicyQuery { - private $pasteIDs; + private $ids; + private $phids; private $authorPHIDs; - public function withPasteIDs(array $ids) { - $this->pasteIDs = $ids; + public function withIDs(array $ids) { + $this->ids = $ids; + return $this; + } + + public function withPHIDs(array $phids) { + $this->phids = $phids; return $this; } @@ -53,11 +59,18 @@ final class PhabricatorPasteQuery extends PhabricatorCursorPagedPolicyQuery { $where[] = $this->buildPagingClause($conn_r); - if ($this->pasteIDs) { + if ($this->ids) { $where[] = qsprintf( $conn_r, - 'id IN (%Ls)', - $this->pasteIDs); + 'id IN (%Ld)', + $this->ids); + } + + if ($this->phids) { + $where[] = qsprintf( + $conn_r, + 'phid IN (%Ls)', + $this->phids); } if ($this->authorPHIDs) { diff --git a/src/applications/phid/handle/PhabricatorObjectHandleData.php b/src/applications/phid/handle/PhabricatorObjectHandleData.php index 7fabb89c1f..7d59dfede3 100644 --- a/src/applications/phid/handle/PhabricatorObjectHandleData.php +++ b/src/applications/phid/handle/PhabricatorObjectHandleData.php @@ -19,11 +19,17 @@ final class PhabricatorObjectHandleData { private $phids; + private $viewer; public function __construct(array $phids) { $this->phids = array_unique($phids); } + public function setViewer(PhabricatorUser $viewer) { + $this->viewer = $viewer; + return $this; + } + public static function loadOneHandle($phid) { $handles = id(new PhabricatorObjectHandleData(array($phid)))->loadHandles(); return $handles[$phid]; @@ -443,7 +449,7 @@ final class PhabricatorObjectHandleData { $questions = id(new PonderQuestionQuery()) ->withPHIDs($phids) ->execute(); - $questions = mpull($questions, 'getPHID'); + $questions = mpull($questions, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); @@ -460,6 +466,29 @@ final class PhabricatorObjectHandleData { $handles[$phid] = $handle; } break; + case PhabricatorPHIDConstants::PHID_TYPE_PSTE: + $pastes = id(new PhabricatorPasteQuery()) + ->withPHIDs($phids) + ->setViewer($this->viewer) + ->execute(); + $pastes = mpull($pastes, null, 'getPHID'); + + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + $handle->setType($type); + if (empty($pastes[$phid])) { + $handle->setName('Unknown Paste'); + } else { + $paste = $pastes[$phid]; + $handle->setName($paste->getTitle()); + $handle->setFullName('P'.$paste->getID().': '.$paste->getTitle()); + $handle->setURI('/P'.$paste->getID()); + $handle->setComplete(true); + } + $handles[$phid] = $handle; + } + break; default: $loader = null; if (isset($external_loaders[$type])) { diff --git a/src/view/layout/PhabricatorActionListView.php b/src/view/layout/PhabricatorActionListView.php new file mode 100644 index 0000000000..5c7a1a9c67 --- /dev/null +++ b/src/view/layout/PhabricatorActionListView.php @@ -0,0 +1,41 @@ +actions[] = $view; + return $this; + } + + + public function render() { + require_celerity_resource('phabricator-action-list-view-css'); + + return phutil_render_tag( + 'ul', + array( + 'class' => 'phabricator-action-list-view', + ), + $this->renderSingleView($this->actions)); + } + + +} diff --git a/src/view/layout/PhabricatorActionView.php b/src/view/layout/PhabricatorActionView.php new file mode 100644 index 0000000000..778e0d4845 --- /dev/null +++ b/src/view/layout/PhabricatorActionView.php @@ -0,0 +1,79 @@ +href = $href; + return $this; + } + + public function setIcon($icon) { + $this->icon = $icon; + return $this; + } + + public function setName($name) { + $this->name = $name; + return $this; + } + + public function render() { + + $icon = null; + if ($this->icon) { + $icon = phutil_render_tag( + 'span', + array( + 'class' => 'phabricator-action-view-icon autosprite '. + 'action-'.$this->icon, + ), + ''); + } + + if ($this->href) { + $item = phutil_render_tag( + 'a', + array( + 'href' => $this->href, + 'class' => 'phabricator-action-view-item', + ), + phutil_escape_html($this->name)); + } else { + $item = phutil_render_tag( + 'span', + array( + 'class' => 'phabricator-action-view-item', + ), + phutil_escape_html($this->name)); + } + + return phutil_render_tag( + 'li', + array( + 'class' => 'phabricator-action-view', + ), + $icon.$item); + } + + +} diff --git a/src/view/layout/PhabricatorHeaderView.php b/src/view/layout/PhabricatorHeaderView.php new file mode 100644 index 0000000000..7b22e923c9 --- /dev/null +++ b/src/view/layout/PhabricatorHeaderView.php @@ -0,0 +1,57 @@ +header = $header; + return $this; + } + + public function setObjectName($object_name) { + $this->objectName = $object_name; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-header-view-css'); + + $header = phutil_escape_html($this->header); + + if ($this->objectName) { + $header = phutil_render_tag( + 'a', + array( + 'href' => '/'.$this->objectName, + ), + phutil_escape_html($this->objectName)).' '.$header; + } + + return phutil_render_tag( + 'h1', + array( + 'class' => 'phabricator-header-view', + ), + $header); + } + + +} diff --git a/src/view/layout/PhabricatorObjectItemListView.php b/src/view/layout/PhabricatorObjectItemListView.php new file mode 100644 index 0000000000..3bd19d17ea --- /dev/null +++ b/src/view/layout/PhabricatorObjectItemListView.php @@ -0,0 +1,64 @@ +header = $header; + return $this; + } + + public function setPager($pager) { + $this->pager = $pager; + return $this; + } + + public function addItem(PhabricatorObjectItemView $item) { + $this->items[] = $item; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-object-item-list-view-css'); + + $header = phutil_render_tag( + 'h1', + array( + 'class' => 'phabricator-object-item-list-header', + ), + phutil_escape_html($this->header)); + $items = $this->renderSingleView($this->items); + + $pager = null; + if ($this->pager) { + $pager = $this->renderSingleView($this->pager); + } + + return phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-object-item-list-view', + ), + $header.$items.$pager); + } + +} diff --git a/src/view/layout/PhabricatorObjectItemView.php b/src/view/layout/PhabricatorObjectItemView.php new file mode 100644 index 0000000000..58d057ef04 --- /dev/null +++ b/src/view/layout/PhabricatorObjectItemView.php @@ -0,0 +1,109 @@ +href = $href; + return $this; + } + + public function getHref() { + return $this->href; + } + + public function setHeader($header) { + $this->header = $header; + return $this; + } + + public function getHeader() { + return $this->header; + } + + public function addDetail($name, $value, $class = null) { + $this->details[] = array( + 'name' => $name, + 'value' => $value, + ); + return $this; + } + + public function addAttribute($attribute) { + $this->attributes[] = $attribute; + return $this; + } + + public function render() { + $header = phutil_render_tag( + 'a', + array( + 'href' => $this->href, + 'class' => 'phabricator-object-item-name', + ), + phutil_escape_html($this->header)); + + $details = null; + if ($this->details) { + $details = array(); + foreach ($this->details as $detail) { + $details[] = + '
'. + phutil_escape_html($detail['name']). + '
'; + $details[] = + '
'. + $detail['value']. + ''; + } + $details = phutil_render_tag( + 'dl', + array( + 'class' => 'phabricator-object-detail-list', + ), + implode('', $details)); + } + + $attrs = null; + if ($this->attributes) { + $attrs = array(); + foreach ($this->attributes as $attribute) { + $attrs[] = '
  • '.$attribute.'
  • '; + } + $attrs = phutil_render_tag( + 'ul', + array( + 'class' => 'phabricator-object-item-attributes', + ), + implode('', $attrs)); + } + + return phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-object-item', + ), + $header.$details.$attrs); + } + +} diff --git a/src/view/layout/PhabricatorPropertyListView.php b/src/view/layout/PhabricatorPropertyListView.php new file mode 100644 index 0000000000..e3abbcfe69 --- /dev/null +++ b/src/view/layout/PhabricatorPropertyListView.php @@ -0,0 +1,62 @@ +properties[$key] = $value; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-property-list-view-css'); + + $items = array(); + foreach ($this->properties as $key => $value) { + $items[] = phutil_render_tag( + 'dt', + array( + 'class' => 'phabricator-property-key', + ), + phutil_escape_html($key)); + $items[] = phutil_render_tag( + 'dd', + array( + 'class' => 'phabricator-property-value', + ), + $this->renderSingleView($value)); + } + + $list = phutil_render_tag( + 'dl', + array( + ), + $this->renderSingleView($items)); + + return phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-property-list-view', + ), + $list); + } + + +} diff --git a/src/view/layout/PhabricatorSourceCodeView.php b/src/view/layout/PhabricatorSourceCodeView.php new file mode 100644 index 0000000000..d82856e931 --- /dev/null +++ b/src/view/layout/PhabricatorSourceCodeView.php @@ -0,0 +1,68 @@ +lines = $lines; + return $this; + } + + public function render() { + require_celerity_resource('phabricator-source-code-view-css'); + require_celerity_resource('syntax-highlighting-css'); + + Javelin::initBehavior('phabricator-oncopy', array()); + + $line_number = 1; + + $rows = array(); + foreach ($this->lines as $line) { + + // TODO: Provide nice links. + + $rows[] = + ''. + ''. + phutil_escape_html($line_number). + ''. + ''. + "\xE2\x80\x8B". + $line. + ''. + ''; + + $line_number++; + } + + $classes = array(); + $classes[] = 'phabricator-source-code-view'; + $classes[] = 'remarkup-code'; + $classes[] = 'PhabricatorMonospaced'; + + return phutil_render_tag( + 'table', + array( + 'class' => implode(' ', $classes), + ), + implode('', $rows)); + } + +} diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index b48ce0a34c..194074301c 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -31,6 +31,12 @@ final class PhabricatorStandardPageView extends AphrontPageView { private $searchDefaultScope; private $pageObjects = array(); private $controller; + private $deviceReady; + + public function setDeviceReady($device_ready) { + $this->deviceReady = $device_ready; + return $this; + } public function setController(AphrontController $controller) { $this->controller = $controller; @@ -203,12 +209,15 @@ final class PhabricatorStandardPageView extends AphrontPageView { } $viewport_tag = null; - if (PhabricatorEnv::getEnvConfig('preview.viewport-meta-tag')) { + if (PhabricatorEnv::getEnvConfig('preview.viewport-meta-tag') || + $this->deviceReady) { $viewport_tag = phutil_render_tag( 'meta', array( 'name' => 'viewport', - 'content' => 'width=device-width, initial-scale=1, maximum-scale=1', + 'content' => 'width=device-width, '. + 'initial-scale=1, '. + 'maximum-scale=1', )); } @@ -293,40 +302,6 @@ final class PhabricatorStandardPageView extends AphrontPageView { } } - $foot_links = array(); - - $version = PhabricatorEnv::getEnvConfig('phabricator.version'); - $foot_links[] = phutil_escape_html('Phabricator '.$version); - - $foot_links[] = - ''. - 'Report a Bug'. - ''; - - if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && - !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { - if ($console) { - $link = javelin_render_tag( - 'a', - array( - 'href' => '/~/', - 'sigil' => 'workflow', - ), - 'Disable DarkConsole'); - } else { - $link = javelin_render_tag( - 'a', - array( - 'href' => '/~/', - 'sigil' => 'workflow', - ), - 'Enable DarkConsole'); - } - $foot_links[] = $link; - } - - $foot_links = implode(' · ', $foot_links); - $admin_class = null; if ($this->getIsAdminInterface()) { $admin_class = 'phabricator-admin-page-view'; @@ -336,10 +311,10 @@ final class PhabricatorStandardPageView extends AphrontPageView { $footer_chrome = null; if ($this->getShowChrome()) { $header_chrome = $this->menuContent; - $footer_chrome = - '
    '. - $foot_links. - '
    '; + + if (!$this->deviceReady) { + $footer_chrome = $this->renderFooter(); + } } $developer_warning = null; @@ -491,4 +466,47 @@ final class PhabricatorStandardPageView extends AphrontPageView { return $menu->render(); } + public function renderFooter() { + $console = $this->getConsole(); + + $foot_links = array(); + + $version = PhabricatorEnv::getEnvConfig('phabricator.version'); + $foot_links[] = phutil_escape_html('Phabricator '.$version); + + $foot_links[] = + ''. + 'Report a Bug'. + ''; + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && + !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { + if ($console) { + $link = javelin_render_tag( + 'a', + array( + 'href' => '/~/', + 'sigil' => 'workflow', + ), + 'Disable DarkConsole'); + } else { + $link = javelin_render_tag( + 'a', + array( + 'href' => '/~/', + 'sigil' => 'workflow', + ), + 'Enable DarkConsole'); + } + $foot_links[] = $link; + } + + $foot_links = implode(' · ', $foot_links); + + return + '
    '. + $foot_links. + '
    '; + } + } diff --git a/src/view/viewutils.php b/src/view/viewutils.php index 880d11653d..a2324daee1 100644 --- a/src/view/viewutils.php +++ b/src/view/viewutils.php @@ -16,7 +16,7 @@ * limitations under the License. */ -function phabricator_date($epoch, $user) { +function phabricator_date($epoch, PhabricatorUser $user) { return phabricator_format_local_time( $epoch, $user, diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index f2f99b4a96..c1a30e925e 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -14,7 +14,7 @@ .phabricator-page-foot { text-align: right; margin: 2em; - border-top: 1px solid #afafaf; + border-top: 1px solid #dfdfdf; padding: .5em 1em; font-size: 11px; color: #666666; diff --git a/webroot/rsrc/css/autosprite.css b/webroot/rsrc/css/autosprite.css index be17be3b3f..5d61c7e8a3 100644 --- a/webroot/rsrc/css/autosprite.css +++ b/webroot/rsrc/css/autosprite.css @@ -234,3 +234,19 @@ .app-feed { background-position: 0px -2306px; } + +.app-paste-full { + background-position: 0px -2337px; +} + +.app-paste { + background-position: 0px -2398px; +} + +.action-file { + background-position: 0px -2429px; +} + +.action-fork { + background-position: 0px -2446px; +} diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css index 3eca95c220..2a6a8e5181 100644 --- a/webroot/rsrc/css/core/core.css +++ b/webroot/rsrc/css/core/core.css @@ -4,7 +4,16 @@ html { + /* Always show the vertical scrollbar so that going from a page without a + scrollbar to a page with a scrollbar doesn't make content jump a few + pixels left when the viewport narrows. */ overflow-y: scroll; + + /* By default, the iPhone zooms all text on the page by some percentage when + you rotate from portrait mode to landscape mode. Disable this, since it + breaks lots of things and prevents you from using landscape to see more + columns in source code views. */ + -webkit-text-size-adjust: none; } body, div, dl, dt, dd, ul, ol, li, diff --git a/webroot/rsrc/css/layout/phabricator-action-list-view.css b/webroot/rsrc/css/layout/phabricator-action-list-view.css new file mode 100644 index 0000000000..37b076dbb8 --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-action-list-view.css @@ -0,0 +1,54 @@ +/** + * @provides phabricator-action-list-view-css + */ + +.phabricator-action-list-view { + background: #ffffff; +} + +.device-desktop .phabricator-action-list-view { + border: 1px solid #dcdcdc; + padding: .5em 0; + + position: absolute; + margin-top: -30px; + right: 1%; + width: 20%; + border-radius: 2px; + font-size: 12px; + + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.10); +} + +.device-tablet .phabricator-action-list-view, +.device-phone .phabricator-action-list-view { + background: #f3f3f3; + border-top: 1px solid #dcdcdc; + padding: .5em 0; +} + +.phabricator-action-view { + padding: 2px 0; + position: relative; +} + +.phabricator-action-view-item { + line-height: 20px; + padding-left: 34px; + display: block; + font-size: 12px; +} + +.phabricator-action-view-icon { + width: 16px; + height: 16px; + position: absolute; + top: 4px; + left: 12px; +} + +.device-desktop .phabricator-action-view-item:hover { + background-color: #3875d7; + color: #ffffff; + text-decoration: none; +} diff --git a/webroot/rsrc/css/layout/phabricator-header-view.css b/webroot/rsrc/css/layout/phabricator-header-view.css new file mode 100644 index 0000000000..c3f96e9239 --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-header-view.css @@ -0,0 +1,13 @@ +/** + * @provides phabricator-header-view-css + */ + +.phabricator-header-view { + padding: 1em 2%; + font-size: 15px; + color: #333333; +} + +.device-desktop .phabricator-header-view { + width: 66%; +} diff --git a/webroot/rsrc/css/layout/phabricator-object-item-list-view.css b/webroot/rsrc/css/layout/phabricator-object-item-list-view.css new file mode 100644 index 0000000000..755c8c777e --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-object-item-list-view.css @@ -0,0 +1,103 @@ +/** + * @provides phabricator-object-item-list-view-css + */ + +.phabricator-object-item-list-view { + padding: 0 2%; + margin: 1em 0; +} + +.phabricator-object-item-list-header { + font-weight: normal; + color: #333333; + font-size: 15px; + margin-bottom: 12px; +} + + +.phabricator-object-item { + background: #f9f9f9; + border: 1px solid #dbdbdb; + border-radius: 2px; + margin: 6px 0; + + overflow: hidden; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10); +} + +.phabricator-object-item-name { + display: block; + background: #e9e9e9; + padding: 2px 1em; + font-weight: bold; +} + +.device-desktop .phabricator-object-item-name { + + border: solid #dbdbdb; + border-width: 0 0 1px 0; +} + +/* - Detail List ------------------------------------------------------------ + + Object details, used to render things like authors, reviewers, etc. + +*/ + + +.phabricator-object-detail-list { + font-size: 11px; + width: 55%; + padding: 2px 1%; +} + +.device-desktop .phabricator-object-detail-list, +.device-tablet .phabricator-object-detail-list { + float: left; +} + +.phabricator-object-detail-key { + color: #555555; + float: left; + clear: left; + width: 20%; + text-align: right; + padding: 2px 6px; + overflow: hidden; +} + +.phabricator-object-detail-value { + color: #444444; + float: left; + + padding: 2px 6px; +} + + +/* - Attribute List ------------------------------------------------------------ + + Object attributes, commonly used to render created date, etc. + +*/ + +.phabricator-object-item-attributes { + color: #555555; + text-align: right; + font-size: 11px; + + padding: 2px 1%; +} + +.device-desktop .phabricator-object-item-attributes, +.device-tablet .phabricator-object-item-attributes { + width: 40%; + float: right; +} + +.device-phone .phabricator-object-item-attributes { + clear: both; +} + +.phabricator-object-item-attributes li { + padding: 2px 1%; +} diff --git a/webroot/rsrc/css/layout/phabricator-property-list-view.css b/webroot/rsrc/css/layout/phabricator-property-list-view.css new file mode 100644 index 0000000000..afd471855f --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-property-list-view.css @@ -0,0 +1,59 @@ +/** + * @provides phabricator-property-list-view-css + */ + +.phabricator-property-list-view { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px 0; + background-color: #f9f9f9; + + overflow: hidden; +} + +.device-desktop .phabricator-property-list-view, +.device-tablet .phabricator-property-list-view { + padding: 1em 0 0.75em; +} + + +.device-phone .phabricator-property-list-view { + padding: .5em; +} + +.phabricator-property-key { + color: #333333; + font-weight: bold; +} + +.device-desktop .phabricator-property-key { + width: 12%; + margin-left: 1%; + text-align: right; + float: left; + clear: left; + margin-bottom: .5em; +} + +.device-tablet .phabricator-property-key, +.device-phone .phabricator-property-key { + padding-left: .5em; +} + +.phabricator-property-value { + color: #333333; +} + +.device-desktop .phabricator-property-value { + width: 53%; + margin-left: 1%; + float: left; + margin-bottom: .5em; +} + + +.device-tablet .phabricator-property-value, +.device-phone .phabricator-property-value { + padding-left: 1.5em; + margin-bottom: .5em; +} diff --git a/webroot/rsrc/css/layout/phabricator-source-code-view.css b/webroot/rsrc/css/layout/phabricator-source-code-view.css new file mode 100644 index 0000000000..3ec9b2b592 --- /dev/null +++ b/webroot/rsrc/css/layout/phabricator-source-code-view.css @@ -0,0 +1,26 @@ +/** + * @provides phabricator-source-code-view-css + */ + +.phabricator-source-code { + white-space: pre-wrap; + padding: 3px 8px; +} + +.phabricator-source-line { + text-align: right; + padding: 3px 6px 3px 12px; + + border-right: 1px solid #dbdbdb; + font-weight: bold; + color: #555555; + + /* When the user selects rows of source, don't visibly select the line + numbers beside them. We use JS to strip the line numbers out when the user + copies the text. */ + -moz-user-select: -moz-none; + -khtml-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} diff --git a/webroot/rsrc/image/autosprite.png b/webroot/rsrc/image/autosprite.png index d45011bd39..1010357901 100644 Binary files a/webroot/rsrc/image/autosprite.png and b/webroot/rsrc/image/autosprite.png differ