Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15414295
D13908.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D13908.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1362,6 +1362,8 @@
'PHUIDiffInlineCommentView' => 'infrastructure/diff/view/PHUIDiffInlineCommentView.php',
'PHUIDiffOneUpInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffOneUpInlineCommentRowScaffold.php',
'PHUIDiffRevealIconView' => 'infrastructure/diff/view/PHUIDiffRevealIconView.php',
+ 'PHUIDiffTableOfContentsItemView' => 'infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php',
+ 'PHUIDiffTableOfContentsListView' => 'infrastructure/diff/view/PHUIDiffTableOfContentsListView.php',
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffTwoUpInlineCommentRowScaffold.php',
'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php',
'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php',
@@ -5157,6 +5159,8 @@
'PHUIDiffInlineCommentView' => 'AphrontView',
'PHUIDiffOneUpInlineCommentRowScaffold' => 'PHUIDiffInlineCommentRowScaffold',
'PHUIDiffRevealIconView' => 'AphrontView',
+ 'PHUIDiffTableOfContentsItemView' => 'AphrontView',
+ 'PHUIDiffTableOfContentsListView' => 'AphrontView',
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'PHUIDiffInlineCommentRowScaffold',
'PHUIDocumentExample' => 'PhabricatorUIExample',
'PHUIDocumentView' => 'AphrontTagView',
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -349,16 +349,10 @@
$other_view = $this->renderOtherRevisions($other_revisions);
}
- $toc_view = new DifferentialDiffTableOfContentsView();
- $toc_view->setChangesets($changesets);
- $toc_view->setVisibleChangesets($visible_changesets);
- $toc_view->setRenderingReferences($rendering_references);
- $toc_view->setCoverageMap($target->loadCoverageMap($user));
- if ($repository) {
- $toc_view->setRepository($repository);
- }
- $toc_view->setDiff($target);
- $toc_view->setUser($user);
+ $toc_view = $this->buildTableOfContents(
+ $changesets,
+ $visible_changesets,
+ $target->loadCoverageMap($user));
$comment_form = null;
if (!$viewer_is_anonymous) {
@@ -1042,5 +1036,34 @@
return $view;
}
+ private function buildTableOfContents(
+ array $changesets,
+ array $visible_changesets,
+ array $coverage) {
+ $viewer = $this->getViewer();
+
+ $toc_view = id(new PHUIDiffTableOfContentsListView())
+ ->setUser($viewer);
+
+ foreach ($changesets as $changeset_id => $changeset) {
+ $is_visible = isset($visible_changesets[$changeset_id]);
+ $anchor = $changeset->getAnchorName();
+
+ $filename = $changeset->getFilename();
+ $coverage_id = 'differential-mcoverage-'.md5($filename);
+
+ $item = id(new PHUIDiffTableOfContentsItemView())
+ ->setChangeset($changeset)
+ ->setIsVisible($is_visible)
+ ->setAnchor($anchor)
+ ->setCoverage(idx($coverage, $filename))
+ ->setCoverageID($coverage_id);
+
+ $toc_view->addItem($item);
+ }
+
+ return $toc_view;
+ }
+
}
diff --git a/src/infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php b/src/infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php
@@ -0,0 +1,295 @@
+<?php
+
+final class PHUIDiffTableOfContentsItemView extends AphrontView {
+
+ private $changeset;
+ private $isVisible;
+ private $anchor;
+ private $coverage;
+ private $coverageID;
+
+ public function setChangeset(DifferentialChangeset $changeset) {
+ $this->changeset = $changeset;
+ return $this;
+ }
+
+ public function getChangeset() {
+ return $this->changeset;
+ }
+
+ public function setIsVisible($is_visible) {
+ $this->isVisible = $is_visible;
+ return $this;
+ }
+
+ public function getIsVisible() {
+ return $this->isVisible;
+ }
+
+ public function setAnchor($anchor) {
+ $this->anchor = $anchor;
+ return $this;
+ }
+
+ public function getAnchor() {
+ return $this->anchor;
+ }
+
+ public function setCoverage($coverage) {
+ $this->coverage = $coverage;
+ return $this;
+ }
+
+ public function getCoverage() {
+ return $this->coverage;
+ }
+
+ public function setCoverageID($coverage_id) {
+ $this->coverageID = $coverage_id;
+ return $this;
+ }
+
+ public function getCoverageID() {
+ return $this->coverageID;
+ }
+
+ public function render() {
+ $changeset = $this->getChangeset();
+
+ $cells = array();
+
+ $cells[] = $this->renderPathChangeCharacter();
+ $cells[] = $this->renderPropertyChangeCharacter();
+ $cells[] = $this->renderPropertyChangeDescription();
+
+ $link = $this->renderChangesetLink();
+ $lines = $this->renderChangesetLines();
+ $meta = $this->renderChangesetMetadata();
+
+ $cells[] = array(
+ $link,
+ $lines,
+ $meta,
+ );
+
+ $cells[] = $this->renderCoverage();
+ $cells[] = $this->renderModifiedCoverage();
+
+ return $cells;
+ }
+
+ private function renderPathChangeCharacter() {
+ $changeset = $this->getChangeset();
+ $type = $changeset->getChangeType();
+
+ $color = DifferentialChangeType::getSummaryColorForChangeType($type);
+ $char = DifferentialChangeType::getSummaryCharacterForChangeType($type);
+ $title = DifferentialChangeType::getFullNameForChangeType($type);
+
+ return javelin_tag(
+ 'span',
+ array(
+ 'sigil' => 'has-tip',
+ 'meta' => array(
+ 'tip' => $title,
+ 'align' => 'E',
+ ),
+ 'class' => 'phui-text-'.$color,
+ ),
+ $char);
+ }
+
+ private function renderPropertyChangeCharacter() {
+ $changeset = $this->getChangeset();
+
+ $old = $changeset->getOldProperties();
+ $new = $changeset->getNewProperties();
+
+ if ($old === $new) {
+ return null;
+ }
+
+ return javelin_tag(
+ 'span',
+ array(
+ 'sigil' => 'has-tip',
+ 'meta' => array(
+ 'tip' => pht('Properties Modified'),
+ 'align' => 'E',
+ ),
+ ),
+ 'M');
+ }
+
+ private function renderPropertyChangeDescription() {
+ $changeset = $this->getChangeset();
+
+ $file_type = $changeset->getFileType();
+
+ $desc = DifferentialChangeType::getShortNameForFileType($file_type);
+ if ($desc === null) {
+ return null;
+ }
+
+ return pht('(%s)', $desc);
+ }
+
+ private function renderChangesetLink() {
+ $anchor = $this->getAnchor();
+
+ $changeset = $this->getChangeset();
+ $name = $changeset->getDisplayFilename();
+
+ $change_type = $changeset->getChangeType();
+ if (DifferentialChangeType::isOldLocationChangeType($change_type)) {
+ $away = $changeset->getAwayPaths();
+ if (count($away) == 1) {
+ if ($change_type == DifferentialChangeType::TYPE_MOVE_AWAY) {
+ $right_arrow = "\xE2\x86\x92";
+ $name = $this->renderRename($name, head($away), $right_arrow);
+ }
+ }
+ } else if ($change_type == DifferentialChangeType::TYPE_MOVE_HERE) {
+ $left_arrow = "\xE2\x86\x90";
+ $name = $this->renderRename($name, $changeset->getOldFile(), $left_arrow);
+ }
+
+ return javelin_tag(
+ 'a',
+ array(
+ 'href' => '#'.$anchor,
+ 'sigil' => 'differential-load',
+ 'meta' => array(
+ 'id' => 'diff-'.$anchor,
+ ),
+ ),
+ $name);
+ }
+
+ private function renderChangesetLines() {
+ $changeset = $this->getChangeset();
+
+ $line_count = $changeset->getAffectedLineCount();
+ if (!$line_count) {
+ return null;
+ }
+
+ return ' '.pht('(%d line(s))', $line_count);
+ }
+
+ private function renderCoverage() {
+ $not_applicable = '-';
+
+ $coverage = $this->getCoverage();
+ if (!strlen($coverage)) {
+ return $not_applicable;
+ }
+
+ $covered = substr_count($coverage, 'C');
+ $not_covered = substr_count($coverage, 'U');
+
+ if (!$not_covered && !$covered) {
+ return $not_applicable;
+ }
+
+ return sprintf('%d%%', 100 * ($covered / ($covered + $not_covered)));
+ }
+
+ private function renderModifiedCoverage() {
+ $not_applicable = '-';
+
+ $coverage = $this->getCoverage();
+ if (!strlen($coverage)) {
+ return $not_applicable;
+ }
+
+ if ($this->getIsVisible()) {
+ $label = pht('Loading...');
+ } else {
+ $label = pht('?');
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'id' => $this->getCoverageID(),
+ 'class' => 'differential-mcoverage-loading',
+ ),
+ $label);
+ }
+
+ private function renderChangesetMetadata() {
+ $changeset = $this->getChangeset();
+ $type = $changeset->getChangeType();
+
+ $meta = array();
+ if (DifferentialChangeType::isOldLocationChangeType($type)) {
+ $away = $changeset->getAwayPaths();
+ if (count($away) > 1) {
+ if ($type == DifferentialChangeType::TYPE_MULTICOPY) {
+ $meta[] = pht('Deleted after being copied to multiple locations:');
+ } else {
+ $meta[] = pht('Copied to multiple locations:');
+ }
+ foreach ($away as $path) {
+ $meta[] = $path;
+ }
+ } else {
+ if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) {
+ // This case is handled when we render the path.
+ } else {
+ $meta[] = pht('Copied to %s', head($away));
+ }
+ }
+ } else if ($type == DifferentialChangeType::TYPE_COPY_HERE) {
+ $meta = pht('Copied from %s', $changeset->getOldFile());
+ }
+
+ if (!$meta) {
+ return null;
+ }
+
+ $meta = phutil_implode_html(phutil_tag('br'), $meta);
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'differential-toc-meta',
+ ),
+ $meta);
+ }
+
+ private function renderRename($self, $other, $arrow) {
+ $old = explode('/', $self);
+ $new = explode('/', $other);
+
+ $start = count($old);
+ foreach ($old as $index => $part) {
+ if (!isset($new[$index]) || $part != $new[$index]) {
+ $start = $index;
+ break;
+ }
+ }
+
+ $end = count($old);
+ foreach (array_reverse($old) as $from_end => $part) {
+ $index = count($new) - $from_end - 1;
+ if (!isset($new[$index]) || $part != $new[$index]) {
+ $end = $from_end;
+ break;
+ }
+ }
+
+ $rename =
+ '{'.
+ implode('/', array_slice($old, $start, count($old) - $end - $start)).
+ ' '.$arrow.' '.
+ implode('/', array_slice($new, $start, count($new) - $end - $start)).
+ '}';
+
+ array_splice($new, $start, count($new) - $end - $start, $rename);
+
+ return implode('/', $new);
+ }
+
+}
diff --git a/src/infrastructure/diff/view/PHUIDiffTableOfContentsListView.php b/src/infrastructure/diff/view/PHUIDiffTableOfContentsListView.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/diff/view/PHUIDiffTableOfContentsListView.php
@@ -0,0 +1,80 @@
+<?php
+
+final class PHUIDiffTableOfContentsListView extends AphrontView {
+
+ private $items = array();
+
+ public function addItem(PHUIDiffTableOfContentsItemView $item) {
+ $this->items[] = $item;
+ return $this;
+ }
+
+ public function render() {
+ $this->requireResource('differential-core-view-css');
+ $this->requireResource('differential-table-of-contents-css');
+ $this->requireResource('phui-text-css');
+
+ $items = $this->items;
+
+ $rows = array();
+ foreach ($items as $item) {
+ $rows[] = $item->render();
+ }
+
+ $reveal_link = javelin_tag(
+ 'a',
+ array(
+ 'sigil' => 'differential-reveal-all',
+ 'mustcapture' => true,
+ 'class' => 'button differential-toc-reveal-all',
+ ),
+ pht('Show All Context'));
+
+ $buttons = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'differential-toc-buttons grouped',
+ ),
+ $reveal_link);
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ '',
+ '',
+ '',
+ pht('Path'),
+ pht('Coverage (All)'),
+ pht('Coverage (Touched)'),
+ ))
+ ->setColumnClasses(
+ array(
+ 'differential-toc-char center',
+ 'differential-toc-prop center',
+ 'differential-toc-ftype center',
+ 'differential-toc-file wide',
+ 'differential-toc-cov',
+ 'differential-toc-cov',
+ ))
+ ->setDeviceVisibility(
+ array(
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ ));
+
+ $anchor = id(new PhabricatorAnchorView())
+ ->setAnchorName('toc')
+ ->setNavigationMarker(true);
+
+ return id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Table of Contents'))
+ ->setTable($table)
+ ->appendChild($anchor)
+ ->appendChild($buttons);
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 21, 12:02 AM (1 d, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7714657
Default Alt Text
D13908.diff (13 KB)
Attached To
Mode
D13908: Convert DifferentialRevision view to new PHUIDiffTableOfContentsListView
Attached
Detach File
Event Timeline
Log In to Comment