Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14036866
D20353.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D20353.diff
View Options
diff --git a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
--- a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
+++ b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
@@ -54,6 +54,11 @@
->setProfileObject($favorites)
->setCustomPHID($viewer->getPHID());
+ $controller = $this->getController();
+ if ($controller) {
+ $menu_engine->setController($controller);
+ }
+
$filter_view = $menu_engine->buildNavigation();
$menu_view = $filter_view->getMenu();
diff --git a/src/applications/home/controller/PhabricatorHomeController.php b/src/applications/home/controller/PhabricatorHomeController.php
--- a/src/applications/home/controller/PhabricatorHomeController.php
+++ b/src/applications/home/controller/PhabricatorHomeController.php
@@ -31,6 +31,7 @@
$engine = id(new PhabricatorHomeProfileMenuEngine())
->setViewer($viewer)
+ ->setController($this)
->setProfileObject($home)
->setCustomPHID($viewer->getPHID());
diff --git a/src/applications/project/controller/PhabricatorProjectBoardController.php b/src/applications/project/controller/PhabricatorProjectBoardController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardController.php
@@ -1,14 +1,4 @@
<?php
abstract class PhabricatorProjectBoardController
- extends PhabricatorProjectController {
-
- protected function getProfileMenu() {
- $menu = parent::getProfileMenu();
-
- $menu->selectFilter(PhabricatorProject::ITEM_WORKBOARD);
- $menu->addClass('project-board-nav');
-
- return $menu;
- }
-}
+ extends PhabricatorProjectController {}
diff --git a/src/applications/project/controller/PhabricatorProjectBoardViewController.php b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardViewController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
@@ -172,8 +172,7 @@
return $content;
}
- $nav = $this->getProfileMenu();
- $nav->selectFilter(PhabricatorProject::ITEM_WORKBOARD);
+ $nav = $this->newWorkboardProfileMenu();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'));
@@ -720,7 +719,7 @@
->appendChild($board)
->addClass('project-board-wrapper');
- $nav = $this->getProfileMenu();
+ $nav = $this->newWorkboardProfileMenu();
$divider = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_DIVIDER);
@@ -1504,4 +1503,15 @@
->addCancelButton($profile_uri);
}
+ private function newWorkboardProfileMenu() {
+ $default_item = id(new PhabricatorProfileMenuItemConfiguration())
+ ->setBuiltinKey(PhabricatorProject::ITEM_WORKBOARD);
+
+ $menu = parent::getProfileMenu($default_item);
+
+ $menu->addClass('project-board-nav');
+
+ return $menu;
+ }
+
}
diff --git a/src/applications/project/controller/PhabricatorProjectController.php b/src/applications/project/controller/PhabricatorProjectController.php
--- a/src/applications/project/controller/PhabricatorProjectController.php
+++ b/src/applications/project/controller/PhabricatorProjectController.php
@@ -97,11 +97,11 @@
return $menu;
}
- protected function getProfileMenu() {
+ protected function getProfileMenu($default_item = null) {
if (!$this->profileMenu) {
$engine = $this->getProfileMenuEngine();
if ($engine) {
- $this->profileMenu = $engine->buildNavigation();
+ $this->profileMenu = $engine->buildNavigation($default_item);
}
}
diff --git a/src/applications/search/engine/PhabricatorProfileMenuEngine.php b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
--- a/src/applications/search/engine/PhabricatorProfileMenuEngine.php
+++ b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
@@ -183,7 +183,7 @@
break;
}
- $navigation = $this->buildNavigation();
+ $navigation = $this->buildNavigation($selected_item);
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
@@ -223,8 +223,6 @@
switch ($item_action) {
case 'view':
if ($selected_item) {
- $navigation->selectFilter($selected_item->getDefaultMenuItemKey());
-
try {
$content = $this->buildItemViewContent($selected_item);
} catch (Exception $ex) {
@@ -335,7 +333,9 @@
return $page;
}
- public function buildNavigation() {
+ public function buildNavigation(
+ PhabricatorProfileMenuItemConfiguration $selected_item = null) {
+
if ($this->navigation) {
return $this->navigation;
}
@@ -398,6 +398,12 @@
$nav->selectFilter(null);
+ $navigation_items = $nav->getMenu()->getItems();
+ $select_key = $this->pickHighlightedMenuItem(
+ $navigation_items,
+ $selected_item);
+ $nav->selectFilter($select_key);
+
$this->navigation = $nav;
return $this->navigation;
}
@@ -1367,4 +1373,97 @@
return null;
}
+ private function pickHighlightedMenuItem(
+ array $items,
+ PhabricatorProfileMenuItemConfiguration $selected_item = null) {
+
+ assert_instances_of($items, 'PHUIListItemView');
+
+ $default_key = null;
+ if ($selected_item) {
+ $default_key = $selected_item->getDefaultMenuItemKey();
+ }
+
+ $controller = $this->getController();
+
+ // In some rare cases, when like building the "Favorites" menu on a
+ // 404 page, we may not have a controller. Just accept whatever default
+ // behavior we'd otherwise end up with.
+ if (!$controller) {
+ return $default_key;
+ }
+
+ $request = $controller->getRequest();
+
+ // See T12949. If one of the menu items is a link to the same URI that
+ // the page was accessed with, we want to highlight that item. For example,
+ // this allows you to add links to a menu that apply filters to a
+ // workboard.
+
+ $matches = array();
+ foreach ($items as $item) {
+ $href = $item->getHref();
+ if ($this->isMatchForRequestURI($request, $href)) {
+ $matches[] = $item;
+ }
+ }
+
+ foreach ($matches as $match) {
+ if ($match->getKey() === $default_key) {
+ return $default_key;
+ }
+ }
+
+ if ($matches) {
+ return head($matches)->getKey();
+ }
+
+ return $default_key;
+ }
+
+ private function isMatchForRequestURI(AphrontRequest $request, $item_uri) {
+ $request_uri = $request->getAbsoluteRequestURI();
+ $item_uri = new PhutilURI($item_uri);
+
+ // If the request URI and item URI don't have matching paths, they
+ // do not match.
+ if ($request_uri->getPath() !== $item_uri->getPath()) {
+ return false;
+ }
+
+ // If the request URI and item URI don't have matching parameters, they
+ // also do not match. We're specifically trying to let "?filter=X" work
+ // on Workboards, among other use cases, so this is important.
+ $request_params = $request_uri->getQueryParamsAsPairList();
+ $item_params = $item_uri->getQueryParamsAsPairList();
+ if ($request_params !== $item_params) {
+ return false;
+ }
+
+ // If the paths and parameters match, the item domain must be: empty; or
+ // match the request domain; or match the production domain.
+
+ $request_domain = $request_uri->getDomain();
+
+ $production_uri = PhabricatorEnv::getProductionURI('/');
+ $production_domain = id(new PhutilURI($production_uri))
+ ->getDomain();
+
+ $allowed_domains = array(
+ '',
+ $request_domain,
+ $production_domain,
+ );
+ $allowed_domains = array_fuse($allowed_domains);
+
+ $item_domain = $item_uri->getDomain();
+ $item_domain = (string)$item_domain;
+
+ if (isset($allowed_domains[$item_domain])) {
+ return true;
+ }
+
+ return false;
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 11, 12:38 PM (1 w, 5 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6730902
Default Alt Text
D20353.diff (7 KB)
Attached To
Mode
D20353: When a ProfileMenu has a link item that adds URI parameters, highlight it when clicked
Attached
Detach File
Event Timeline
Log In to Comment