Skip to content

Commit 93b0a50

Browse files
author
epriestley
committedAug 21, 2012
Add local navigation to Differential
Summary: Adds a flexible navigation menu to diffs that shows you your current position in the diff. Anticipating some "this is the best thing ever" and some "this is the wosrt thing ever" on this, but let's see how much pushback we get? It seems pretty good to me. Test Plan: Will attach screenshots. Reviewers: vrana, btrahan Reviewed By: vrana CC: aran Maniphest Tasks: T1633, T1591 Differential Revision: https://secure.phabricator.com/D3355
1 parent d2fbfaa commit 93b0a50

21 files changed

+376
-159
lines changed
 

‎scripts/celerity_mapper.php

-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@
121121

122122
'differential-inline-comment-editor',
123123
'javelin-behavior-differential-dropdown-menus',
124-
'javelin-behavior-buoyant',
125124
),
126125
'diffusion.pkg.css' => array(
127126
'diffusion-commit-view-css',

‎src/__phutil_library_map__.php

+2
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@
547547
'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php',
548548
'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php',
549549
'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
550+
'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
550551
'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php',
551552
'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php',
552553
'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php',
@@ -1683,6 +1684,7 @@
16831684
'Phabricator404Controller' => 'PhabricatorController',
16841685
'PhabricatorActionListView' => 'AphrontView',
16851686
'PhabricatorActionView' => 'AphrontView',
1687+
'PhabricatorAnchorView' => 'AphrontView',
16861688
'PhabricatorApplicationApplications' => 'PhabricatorApplication',
16871689
'PhabricatorApplicationAudit' => 'PhabricatorApplication',
16881690
'PhabricatorApplicationAuth' => 'PhabricatorApplication',

‎src/applications/differential/controller/DifferentialRevisionViewController.php

+88-3
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public function processRequest() {
194194
array(
195195
'href' => $request_uri
196196
->alter('large', 'true')
197-
->setFragment('differential-review-toc'),
197+
->setFragment('toc'),
198198
),
199199
'Show All Files Inline').
200200
"</strong>");
@@ -395,12 +395,22 @@ public function processRequest() {
395395
PhabricatorFeedStoryNotification::updateObjectNotificationViews(
396396
$user, $revision->getPHID());
397397

398-
return $this->buildStandardPageResponse(
398+
$top_anchor = id(new PhabricatorAnchorView())
399+
->setAnchorName('top')
400+
->setNavigationMarker(true);
401+
402+
$nav = $this->buildSideNavView($revision, $changesets);
403+
$nav->selectFilter('');
404+
$nav->appendChild(
399405
array(
400406
$reviewer_warning,
407+
$top_anchor,
401408
$revision_detail,
402409
$page_pane,
403-
),
410+
));
411+
412+
return $this->buildApplicationPage(
413+
$nav,
404414
array(
405415
'title' => 'D'.$revision->getID().' '.$revision->getTitle(),
406416
));
@@ -996,4 +1006,79 @@ private function buildRawDiffResponse(
9961006
return id(new AphrontRedirectResponse())->setURI($file->getBestURI());
9971007

9981008
}
1009+
1010+
private function buildSideNavView(
1011+
DifferentialRevision $revision,
1012+
array $changesets) {
1013+
1014+
$nav = new AphrontSideNavFilterView();
1015+
$nav->setBaseURI(new PhutilURI('/D'.$revision->getID()));
1016+
$nav->setFlexible(true);
1017+
1018+
$nav->addFilter('top', 'D'.$revision->getID(), '#top',
1019+
$relative = false,
1020+
'phabricator-active-nav-focus');
1021+
1022+
$tree = new PhutilFileTree();
1023+
foreach ($changesets as $changeset) {
1024+
$tree->addPath($changeset->getFilename(), $changeset);
1025+
}
1026+
1027+
require_celerity_resource('phabricator-filetree-view-css');
1028+
1029+
$filetree = array();
1030+
1031+
$path = $tree;
1032+
while (($path = $path->getNextNode())) {
1033+
$data = $path->getData();
1034+
1035+
$name = $path->getName();
1036+
$style = 'padding-left: '.(2 + (3 * $path->getDepth())).'px';
1037+
1038+
$href = null;
1039+
if ($data) {
1040+
$href = '#'.$data->getAnchorName();
1041+
$icon = 'phabricator-filetree-icon-file';
1042+
} else {
1043+
$name .= '/';
1044+
$icon = 'phabricator-filetree-icon-dir';
1045+
}
1046+
1047+
$icon = phutil_render_tag(
1048+
'span',
1049+
array(
1050+
'class' => 'phabricator-filetree-icon '.$icon,
1051+
),
1052+
'');
1053+
1054+
$name_element = phutil_render_tag(
1055+
'span',
1056+
array(
1057+
'class' => 'phabricator-filetree-name',
1058+
),
1059+
phutil_escape_html($name));
1060+
1061+
$filetree[] = javelin_render_tag(
1062+
$href ? 'a' : 'span',
1063+
array(
1064+
'href' => $href,
1065+
'style' => $style,
1066+
'title' => $name,
1067+
'class' => 'phabricator-filetree-item',
1068+
),
1069+
$icon.$name_element);
1070+
}
1071+
$tree->destroy();
1072+
1073+
$filetree =
1074+
'<div class="phabricator-filetree">'.
1075+
implode("\n", $filetree).
1076+
'</div>';
1077+
$nav->addFilter('toc', 'Table of Contents', '#toc');
1078+
$nav->addCustomBlock($filetree);
1079+
$nav->addFilter('comment', 'Add Comment', '#comment');
1080+
$nav->setActive(true);
1081+
1082+
return $nav;
1083+
}
9991084
}

