From 688c506ecf658833d895a29b69c7723c9bee1013 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Wed, 22 Apr 2015 12:05:27 -0700 Subject: [PATCH] Quicksand - update help appropriately as you navigate about Summary: Fixes T7724. Things are a bit tricky here as sometimes we don't want to display the help icon at all...! Change things such that we always render at least the icon, though it may have the style set to hidden if appropriate. Instrument quicksand javascript to then load the proper help dropdown if it can. Do this generally so other aphlict dropdowns could work pretty easily. Test Plan: started on home and noted no help. clicked maniphest and saw maniphest help. clicked home and saw no help again. clicked differential and saw differential help. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7724 Differential Revision: https://secure.phabricator.com/D12499 --- resources/celerity/map.php | 48 ++++++------- .../PhabricatorHelpApplication.php | 67 ++++++++++--------- src/view/page/PhabricatorStandardPageView.php | 60 ++++++++++++++--- .../aphlict/behavior-aphlict-dropdown.js | 18 ++++- webroot/rsrc/js/core/behavior-dark-console.js | 13 ++++ 5 files changed, 139 insertions(+), 67 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index b0e59154ca..932cf68d17 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,8 +8,8 @@ return array( 'names' => array( 'core.pkg.css' => 'a2a90172', - 'core.pkg.js' => 'd57952b0', - 'darkconsole.pkg.js' => '8ab24e01', + 'core.pkg.js' => '8e62b4aa', + 'darkconsole.pkg.js' => 'b0a3ba93', 'differential.pkg.css' => '3500921f', 'differential.pkg.js' => 'c0506961', 'diffusion.pkg.css' => '591664fa', @@ -350,7 +350,7 @@ return array( 'rsrc/image/texture/table_header_hover.png' => '038ec3b9', 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 'rsrc/js/application/aphlict/Aphlict.js' => '30a6303c', - 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '572566ae', + 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'ee37f73a', 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'b1a59974', 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761', 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', @@ -460,7 +460,7 @@ return array( 'rsrc/js/core/behavior-autofocus.js' => '7319e029', 'rsrc/js/core/behavior-choose-control.js' => '6153c708', 'rsrc/js/core/behavior-crop.js' => 'fa0f4fc2', - 'rsrc/js/core/behavior-dark-console.js' => '08883e8b', + 'rsrc/js/core/behavior-dark-console.js' => 'b8df5663', 'rsrc/js/core/behavior-device.js' => 'a205cf28', 'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '6d49590e', 'rsrc/js/core/behavior-error-log.js' => '6882e80a', @@ -550,7 +550,7 @@ return array( 'inline-comment-summary-css' => 'eb5f8e8c', 'javelin-aphlict' => '30a6303c', 'javelin-behavior' => '61cbc29a', - 'javelin-behavior-aphlict-dropdown' => '572566ae', + 'javelin-behavior-aphlict-dropdown' => 'ee37f73a', 'javelin-behavior-aphlict-listen' => 'b1a59974', 'javelin-behavior-aphlict-status' => 'ea681761', 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', @@ -567,7 +567,7 @@ return array( 'javelin-behavior-conpherence-pontificate' => '21ba5861', 'javelin-behavior-conpherence-widget-pane' => '93568464', 'javelin-behavior-countdown-timer' => 'e4cc26b3', - 'javelin-behavior-dark-console' => '08883e8b', + 'javelin-behavior-dark-console' => 'b8df5663', 'javelin-behavior-dashboard-async-panel' => '469c0d9e', 'javelin-behavior-dashboard-move-panels' => '82439934', 'javelin-behavior-dashboard-query-panel-select' => '453c5375', @@ -869,14 +869,6 @@ return array( 'phabricator-shaped-request', 'conpherence-thread-manager', ), - '08883e8b' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-util', - 'javelin-dom', - 'javelin-request', - 'phabricator-keyboard-shortcut', - ), '0a3f3021' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1198,16 +1190,6 @@ return array( 'javelin-vector', 'javelin-dom', ), - '572566ae' => array( - 'javelin-behavior', - 'javelin-request', - 'javelin-stratcom', - 'javelin-vector', - 'javelin-dom', - 'javelin-uri', - 'javelin-behavior-device', - 'phabricator-title', - ), 58562350 => array( 'javelin-dom', 'javelin-util', @@ -1737,6 +1719,14 @@ return array( 'javelin-dom', 'javelin-util', ), + 'b8df5663' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-util', + 'javelin-dom', + 'javelin-request', + 'phabricator-keyboard-shortcut', + ), 'bba9eedf' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1950,6 +1940,16 @@ return array( 'javelin-stratcom', 'javelin-vector', ), + 'ee37f73a' => array( + 'javelin-behavior', + 'javelin-request', + 'javelin-stratcom', + 'javelin-vector', + 'javelin-dom', + 'javelin-uri', + 'javelin-behavior-device', + 'phabricator-title', + ), 'efe49472' => array( 'javelin-install', 'javelin-util', diff --git a/src/applications/help/application/PhabricatorHelpApplication.php b/src/applications/help/application/PhabricatorHelpApplication.php index cd1704ea42..8f0b5a52b2 100644 --- a/src/applications/help/application/PhabricatorHelpApplication.php +++ b/src/applications/help/application/PhabricatorHelpApplication.php @@ -35,34 +35,42 @@ final class PhabricatorHelpApplication extends PhabricatorApplication { } $items = array(); + + $help_id = celerity_generate_unique_node_id(); + + Javelin::initBehavior( + 'aphlict-dropdown', + array( + 'bubbleID' => $help_id, + 'dropdownID' => 'phabricator-help-menu', + 'applicationClass' => 'PhabricatorHelpApplication', + 'local' => true, + 'desktop' => true, + 'right' => true, + )); + + $item = id(new PHUIListItemView()) + ->setIcon('fa-life-ring') + ->addClass('core-menu-item') + ->setID($help_id) + ->setOrder(200); + + $hide = true; if ($application) { + $help_name = pht('%s Help', $application->getName()); + $item + ->setName($help_name) + ->setHref('/help/documentation/'.get_class($application).'/') + ->setAural($help_name); $help_items = $application->getHelpMenuItems($user); if ($help_items) { - $help_id = celerity_generate_unique_node_id(); - - Javelin::initBehavior( - 'aphlict-dropdown', - array( - 'bubbleID' => $help_id, - 'dropdownID' => 'phabricator-help-menu', - 'local' => true, - 'desktop' => true, - 'right' => true, - )); - - $help_name = pht('%s Help', $application->getName()); - - $item = id(new PHUIListItemView()) - ->setName($help_name) - ->setIcon('fa-life-ring') - ->setHref('/help/documentation/'.get_class($application).'/') - ->addClass('core-menu-item') - ->setID($help_id) - ->setAural($help_name) - ->setOrder(200); - $items[] = $item; + $hide = false; } } + if ($hide) { + $item->setStyle('display: none'); + } + $items[] = $item; return $items; } @@ -80,14 +88,13 @@ final class PhabricatorHelpApplication extends PhabricatorApplication { return null; } + $view = null; $help_items = $application->getHelpMenuItems($viewer); - if (!$help_items) { - return null; - } - - $view = new PHUIListView(); - foreach ($help_items as $item) { - $view->addMenuItem($item); + if ($help_items) { + $view = new PHUIListView(); + foreach ($help_items as $item) { + $view->addMenuItem($item); + } } return phutil_tag( diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index 5aafc86a37..05981a88f1 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -244,15 +244,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { Javelin::initBehavior( 'dark-console', - array( - // NOTE: We use a generic label here to prevent input reflection - // and mitigate compression attacks like BREACH. See discussion in - // T3684. - 'uri' => pht('Main Request'), - 'selected' => $user ? $user->getConsoleTab() : null, - 'visible' => $user ? (int)$user->getConsoleVisible() : true, - 'headers' => $headers, - )); + $this->getConsoleConfig()); // Change this to initBehavior when there is some behavior to initialize require_celerity_resource('javelin-behavior-error-log'); @@ -533,6 +525,28 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { return $this->getRequest()->getApplicationConfiguration()->getConsole(); } + private function getConsoleConfig() { + $user = $this->getRequest()->getUser(); + + $headers = array(); + if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) { + $headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page'; + } + if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) { + $headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true; + } + + return array( + // NOTE: We use a generic label here to prevent input reflection + // and mitigate compression attacks like BREACH. See discussion in + // T3684. + 'uri' => pht('Main Request'), + 'selected' => $user ? $user->getConsoleTab() : null, + 'visible' => $user ? (int)$user->getConsoleVisible() : true, + 'headers' => $headers, + ); + } + private function renderFooter() { if (!$this->getShowChrome()) { return null; @@ -590,18 +604,42 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { } private function buildQuicksandConfig() { - $user = $this->getRequest()->getUser(); + $viewer = $this->getRequest()->getUser(); $dropdown_query = id(new AphlictDropdownDataQuery()) - ->setViewer($user); + ->setViewer($viewer); $dropdown_query->execute(); + $rendered_dropdowns = array(); + $applications = array( + 'PhabricatorHelpApplication', + ); + foreach ($applications as $application_class) { + if (!PhabricatorApplication::isClassInstalledForViewer( + $application_class, + $viewer)) { + continue; + } + $application = PhabricatorApplication::getByClass($application_class); + $rendered_dropdowns[$application_class] = + $application->buildMainMenuExtraNodes( + $viewer, + $this->getController()); + } + + $console_config = null; + $console = $this->getConsole(); + if ($console) { + $console_config = $this->getConsoleConfig(); + } return array( 'title' => $this->getTitle(), 'aphlictDropdownData' => array( $dropdown_query->getNotificationData(), $dropdown_query->getConpherenceData(), ), + 'aphlictDropdowns' => $rendered_dropdowns, + 'consoleConfig' => $console_config, ) + $this->buildAphlictListenConfigData(); } diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js index 90849d8949..a3f01bfc30 100644 --- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js +++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js @@ -71,11 +71,25 @@ JX.behavior('aphlict-dropdown', function(config, statics) { 'quicksand-redraw', null, function (e) { - if (config.local) { + var data = e.getData(); + if (config.local && config.applicationClass) { + var local_dropdowns = data.newResponse.aphlictDropdowns; + if (local_dropdowns[config.applicationClass]) { + JX.DOM.replace( + dropdown, + JX.$H(local_dropdowns[config.applicationClass])); + dropdown = JX.$(config.dropdownID); + if (dropdown.childNodes.length === 0) { + JX.DOM.hide(bubble); + } else { + JX.DOM.show(bubble); + } + } else { + JX.DOM.hide(bubble); + } return; } - var data = e.getData(); if (!data.fromServer) { return; } diff --git a/webroot/rsrc/js/core/behavior-dark-console.js b/webroot/rsrc/js/core/behavior-dark-console.js index 26c1fc84d7..b7e756efca 100644 --- a/webroot/rsrc/js/core/behavior-dark-console.js +++ b/webroot/rsrc/js/core/behavior-dark-console.js @@ -50,6 +50,19 @@ JX.behavior('dark-console', function(config, statics) { } var root = statics.root || setup_console(); + JX.Stratcom.listen( + 'quicksand-redraw', + null, + function (e) { + e.kill(); + var data = e.getData().newResponse; + console.log(data); + if (data.consoleConfig) { + console.log('hey'); + root = setup_console(); + //add_request(data.consoleConfig); + } + }); config.key = config.key || root.getAttribute('data-console-key');