2011-07-17 11:06:02 -07:00
|
|
|
<?php
|
|
|
|
|
2014-07-10 08:12:48 +10:00
|
|
|
final class PhrictionDiffController extends PhrictionController {
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
2014-11-07 15:36:58 -08:00
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->id = $data['id'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
2014-05-19 12:41:12 -07:00
|
|
|
$document = id(new PhrictionDocumentQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withIDs(array($this->id))
|
|
|
|
->needContent(true)
|
|
|
|
->executeOne();
|
2011-07-17 11:06:02 -07:00
|
|
|
if (!$document) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
2014-05-19 12:41:12 -07:00
|
|
|
$current = $document->getContent();
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
$l = $request->getInt('l');
|
|
|
|
$r = $request->getInt('r');
|
|
|
|
|
|
|
|
$ref = $request->getStr('ref');
|
|
|
|
if ($ref) {
|
|
|
|
list($l, $r) = explode(',', $ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
$content = id(new PhrictionContent())->loadAllWhere(
|
|
|
|
'documentID = %d AND version IN (%Ld)',
|
|
|
|
$document->getID(),
|
|
|
|
array($l, $r));
|
|
|
|
$content = mpull($content, null, 'getVersion');
|
|
|
|
|
|
|
|
$content_l = idx($content, $l, null);
|
|
|
|
$content_r = idx($content, $r, null);
|
|
|
|
|
|
|
|
if (!$content_l || !$content_r) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$text_l = $content_l->getContent();
|
|
|
|
$text_r = $content_r->getContent();
|
|
|
|
|
2013-02-28 09:17:58 -08:00
|
|
|
$text_l = phutil_utf8_hard_wrap($text_l, 80);
|
2013-03-03 11:37:45 -08:00
|
|
|
$text_l = implode("\n", $text_l);
|
2013-02-28 09:17:58 -08:00
|
|
|
$text_r = phutil_utf8_hard_wrap($text_r, 80);
|
2013-03-03 11:37:45 -08:00
|
|
|
$text_r = implode("\n", $text_r);
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
$engine = new PhabricatorDifferenceEngine();
|
|
|
|
$changeset = $engine->generateChangesetFromFileContent($text_l, $text_r);
|
|
|
|
|
2015-03-05 14:02:45 -08:00
|
|
|
$changeset->setFilename($content_r->getTitle());
|
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
$changeset->setOldProperties(
|
|
|
|
array(
|
|
|
|
'Title' => $content_l->getTitle(),
|
|
|
|
));
|
|
|
|
$changeset->setNewProperties(
|
|
|
|
array(
|
|
|
|
'Title' => $content_r->getTitle(),
|
|
|
|
));
|
|
|
|
|
|
|
|
$whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
|
|
|
|
|
2015-03-08 06:02:47 -07:00
|
|
|
$parser = id(new DifferentialChangesetParser())
|
|
|
|
->setUser($user)
|
|
|
|
->setChangeset($changeset)
|
|
|
|
->setRenderingReference("{$l},{$r}");
|
|
|
|
|
|
|
|
$parser->readParametersFromRequest($request);
|
2011-07-17 11:06:02 -07:00
|
|
|
$parser->setWhitespaceMode($whitespace_mode);
|
|
|
|
|
2012-12-08 17:35:34 -08:00
|
|
|
$engine = new PhabricatorMarkupEngine();
|
|
|
|
$engine->setViewer($user);
|
|
|
|
$engine->process();
|
|
|
|
$parser->setMarkupEngine($engine);
|
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
$spec = $request->getStr('range');
|
|
|
|
list($range_s, $range_e, $mask) =
|
|
|
|
DifferentialChangesetParser::parseRangeSpecification($spec);
|
2015-03-05 14:02:45 -08:00
|
|
|
|
2015-03-08 06:02:47 -07:00
|
|
|
$parser->setRange($range_s, $range_e);
|
|
|
|
$parser->setMask($mask);
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
if ($request->isAjax()) {
|
2012-03-12 21:39:05 -07:00
|
|
|
return id(new PhabricatorChangesetResponse())
|
2015-03-08 06:02:47 -07:00
|
|
|
->setRenderedChangeset($parser->renderChangeset());
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
2015-03-08 06:02:47 -07:00
|
|
|
$changes = id(new DifferentialChangesetListView())
|
2015-03-05 14:02:45 -08:00
|
|
|
->setUser($this->getViewer())
|
2015-03-08 06:02:47 -07:00
|
|
|
->setChangesets(array($changeset))
|
|
|
|
->setVisibleChangesets(array($changeset))
|
|
|
|
->setRenderingReferences(array("{$l},{$r}"))
|
Make "Show Context" persist rendering, whitespace, encoding, etc
Summary:
Ref T2009. Currently, we do not persist view parameters when making context rendering requests.
The big one is the renderer (1up vs 2up). This makes context on unified diffs come in with too many columns.
However, it impacts other parameters too. For example, at HEAD, if you change highlighting to "rainbow" and then load more context, the context uses the original highlighter instead of the rainbow highlighter.
This moves context loads into ChangesetViewManager, which maintains view parameters and can provide them correctly.
- This removes "ref"; it is no longer required, as the ChangesetViewManager tracks it.
- This removes URI management from `behavior-show-more`; it is no longer required, since the ChangesetViewManager knows how to render.
- This removes "whitespace" since this is handled properly by the view manager.
Test Plan:
- Used "Show Top" / "Show All" / "Show Bottom" in 1-up and 2-up views.
- Changed file highlighting to rainbow, loaded stuff, saw rainbow stick.
- Used "Show Entire File" in 1-up and 2-up views.
- Saw loading chrome.
- No loading chrome normally.
- Made inlines, verified `copyRows()` code runs.
- Poked around Diffusion -- it is missing some parameter handling, but works OK.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T2009
Differential Revision: https://secure.phabricator.com/D11977
2015-03-05 14:03:00 -08:00
|
|
|
->setRenderURI('/phriction/diff/'.$document->getID().'/')
|
2015-03-08 06:02:47 -07:00
|
|
|
->setTitle(pht('Changes'))
|
|
|
|
->setParser($parser);
|
2015-03-05 14:02:45 -08:00
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
require_celerity_resource('phriction-document-css');
|
|
|
|
|
|
|
|
$slug = $document->getSlug();
|
|
|
|
|
|
|
|
$revert_l = $this->renderRevertButton($content_l, $current);
|
|
|
|
$revert_r = $this->renderRevertButton($content_r, $current);
|
|
|
|
|
2013-03-13 15:15:58 -07:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumb_views = $this->renderBreadcrumbs($slug);
|
|
|
|
foreach ($crumb_views as $view) {
|
|
|
|
$crumbs->addCrumb($view);
|
|
|
|
}
|
|
|
|
|
2013-12-18 17:47:34 -08:00
|
|
|
$crumbs->addTextCrumb(
|
|
|
|
pht('History'),
|
|
|
|
PhrictionDocument::getSlugURI($slug, 'history'));
|
2013-03-13 15:15:58 -07:00
|
|
|
|
2014-06-09 11:36:49 -07:00
|
|
|
$title = pht('Version %s vs %s', $l, $r);
|
2013-03-13 15:15:58 -07:00
|
|
|
|
2013-09-17 09:12:37 -07:00
|
|
|
$header = id(new PHUIHeaderView())
|
2013-03-13 15:15:58 -07:00
|
|
|
->setHeader($title);
|
|
|
|
|
2013-12-18 17:47:34 -08:00
|
|
|
$crumbs->addTextCrumb($title, $request->getRequestURI());
|
2013-03-13 15:15:58 -07:00
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
$comparison_table = $this->renderComparisonTable(
|
|
|
|
array(
|
|
|
|
$content_r,
|
|
|
|
$content_l,
|
|
|
|
));
|
|
|
|
|
|
|
|
$navigation_table = null;
|
|
|
|
if ($l + 1 == $r) {
|
|
|
|
$nav_l = ($l > 1);
|
|
|
|
$nav_r = ($r != $current->getVersion());
|
|
|
|
|
|
|
|
$uri = $request->getRequestURI();
|
|
|
|
|
|
|
|
if ($nav_l) {
|
2013-01-17 18:57:09 -08:00
|
|
|
$link_l = phutil_tag(
|
2011-07-17 11:06:02 -07:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $uri->alter('l', $l - 1)->alter('r', $r - 1),
|
2013-10-29 16:06:13 -07:00
|
|
|
'class' => 'button',
|
2011-07-17 11:06:02 -07:00
|
|
|
),
|
2013-02-08 09:54:27 -08:00
|
|
|
pht("\xC2\xAB Previous Change"));
|
2011-07-17 11:06:02 -07:00
|
|
|
} else {
|
2013-10-29 16:06:13 -07:00
|
|
|
$link_l = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '#',
|
|
|
|
'class' => 'button grey disabled',
|
|
|
|
),
|
|
|
|
pht('Original Change'));
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
$link_r = null;
|
|
|
|
if ($nav_r) {
|
2013-01-17 18:57:09 -08:00
|
|
|
$link_r = phutil_tag(
|
2011-07-17 11:06:02 -07:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $uri->alter('l', $l + 1)->alter('r', $r + 1),
|
2013-10-29 16:06:13 -07:00
|
|
|
'class' => 'button',
|
2011-07-17 11:06:02 -07:00
|
|
|
),
|
2013-02-08 09:54:27 -08:00
|
|
|
pht("Next Change \xC2\xBB"));
|
2011-07-17 11:06:02 -07:00
|
|
|
} else {
|
2013-10-29 16:06:13 -07:00
|
|
|
$link_r = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '#',
|
|
|
|
'class' => 'button grey disabled',
|
|
|
|
),
|
|
|
|
pht('Most Recent Change'));
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
2013-11-11 09:23:23 -08:00
|
|
|
$navigation_table = phutil_tag(
|
|
|
|
'table',
|
|
|
|
array('class' => 'phriction-history-nav-table'),
|
|
|
|
phutil_tag('tr', array(), array(
|
|
|
|
phutil_tag('td', array('class' => 'nav-prev'), $link_l),
|
|
|
|
phutil_tag('td', array('class' => 'nav-next'), $link_r),
|
|
|
|
)));
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-13 14:50:15 -08:00
|
|
|
$output = hsprintf(
|
2014-03-30 11:18:49 -07:00
|
|
|
'<div class="phriction-document-history-diff">'.
|
2013-10-29 16:06:13 -07:00
|
|
|
'%s%s'.
|
2011-07-17 11:06:02 -07:00
|
|
|
'<table class="phriction-revert-table">'.
|
2013-02-13 14:50:15 -08:00
|
|
|
'<tr><td>%s</td><td>%s</td>'.
|
2011-07-17 11:06:02 -07:00
|
|
|
'</table>'.
|
2013-02-13 14:50:15 -08:00
|
|
|
'</div>',
|
|
|
|
$comparison_table->render(),
|
|
|
|
$navigation_table,
|
|
|
|
$revert_l,
|
2015-03-08 06:02:47 -07:00
|
|
|
$revert_r);
|
2011-07-17 11:06:02 -07:00
|
|
|
|
2013-03-13 15:15:58 -07:00
|
|
|
|
2013-10-29 16:06:13 -07:00
|
|
|
$object_box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
|
|
|
->appendChild($output);
|
|
|
|
|
2013-03-13 15:15:58 -07:00
|
|
|
return $this->buildApplicationPage(
|
2011-07-17 11:06:02 -07:00
|
|
|
array(
|
|
|
|
$crumbs,
|
2013-10-29 16:06:13 -07:00
|
|
|
$object_box,
|
2015-03-08 06:02:47 -07:00
|
|
|
$changes,
|
2011-07-17 11:06:02 -07:00
|
|
|
),
|
|
|
|
array(
|
2013-02-08 09:54:27 -08:00
|
|
|
'title' => pht('Document History'),
|
2011-07-17 11:06:02 -07:00
|
|
|
));
|
2013-03-13 15:15:58 -07:00
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
private function renderRevertButton(
|
|
|
|
PhrictionContent $content,
|
|
|
|
PhrictionContent $current) {
|
|
|
|
|
|
|
|
$document_id = $content->getDocumentID();
|
|
|
|
$version = $content->getVersion();
|
|
|
|
|
2013-03-22 14:42:25 -07:00
|
|
|
$hidden_statuses = array(
|
|
|
|
PhrictionChangeType::CHANGE_DELETE => true, // Silly
|
|
|
|
PhrictionChangeType::CHANGE_MOVE_AWAY => true, // Plain silly
|
|
|
|
PhrictionChangeType::CHANGE_STUB => true, // Utterly silly
|
|
|
|
);
|
|
|
|
if (isset($hidden_statuses[$content->getChangeType()])) {
|
|
|
|
// Don't show an edit/revert button for changes which deleted, moved or
|
|
|
|
// stubbed the content since it's silly.
|
2011-12-17 09:19:08 -08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2011-07-17 11:06:02 -07:00
|
|
|
if ($content->getID() == $current->getID()) {
|
2013-01-17 18:57:09 -08:00
|
|
|
return phutil_tag(
|
2011-07-17 11:06:02 -07:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/phriction/edit/'.$document_id.'/',
|
2013-10-29 16:06:13 -07:00
|
|
|
'class' => 'button grey',
|
2011-07-17 11:06:02 -07:00
|
|
|
),
|
2013-02-08 09:54:27 -08:00
|
|
|
pht('Edit Current Version'));
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-18 00:32:58 -08:00
|
|
|
return phutil_tag(
|
2011-07-17 11:06:02 -07:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/phriction/edit/'.$document_id.'/?revert='.$version,
|
2013-10-29 16:06:13 -07:00
|
|
|
'class' => 'button grey',
|
2011-07-17 11:06:02 -07:00
|
|
|
),
|
2013-02-08 17:29:15 -08:00
|
|
|
pht('Revert to Version %s...', $version));
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
private function renderComparisonTable(array $content) {
|
2012-04-03 12:10:45 -07:00
|
|
|
assert_instances_of($content, 'PhrictionContent');
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
|
|
|
|
$phids = mpull($content, 'getAuthorPHID');
|
2012-09-04 19:02:56 -07:00
|
|
|
$handles = $this->loadViewerHandles($phids);
|
2011-07-17 11:06:02 -07:00
|
|
|
|
2013-09-09 14:14:34 -07:00
|
|
|
$list = new PHUIObjectItemListView();
|
2013-10-29 16:06:13 -07:00
|
|
|
$list->setFlush(true);
|
2013-03-22 14:42:25 -07:00
|
|
|
|
|
|
|
$first = true;
|
2011-07-17 11:06:02 -07:00
|
|
|
foreach ($content as $c) {
|
2013-03-22 14:42:25 -07:00
|
|
|
$author = $handles[$c->getAuthorPHID()]->renderLink();
|
2013-09-09 14:14:34 -07:00
|
|
|
$item = id(new PHUIObjectItemView())
|
2013-03-22 14:42:25 -07:00
|
|
|
->setHeader(pht('%s by %s, %s',
|
|
|
|
PhrictionChangeType::getChangeTypeLabel($c->getChangeType()),
|
|
|
|
$author,
|
|
|
|
pht('Version %s', $c->getVersion())))
|
|
|
|
->addAttribute(pht('%s %s',
|
|
|
|
phabricator_date($c->getDateCreated(), $user),
|
|
|
|
phabricator_time($c->getDateCreated(), $user)));
|
|
|
|
|
|
|
|
if ($c->getDescription()) {
|
|
|
|
$item->addAttribute($c->getDescription());
|
|
|
|
}
|
2011-07-17 11:06:02 -07:00
|
|
|
|
2013-03-22 14:42:25 -07:00
|
|
|
if ($first == true) {
|
|
|
|
$item->setBarColor('green');
|
|
|
|
$first = false;
|
|
|
|
} else {
|
|
|
|
$item->setBarColor('red');
|
|
|
|
}
|
2011-07-17 11:06:02 -07:00
|
|
|
|
2013-03-22 14:42:25 -07:00
|
|
|
$list->addItem($item);
|
|
|
|
}
|
2011-07-17 11:06:02 -07:00
|
|
|
|
2013-03-22 14:42:25 -07:00
|
|
|
return $list;
|
2011-07-17 11:06:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|