‎src/applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public function renderValueForMail($phase) {
118118
$body[] = null;
119119
$body[] = 'CHANGE SINCE LAST DIFF';
120120
$body[] = ' '.PhabricatorEnv::getProductionURI(
121-
"/D{$this->id}?vs={$old}&id={$new}#differential-review-toc");
121+
"/D{$this->id}?vs={$old}&id={$new}#toc");
122122
}
123123
}
124124

‎src/applications/differential/view/DifferentialAddCommentView.php

+4
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ public function render() {
203203
$panel_view->addClass('aphront-panel-flush');
204204

205205
return
206+
id(new PhabricatorAnchorView())
207+
->setAnchorName('comment')
208+
->setNavigationMarker(true)
209+
->render().
206210
'<div class="differential-add-comment-panel">'.
207211
$panel_view->render().
208212
'<div class="aphront-panel-preview aphront-panel-flush">'.

‎src/applications/differential/view/DifferentialChangesetDetailView.php

+5-30
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ public function render() {
9393

9494
$display_filename = $changeset->getDisplayFilename();
9595

96-
$buoyant_begin = $this->renderBuoyant($display_filename);
97-
$buoyant_end = $this->renderBuoyant(null);
98-
9996
$output = javelin_render_tag(
10097
'div',
10198
array(
@@ -109,39 +106,17 @@ public function render() {
109106
'class' => $class,
110107
'id' => $id,
111108
),
112-
$buoyant_begin.
113-
phutil_render_tag(
114-
'a',
115-
array(
116-
'name' => $changeset->getAnchorName(),
117-
),
118-
'').
109+
id(new PhabricatorAnchorView())
110+
->setAnchorName($changeset->getAnchorName())
111+
->setNavigationMarker(true)
112+
->render().
119113
$buttons.
120114
'<h1>'.phutil_escape_html($display_filename).'</h1>'.
121115
'<div style="clear: both;"></div>'.
122-
$this->renderChildren().
123-
$buoyant_end);
116+
$this->renderChildren());
124117

125118

126119
return $output;
127120
}
128121

129-
private function renderBuoyant($text) {
130-
return javelin_render_tag(
131-
'div',
132-
array(
133-
'sigil' => 'buoyant',
134-
'meta' => array(
135-
'text' => $text,
136-
),
137-
'style' => ($text === null)
138-
// Current CSS spacing rules cause the "end" anchor to appear too
139-
// late in the display document. Shift it up a bit so we drop the
140-
// buoyant header sooner. This reduces confusion when using keystroke
141-
// navigation.
142-
? 'bottom: 60px; position: absolute;'
143-
: null,
144-
),
145-
'');
146-
}
147122
}

‎src/applications/differential/view/DifferentialChangesetListView.php

