diff --git a/conf/default.conf.php b/conf/default.conf.php index a668c27d79..b265976e23 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -24,8 +24,39 @@ return array( 'phabricator.csrf-key' => '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3', + + 'phabricator.version' => 'UNSTABLE', + 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef', + + // When email is sent, try to hand it off to the MTA immediately. The only + // reason to disable this is if your MTA infrastructure is completely + // terrible. If you disable this option, you must run the 'metamta_mta.php' + // daemon or mail won't be handed off to the MTA. + 'metamta.send-immediately' => true, + + +// -- DarkConsole ----------------------------------------------------------- // + + // DarkConsole is a administrative debugging/profiling tool built into + // Phabricator. You can leave it disabled unless you're developing against + // Phabricator. + + // Determines whether or not DarkConsole is available. DarkConsole exposes + // some data like queries and stack traces, so you should be careful about + // turning it on in production (although users can not normally see it, even + // if the deployment configuration enables it). + 'darkconsole.enabled' => true, + + // Always enable DarkConsole, even for logged out users. This potentially + // exposes sensitive information to users, so make sure untrusted users can + // not access an install running in this mode. You should definitely leave + // this off in production. It is only really useful for using DarkConsole + // utilties to debug or profile logged-out pages. You must set + // 'darkconsole.enabled' to use this option. + 'darkconsole.always-on' => false, + // -- MySQL --------------------------------------------------------------- // @@ -64,14 +95,5 @@ return array( 'recaptcha.private-key' => null, - 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef', - - // When email is sent, try to hand it off to the MTA immediately. The only - // reason to disable this is if your MTA infrastructure is completely - // terrible. If you disable this option, you must run the 'metamta_mta.php' - // daemon or mail won't be handed off to the MTA. - 'metamta.send-immediately' => true, - - ); diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 85b13652c0..6b34bd6c71 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -91,7 +91,7 @@ celerity_register_resource_map(array( ), 'phabricator-standard-page-view' => array( - 'uri' => '/res/fb02fb0e/rsrc/css/application/base/standard-page-view.css', + 'uri' => '/res/c7dedb5f/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( @@ -127,7 +127,7 @@ celerity_register_resource_map(array( ), 'differential-revision-comment-list-css' => array( - 'uri' => '/res/afbc5f6f/rsrc/css/application/differential/revision-comment-list.css', + 'uri' => '/res/10b9a829/rsrc/css/application/differential/revision-comment-list.css', 'type' => 'css', 'requires' => array( @@ -190,7 +190,7 @@ celerity_register_resource_map(array( ), 'phabricator-core-css' => array( - 'uri' => '/res/41c62455/rsrc/css/core/core.css', + 'uri' => '/res/80cbabe4/rsrc/css/core/core.css', 'type' => 'css', 'requires' => array( @@ -243,6 +243,16 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/core/behavior-tokenizer.js', ), + 'javelin-behavior-workflow' => + array( + 'uri' => '/res/15446e7e/rsrc/js/application/core/behavior-workflow.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-lib-dev', + ), + 'disk' => '/rsrc/js/application/core/behavior-workflow.js', + ), 'javelin-behavior-differential-add-reviewers' => array( 'uri' => '/res/330154e4/rsrc/js/application/differential/behavior-add-reviewers.js', @@ -295,7 +305,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-differential-show-all-comments' => array( - 'uri' => '/res/625fea99/rsrc/js/application/differential/behavior-show-all-comments.js', + 'uri' => '/res/2a3592b8/rsrc/js/application/differential/behavior-show-all-comments.js', 'type' => 'js', 'requires' => array( @@ -388,7 +398,7 @@ celerity_register_resource_map(array( ), array ( 'packages' => array ( - '20cc4391' => + '554bfa09' => array ( 'name' => 'core.pkg.css', 'symbols' => @@ -407,10 +417,10 @@ celerity_register_resource_map(array( 11 => 'phabricator-remarkup-css', 12 => 'syntax-highlighting-css', ), - 'uri' => '/res/pkg/20cc4391/core.pkg.css', + 'uri' => '/res/pkg/554bfa09/core.pkg.css', 'type' => 'css', ), - 'f7362a6c' => + '4b8af7b5' => array ( 'name' => 'differential.pkg.css', 'symbols' => @@ -424,7 +434,7 @@ celerity_register_resource_map(array( 6 => 'differential-revision-add-comment-css', 7 => 'differential-revision-comment-list-css', ), - 'uri' => '/res/pkg/f7362a6c/differential.pkg.css', + 'uri' => '/res/pkg/4b8af7b5/differential.pkg.css', 'type' => 'css', ), '30d594cf' => @@ -444,27 +454,27 @@ celerity_register_resource_map(array( ), 'reverse' => array ( - 'phabricator-core-css' => '20cc4391', - 'phabricator-core-buttons-css' => '20cc4391', - 'phabricator-standard-page-view' => '20cc4391', - 'aphront-dialog-view-css' => '20cc4391', - 'aphront-form-view-css' => '20cc4391', - 'aphront-panel-view-css' => '20cc4391', - 'aphront-side-nav-view-css' => '20cc4391', - 'aphront-table-view-css' => '20cc4391', - 'aphront-tokenizer-control-css' => '20cc4391', - 'aphront-typeahead-control-css' => '20cc4391', - 'phabricator-directory-css' => '20cc4391', - 'phabricator-remarkup-css' => '20cc4391', - 'syntax-highlighting-css' => '20cc4391', - 'differential-core-view-css' => 'f7362a6c', - 'differential-changeset-view-css' => 'f7362a6c', - 'differential-revision-detail-css' => 'f7362a6c', - 'differential-revision-history-css' => 'f7362a6c', - 'differential-table-of-contents-css' => 'f7362a6c', - 'differential-revision-comment-css' => 'f7362a6c', - 'differential-revision-add-comment-css' => 'f7362a6c', - 'differential-revision-comment-list-css' => 'f7362a6c', + 'phabricator-core-css' => '554bfa09', + 'phabricator-core-buttons-css' => '554bfa09', + 'phabricator-standard-page-view' => '554bfa09', + 'aphront-dialog-view-css' => '554bfa09', + 'aphront-form-view-css' => '554bfa09', + 'aphront-panel-view-css' => '554bfa09', + 'aphront-side-nav-view-css' => '554bfa09', + 'aphront-table-view-css' => '554bfa09', + 'aphront-tokenizer-control-css' => '554bfa09', + 'aphront-typeahead-control-css' => '554bfa09', + 'phabricator-directory-css' => '554bfa09', + 'phabricator-remarkup-css' => '554bfa09', + 'syntax-highlighting-css' => '554bfa09', + 'differential-core-view-css' => '4b8af7b5', + 'differential-changeset-view-css' => '4b8af7b5', + 'differential-revision-detail-css' => '4b8af7b5', + 'differential-revision-history-css' => '4b8af7b5', + 'differential-table-of-contents-css' => '4b8af7b5', + 'differential-revision-comment-css' => '4b8af7b5', + 'differential-revision-add-comment-css' => '4b8af7b5', + 'differential-revision-comment-list-css' => '4b8af7b5', 'javelin-behavior-differential-feedback-preview' => '30d594cf', 'javelin-behavior-differential-edit-inline-comments' => '30d594cf', 'javelin-behavior-differential-populate' => '30d594cf', diff --git a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php index 36d0e9408d..9fb983f220 100644 --- a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php +++ b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php @@ -43,6 +43,10 @@ abstract class AphrontApplicationConfiguration { final public function getConsole() { return $this->console; } + + final public function setConsole($console) { + $this->console = $console; + } final public function buildController() { $map = $this->getURIMap(); @@ -80,7 +84,6 @@ abstract class AphrontApplicationConfiguration { } final public function willBuildRequest() { - $this->console = new DarkConsoleCore(); } } diff --git a/src/aphront/console/controller/DarkConsoleController.php b/src/aphront/console/controller/DarkConsoleController.php index 8ca4128c7e..8c6f0a1925 100755 --- a/src/aphront/console/controller/DarkConsoleController.php +++ b/src/aphront/console/controller/DarkConsoleController.php @@ -38,7 +38,17 @@ class DarkConsoleController extends PhabricatorController { $user->save(); return new AphrontAjaxResponse(); } - + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { + $user->setConsoleEnabled(!$user->getConsoleEnabled()); + $user->save(); + if ($request->isAjax()) { + return new AphrontRedirectResponse(); + } else { + return id(new AphrontRedirectResponse())->setURI('/'); + } + } + } } diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index e78c6217b7..5d59e50786 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -182,6 +182,14 @@ class AphrontDefaultApplicationConfiguration 'dialog' => $response->buildResponseString(), )); } + } else if ($response instanceof AphrontRedirectResponse) { + if ($request->isAjax()) { + return id(new AphrontAjaxResponse()) + ->setContent( + array( + 'redirect' => $response->getURI(), + )); + } } else if ($response instanceof Aphront404Response) { $failure = new AphrontRequestFailureView(); diff --git a/src/aphront/response/redirect/AphrontRedirectResponse.php b/src/aphront/response/redirect/AphrontRedirectResponse.php index bb8666583c..1939a86f53 100644 --- a/src/aphront/response/redirect/AphrontRedirectResponse.php +++ b/src/aphront/response/redirect/AphrontRedirectResponse.php @@ -27,6 +27,10 @@ class AphrontRedirectResponse extends AphrontResponse { $this->uri = $uri; return $this; } + + public function getURI() { + return $this->uri; + } public function getHeaders() { return array( diff --git a/src/applications/base/controller/base/PhabricatorController.php b/src/applications/base/controller/base/PhabricatorController.php index bee50ca2ac..32205c245a 100644 --- a/src/applications/base/controller/base/PhabricatorController.php +++ b/src/applications/base/controller/base/PhabricatorController.php @@ -46,6 +46,14 @@ abstract class PhabricatorController extends AphrontController { } $request->setUser($user); + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { + if ($user->getConsoleEnabled() || + PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { + $console = new DarkConsoleCore(); + $request->getApplicationConfiguration()->setConsole($console); + } + } if ($this->shouldRequireLogin() && !$user->getPHID()) { throw new AphrontRedirectException('/login/'); diff --git a/src/view/page/standard/PhabricatorStandardPageView.php b/src/view/page/standard/PhabricatorStandardPageView.php index 0aaef9802e..a2ba41c9ab 100755 --- a/src/view/page/standard/PhabricatorStandardPageView.php +++ b/src/view/page/standard/PhabricatorStandardPageView.php @@ -80,6 +80,8 @@ class PhabricatorStandardPageView extends AphrontPageView { require_celerity_resource('javelin-lib-dev'); require_celerity_resource('javelin-workflow-dev'); + Javelin::initBehavior('workflow', array()); + if ($console) { require_celerity_resource('aphront-dark-console-css'); Javelin::initBehavior( @@ -171,6 +173,35 @@ class PhabricatorStandardPageView extends AphrontPageView { ''; } } + + $foot_links = array(); + + $version = PhabricatorEnv::getEnvConfig('phabricator.version'); + $foot_links[] = phutil_escape_html('Phabricator '.$version); + + 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 ($console ? '' : null). @@ -191,6 +222,9 @@ class PhabricatorStandardPageView extends AphrontPageView { ''. $this->bodyContent. '
'. + ''. + '
'. + $foot_links. '
'; } diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index befde48900..c525693278 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -49,3 +49,10 @@ .phabricator-login-details { float: right; } + +.phabricator-page-foot { + text-align: right; + padding: .5em 1em; + font-size: 11px; + color: #f3f3f3; +} \ No newline at end of file diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css index bc6836e779..bb11ad23d0 100644 --- a/webroot/rsrc/css/core/core.css +++ b/webroot/rsrc/css/core/core.css @@ -18,7 +18,7 @@ p, blockquote, th, td, button { } html { - padding-bottom: 16em; + padding-bottom: 4em; } table { diff --git a/webroot/rsrc/js/application/core/behavior-workflow.js b/webroot/rsrc/js/application/core/behavior-workflow.js new file mode 100644 index 0000000000..de6fe9b9df --- /dev/null +++ b/webroot/rsrc/js/application/core/behavior-workflow.js @@ -0,0 +1,33 @@ +/** + * @provides javelin-behavior-workflow + * @requires javelin-lib-dev + */ + +JX.behavior('workflow', function() { + JX.Stratcom.listen( + 'submit', + ['workflow', 'tag:form'], + function(e) { + if (JX.Stratcom.pass()) { + return; + } + if (e.getNode('workflow') !== e.getTarget()) { + return; + } + e.prevent(); + JX.Workflow.newFromForm(e.getTarget()).start(); + }); + JX.Stratcom.listen( + 'click', + ['workflow', 'tag:a'], + function(e) { + if (JX.Stratcom.pass()) { + return; + } + if (e.getNode('workflow') !== e.getTarget()) { + return; + } + e.prevent(); + JX.Workflow.newFromLink(e.getTarget()).start(); + }); +});