Summary: NOTE: This is not produced by a script so there might be errors. Please review carefully. Test Plan: Browse around Differential. Reviewers: epriestley Reviewed By: epriestley CC: aran Differential Revision: https://secure.phabricator.com/D2103
307 lines
8.7 KiB
PHP
307 lines
8.7 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright 2012 Facebook, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
final class DifferentialRevisionCommentView extends AphrontView {
|
|
|
|
private $comment;
|
|
private $handles;
|
|
private $markupEngine;
|
|
private $preview;
|
|
private $inlines;
|
|
private $changesets;
|
|
private $target;
|
|
private $anchorName;
|
|
private $user;
|
|
private $versusDiffID;
|
|
|
|
public function setComment($comment) {
|
|
$this->comment = $comment;
|
|
return $this;
|
|
}
|
|
|
|
public function setHandles(array $handles) {
|
|
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
|
$this->handles = $handles;
|
|
return $this;
|
|
}
|
|
|
|
public function setMarkupEngine($markup_engine) {
|
|
$this->markupEngine = $markup_engine;
|
|
return $this;
|
|
}
|
|
|
|
public function setPreview($preview) {
|
|
$this->preview = $preview;
|
|
return $this;
|
|
}
|
|
|
|
public function setInlineComments(array $inline_comments) {
|
|
assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface');
|
|
$this->inlines = $inline_comments;
|
|
return $this;
|
|
}
|
|
|
|
public function setChangesets(array $changesets) {
|
|
assert_instances_of($changesets, 'DifferentialChangeset');
|
|
// Ship these in sorted by getSortKey() and keyed by ID... or else!
|
|
$this->changesets = $changesets;
|
|
return $this;
|
|
}
|
|
|
|
public function setTargetDiff($target) {
|
|
$this->target = $target;
|
|
return $this;
|
|
}
|
|
|
|
public function setVersusDiffID($diff_vs) {
|
|
$this->versusDiffID = $diff_vs;
|
|
return $this;
|
|
}
|
|
|
|
public function setAnchorName($anchor_name) {
|
|
$this->anchorName = $anchor_name;
|
|
return $this;
|
|
}
|
|
|
|
public function setUser(PhabricatorUser $user) {
|
|
$this->user = $user;
|
|
return $this;
|
|
}
|
|
|
|
public function render() {
|
|
|
|
if (!$this->user) {
|
|
throw new Exception("Call setUser() before rendering!");
|
|
}
|
|
|
|
require_celerity_resource('phabricator-remarkup-css');
|
|
require_celerity_resource('differential-revision-comment-css');
|
|
|
|
$comment = $this->comment;
|
|
|
|
$action = $comment->getAction();
|
|
|
|
$action_class = 'differential-comment-action-'.$action;
|
|
|
|
$info = array();
|
|
|
|
$content = $comment->getContent();
|
|
$hide_comments = true;
|
|
if (strlen(rtrim($content))) {
|
|
$hide_comments = false;
|
|
$cache = $comment->getCache();
|
|
if (strlen($cache)) {
|
|
$content = $cache;
|
|
} else {
|
|
$content = $this->markupEngine->markupText($content);
|
|
if ($comment->getID()) {
|
|
$comment->setCache($content);
|
|
|
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
$comment->save();
|
|
unset($unguarded);
|
|
}
|
|
}
|
|
$content =
|
|
'<div class="phabricator-remarkup">'.
|
|
$content.
|
|
'</div>';
|
|
}
|
|
|
|
$inline_render = $this->renderInlineComments();
|
|
if ($inline_render) {
|
|
$hide_comments = false;
|
|
}
|
|
|
|
$author = $this->handles[$comment->getAuthorPHID()];
|
|
$author_link = $author->renderLink();
|
|
|
|
$metadata = $comment->getMetadata();
|
|
$added_reviewers = idx(
|
|
$metadata,
|
|
DifferentialComment::METADATA_ADDED_REVIEWERS,
|
|
array());
|
|
$added_ccs = idx(
|
|
$metadata,
|
|
DifferentialComment::METADATA_ADDED_CCS,
|
|
array());
|
|
|
|
$verb = DifferentialAction::getActionPastTenseVerb($comment->getAction());
|
|
$verb = phutil_escape_html($verb);
|
|
|
|
$actions = array();
|
|
switch ($comment->getAction()) {
|
|
case DifferentialAction::ACTION_ADDCCS:
|
|
$actions[] = "{$author_link} added CCs: ".
|
|
$this->renderHandleList($added_ccs).".";
|
|
$added_ccs = null;
|
|
break;
|
|
case DifferentialAction::ACTION_ADDREVIEWERS:
|
|
$actions[] = "{$author_link} added reviewers: ".
|
|
$this->renderHandleList($added_reviewers).".";
|
|
$added_reviewers = null;
|
|
break;
|
|
case DifferentialAction::ACTION_UPDATE:
|
|
$diff_id = idx($metadata, DifferentialComment::METADATA_DIFF_ID);
|
|
if ($diff_id) {
|
|
$diff_link = phutil_render_tag(
|
|
'a',
|
|
array(
|
|
'href' => '/D'.$comment->getRevisionID().'?id='.$diff_id,
|
|
),
|
|
'Diff #'.phutil_escape_html($diff_id));
|
|
$actions[] = "{$author_link} updated this revision to {$diff_link}.";
|
|
} else {
|
|
$actions[] = "{$author_link} {$verb} this revision.";
|
|
}
|
|
break;
|
|
default:
|
|
$actions[] = "{$author_link} {$verb} this revision.";
|
|
break;
|
|
}
|
|
|
|
if ($added_reviewers) {
|
|
$actions[] = "{$author_link} added reviewers: ".
|
|
$this->renderHandleList($added_reviewers).".";
|
|
}
|
|
|
|
if ($added_ccs) {
|
|
$actions[] = "{$author_link} added CCs: ".
|
|
$this->renderHandleList($added_ccs).".";
|
|
}
|
|
|
|
foreach ($actions as $key => $action) {
|
|
$actions[$key] = '<div>'.$action.'</div>';
|
|
}
|
|
|
|
$xaction_view = id(new PhabricatorTransactionView())
|
|
->setUser($this->user)
|
|
->setImageURI($author->getImageURI())
|
|
->setContentSource($comment->getContentSource())
|
|
->addClass($action_class)
|
|
->setActions($actions);
|
|
|
|
if ($this->preview) {
|
|
$xaction_view->setIsPreview($this->preview);
|
|
} else {
|
|
$xaction_view->setEpoch($comment->getDateCreated());
|
|
if ($this->anchorName) {
|
|
$anchor_name = $this->anchorName;
|
|
$anchor_text = 'D'.$comment->getRevisionID().'#'.$anchor_name;
|
|
|
|
$xaction_view->setAnchor($anchor_name, $anchor_text);
|
|
}
|
|
}
|
|
|
|
if (!$hide_comments) {
|
|
$xaction_view->appendChild(
|
|
'<div class="differential-comment-core">'.
|
|
$content.
|
|
'</div>'.
|
|
$this->renderSingleView($inline_render));
|
|
}
|
|
|
|
return $xaction_view->render();
|
|
}
|
|
|
|
private function renderHandleList(array $phids) {
|
|
$result = array();
|
|
foreach ($phids as $phid) {
|
|
$result[] = $this->handles[$phid]->renderLink();
|
|
}
|
|
return implode(', ', $result);
|
|
}
|
|
|
|
private function renderInlineComments() {
|
|
if (!$this->inlines) {
|
|
return null;
|
|
}
|
|
|
|
$inlines = $this->inlines;
|
|
$changesets = $this->changesets;
|
|
$inlines_by_changeset = mgroup($inlines, 'getChangesetID');
|
|
$inlines_by_changeset = array_select_keys(
|
|
$inlines_by_changeset,
|
|
array_keys($this->changesets));
|
|
|
|
$view = new PhabricatorInlineSummaryView();
|
|
foreach ($inlines_by_changeset as $changeset_id => $inlines) {
|
|
$changeset = $changesets[$changeset_id];
|
|
$items = array();
|
|
foreach ($inlines as $inline) {
|
|
|
|
$on_target = ($this->target) &&
|
|
($this->target->getID() == $changeset->getDiffID());
|
|
|
|
$is_visible = false;
|
|
if ($inline->getIsNewFile()) {
|
|
// This comment is on the right side of the versus diff, and visible
|
|
// on the left side of the page.
|
|
if ($this->versusDiffID) {
|
|
if ($changeset->getDiffID() == $this->versusDiffID) {
|
|
$is_visible = true;
|
|
}
|
|
}
|
|
|
|
// This comment is on the right side of the target diff, and visible
|
|
// on the right side of the page.
|
|
if ($on_target) {
|
|
$is_visible = true;
|
|
}
|
|
} else {
|
|
// Ths comment is on the left side of the target diff, and visible
|
|
// on the left side of the page.
|
|
if (!$this->versusDiffID) {
|
|
if ($on_target) {
|
|
$is_visible = true;
|
|
}
|
|
}
|
|
|
|
// TODO: We still get one edge case wrong here, when we have a
|
|
// versus diff and the file didn't exist in the old version. The
|
|
// comment is visible because we show the left side of the target
|
|
// diff when there's no corresponding file in the versus diff, but
|
|
// we incorrectly link it off-page.
|
|
}
|
|
|
|
$item = array(
|
|
'id' => $inline->getID(),
|
|
'line' => $inline->getLineNumber(),
|
|
'length' => $inline->getLineLength(),
|
|
'content' => PhabricatorInlineSummaryView::renderCommentContent(
|
|
$inline,
|
|
$this->markupEngine),
|
|
);
|
|
|
|
if (!$is_visible) {
|
|
$diff_id = $changeset->getDiffID();
|
|
$item['where'] = '(On Diff #'.$diff_id.')';
|
|
$item['href'] = '?id='.$diff_id.'#inline-'.$inline->getID();
|
|
}
|
|
|
|
$items[] = $item;
|
|
}
|
|
$view->addCommentGroup($changeset->getFilename(), $items);
|
|
}
|
|
|
|
return $view;
|
|
}
|
|
|
|
|
|
}
|