-4
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,6 @@ public function render() {
110110

111111
$changesets = $this->changesets;
112112

113-
// TODO: Restore this once we make it through the redesign, it has funky
114-
// interactions with things and there are various reports that it's slow.
115-
// Javelin::initBehavior('buoyant', array());
116-
117113
Javelin::initBehavior('differential-toggle-files', array());
118114

119115
$output = array();

‎src/applications/differential/view/DifferentialDiffTableOfContentsView.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,11 @@ public function render() {
222222
);
223223

224224
return
225-
'<div id="differential-review-toc" '.
226-
'class="differential-toc differential-panel">'.
225+
id(new PhabricatorAnchorView())
226+
->setAnchorName('toc')
227+
->setNavigationMarker(true)
228+
->render().
229+
'<div class="differential-toc differential-panel">'.
227230
$editor_link.
228231
$reveal_link.
229232
'<h1>Table of Contents</h1>'.

‎src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public function render() {
216216
return
217217
'<div class="differential-revision-history differential-panel">'.
218218
'<h1>Revision Update History</h1>'.
219-
'<form action="#differential-review-toc">'.
219+
'<form action="#toc">'.
220220
'<table class="differential-revision-history-table">'.
221221
'<tr>'.
222222
'<th>Diff</th>'.

‎src/applications/diffusion/controller/DiffusionCommitController.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public function processRequest() {
182182
} else {
183183
$change_panel = new AphrontPanelView();
184184
$change_panel->setHeader("Changes (".number_format($count).")");
185-
$change_panel->setID('differential-review-toc');
185+
$change_panel->setID('toc');
186186

187187
if ($count > self::CHANGES_LIMIT) {
188188
$show_all_button = phutil_render_tag(

‎src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ final protected function updateCommitData($author, $message,
162162
'/D'.$revision->getID().
163163
'?vs='.$vs_diff->getID().
164164
'&id='.$diff->getID().
165-
'#differential-review-toc');
165+
'#toc');
166166
$editor->setChangedByCommit($changed_by_commit);
167167
}
168168

‎src/view/layout/AphrontSideNavFilterView.php

+15
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ final class AphrontSideNavFilterView extends AphrontView {
4545
private $showApplicationMenu;
4646
private $user;
4747
private $currentApplication;
48+
private $active;
49+
50+
public function setActive($active) {
51+
$this->active = $active;
52+
return $this;
53+
}
4854

4955
public function setCurrentApplication(PhabricatorApplication $current) {
5056
$this->currentApplication = $current;
@@ -102,6 +108,11 @@ public function addFilters(array $views) {
102108
}
103109
}
104110

111+
public function addCustomBlock($block) {
112+
$this->items[] = array('custom', null, $block);
113+
return $this;
114+
}
115+
105116
public function addLabel($name) {
106117
$this->items[] = array('label', null, $name);
107118
return $this;
@@ -150,6 +161,7 @@ public function render() {
150161
$view->setFlexNav($this->flexNav);
151162
$view->setFlexible($this->flexible);
152163
$view->setShowApplicationMenu($this->showApplicationMenu);
164+
$view->setActive($this->active);
153165
if ($this->user) {
154166
$view->setUser($this->user);
155167
}
@@ -159,6 +171,9 @@ public function render() {
159171
foreach ($this->items as $item) {
160172
list($type, $key, $name) = $item;
161173
switch ($type) {
174+
case 'custom':
175+
$view->addNavItem($name);
176+
break;
162177
case 'spacer':
163178
$view->addNavItem('<br />');
164179
break;

‎src/view/layout/AphrontSideNavView.php

+14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ final class AphrontSideNavView extends AphrontView {
2424
private $showApplicationMenu;
2525
private $user;
2626
private $currentApplication;
27+
private $active;
2728

2829
public function setUser(PhabricatorUser $user) {
2930
$this->user = $user;
@@ -55,6 +56,11 @@ public function setFlexible($flexible) {
5556
return $this;
5657
}
5758

59+
public function setActive($active) {
60+
$this->active = $active;
61+
return $this;
62+
}
63+
5864
public function render() {
5965
$view = new AphrontNullView();
6066
$view->appendChild($this->items);
@@ -153,6 +159,14 @@ public function render() {
153159
'collapseKey' => $key,
154160
));
155161

162+
if ($this->active && $local_id) {
163+
Javelin::initBehavior(
164+
'phabricator-active-nav',
165+
array(
166+
'localID' => $local_id,
167+
));
168+
}
169+
156170
$header_part =
157171
'<div class="phabricator-nav-head">'.
158172
'<div class="phabricator-nav-head-tablet">'.

0 commit comments

Comments
 (0)
Failed to load comments.