1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Highlight inline diff context in HTML mail

Summary:
Ref T10694. Ref T9790. When generating inline diff context, highlight it and then mangle the highlighted output into `style="..."` so it works in HTML.

Also try to tighten up some spacing/formatting stuff.

Test Plan:
Got some output in this vein:

{F1259937}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9790, T10694

Differential Revision: https://secure.phabricator.com/D15852
This commit is contained in:
epriestley 2016-05-05 09:46:44 -07:00
parent 2025ecd3d8
commit 94c7bb605c
6 changed files with 223 additions and 28 deletions

View file

@ -370,6 +370,7 @@ phutil_register_library_map(array(
'DifferentialChangesetFileTreeSideNavBuilder' => 'applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php',
'DifferentialChangesetHTMLRenderer' => 'applications/differential/render/DifferentialChangesetHTMLRenderer.php',
'DifferentialChangesetListView' => 'applications/differential/view/DifferentialChangesetListView.php',
'DifferentialChangesetOneUpMailRenderer' => 'applications/differential/render/DifferentialChangesetOneUpMailRenderer.php',
'DifferentialChangesetOneUpRenderer' => 'applications/differential/render/DifferentialChangesetOneUpRenderer.php',
'DifferentialChangesetOneUpTestRenderer' => 'applications/differential/render/DifferentialChangesetOneUpTestRenderer.php',
'DifferentialChangesetParser' => 'applications/differential/parser/DifferentialChangesetParser.php',
@ -4559,6 +4560,7 @@ phutil_register_library_map(array(
'DifferentialChangesetFileTreeSideNavBuilder' => 'Phobject',
'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetOneUpMailRenderer' => 'DifferentialChangesetRenderer',
'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer',
'DifferentialChangesetOneUpTestRenderer' => 'DifferentialChangesetTestRenderer',
'DifferentialChangesetParser' => 'Phobject',

View file

@ -1212,9 +1212,7 @@ final class DifferentialTransactionEditor
}
if ($inlines) {
$body->addTextSection(
pht('INLINE COMMENTS'),
$this->renderInlineCommentsForMail($object, $inlines));
$this->appendInlineCommentsForMail($object, $inlines, $body);
}
$changed_uri = $this->getChangedPriorToCommitURI();
@ -1374,13 +1372,23 @@ final class DifferentialTransactionEditor
return $result;
}
private function renderInlineCommentsForMail(
private function appendInlineCommentsForMail(
PhabricatorLiskDAO $object,
array $inlines) {
return id(new DifferentialInlineCommentMailView())
array $inlines,
PhabricatorMetaMTAMailBody $body) {
$section = id(new DifferentialInlineCommentMailView())
->setViewer($this->getActor())
->setInlines($inlines)
->buildMailSection();
$header = pht('INLINE COMMENTS');
$section_text = "\n".$section->getPlaintext();
$section_html = $section->getHTML();
$body->addPlaintextSection($header, $section_text, false);
$body->addHTMLSection($header, $section_html);
}
private function loadDiff($phid, $need_changesets = false) {

View file

@ -71,9 +71,11 @@ final class DifferentialInlineCommentMailView
$context_html = $this->renderInline($parent, true, true);
}
} else {
$patch = $this->getPatch($hunk_parser, $comment);
$context_text = $this->renderPatch($comment, $patch, false);
$context_html = $this->renderPatch($comment, $patch, true);
$patch_text = $this->getPatch($hunk_parser, $comment, false);
$context_text = $this->renderPatch($comment, $patch_text, false);
$patch_html = $this->getPatch($hunk_parser, $comment, true);
$context_html = $this->renderPatch($comment, $patch_html, true);
}
$render_text = $this->renderInline($comment, false, false);
@ -83,7 +85,6 @@ final class DifferentialInlineCommentMailView
$section->addHTMLFragment($context_html);
$section->addPlaintextFragment($spacer_text);
$section->addHTMLFragment($spacer_html);
$section->addPlaintextFragment($render_text);
$section->addHTMLFragment($render_html);
@ -180,6 +181,18 @@ final class DifferentialInlineCommentMailView
$content = $this->renderRemarkupContent($content, $is_html);
if ($is_quote) {
if ($is_html) {
$style = array(
'padding: 4px 0;',
);
$content = phutil_tag(
'div',
array(
'style' => implode(' ', $style),
),
$content);
}
$header = $this->renderHeader($comment, $is_html, true);
} else {
$header = null;
@ -254,6 +267,7 @@ final class DifferentialInlineCommentMailView
'padding: 4px 8px;',
'background: #F8F9FC;',
'border-left: 3px solid #a7b5bf;',
'margin: 4px 0 0;',
);
$styles = implode(' ', $styles);
@ -268,18 +282,43 @@ final class DifferentialInlineCommentMailView
private function getPatch(
DifferentialHunkParser $parser,
DifferentialTransactionComment $comment) {
DifferentialTransactionComment $comment,
$is_html) {
$changeset = $this->getChangeset($comment->getChangesetID());
$hunks = $changeset->getHunks();
$is_new = $comment->getIsNewFile();
$start = $comment->getLineNumber();
$length = $comment->getLineLength();
$diff = $parser->makeContextDiff($hunks, $is_new, $start, $length, 1);
if (!$is_html) {
$hunks = $changeset->getHunks();
$patch = $parser->makeContextDiff($hunks, $is_new, $start, $length, 1);
$patch = phutil_split_lines($patch);
return $diff;
// Remove the "@@ -x,y +u,v @@" line.
array_shift($patch);
return implode('', $patch);
}
$viewer = $this->getViewer();
$engine = new PhabricatorMarkupEngine();
if ($is_new) {
$offset_mode = 'new';
} else {
$offset_mode = 'old';
}
$parser = id(new DifferentialChangesetParser())
->setUser($viewer)
->setChangeset($changeset)
->setOffsetMode($offset_mode)
->setMarkupEngine($engine);
$parser->setRenderer(new DifferentialChangesetOneUpMailRenderer());
return $parser->render($start - 1, $length + 3, array());
}
private function renderPatch(
@ -287,17 +326,10 @@ final class DifferentialInlineCommentMailView
$patch,
$is_html) {
$patch = phutil_split_lines($patch);
// Remove the "@@ -x,y +u,v @@" line.
array_shift($patch);
$patch = implode('', $patch);
if ($is_html) {
$style = array(
'font: 11px/15px "Menlo", "Consolas", "Monaco", monospace;',
'padding: 0',
'padding: 4px 0;',
'margin: 0;',
);
@ -346,7 +378,12 @@ final class DifferentialInlineCommentMailView
$header = "{$path}:{$range}";
if ($is_html) {
$header = phutil_tag('strong', array(), $header);
$header = phutil_tag(
'span',
array(
'style' => 'color: #000000',
),
$header);
}
if ($with_author) {
@ -359,7 +396,12 @@ final class DifferentialInlineCommentMailView
$byline = '@'.$author->getName();
if ($is_html) {
$byline = phutil_tag('strong', array(), $byline);
$byline = phutil_tag(
'span',
array(
'style' => 'color: #000000',
),
$byline);
}
$header = pht('%s wrote in %s', $byline, $header);
@ -371,7 +413,7 @@ final class DifferentialInlineCommentMailView
$header = phutil_tag(
'div',
array(
'style' => 'font-style: italic',
'style' => 'font-style: italic; color: #74777d',
),
$header);
}

View file

@ -50,6 +50,7 @@ final class DifferentialChangesetParser extends Phobject {
private $showEditAndReplyLinks = true;
private $canMarkDone;
private $objectOwnerPHID;
private $offsetMode;
private $rangeStart;
private $rangeEnd;
@ -138,6 +139,15 @@ final class DifferentialChangesetParser extends Phobject {
return $this->objectOwnerPHID;
}
public function setOffsetMode($offset_mode) {
$this->offsetMode = $offset_mode;
return $this;
}
public function getOffsetMode() {
return $this->offsetMode;
}
public static function getDefaultRendererForViewer(PhabricatorUser $viewer) {
$prefs = $viewer->loadPreferences();
$pref_unified = PhabricatorUserPreferences::PREFERENCE_DIFF_UNIFIED;
@ -829,6 +839,22 @@ final class DifferentialChangesetParser extends Phobject {
}
$this->tryCacheStuff();
// If we're rendering in an offset mode, treat the range numbers as line
// numbers instead of rendering offsets.
$offset_mode = $this->getOffsetMode();
if ($offset_mode) {
if ($offset_mode == 'new') {
$offset_map = $this->new;
} else {
$offset_map = $this->old;
}
$range_end = $this->getOffset($offset_map, $range_start + $range_len);
$range_start = $this->getOffset($offset_map, $range_start);
$range_len = $range_end - $range_start;
}
$render_pch = $this->shouldRenderPropertyChangeHeader($this->changeset);
$rows = max(
@ -1632,5 +1658,21 @@ final class DifferentialChangesetParser extends Phobject {
return $results;
}
private function getOffset(array $map, $line) {
if (!$map) {
return null;
}
$line = (int)$line;
foreach ($map as $key => $spec) {
if ($spec && isset($spec['line'])) {
if ((int)$spec['line'] >= $line) {
return $key;
}
}
}
return $key;
}
}

View file

@ -0,0 +1,98 @@
<?php
final class DifferentialChangesetOneUpMailRenderer
extends DifferentialChangesetRenderer {
public function isOneUpRenderer() {
return true;
}
protected function getRendererTableClass() {
return 'diff-1up-mail';
}
public function getRendererKey() {
return '1up-mail';
}
protected function renderChangeTypeHeader($force) {
return null;
}
protected function renderUndershieldHeader() {
return null;
}
public function renderShield($message, $force = 'default') {
return null;
}
protected function renderPropertyChangeHeader() {
return null;
}
public function renderFileChange(
$old_file = null,
$new_file = null,
$id = 0,
$vs = 0) {
return null;
}
public function renderTextChange(
$range_start,
$range_len,
$rows) {
$primitives = $this->buildPrimitives($range_start, $range_len);
return $this->renderPrimitives($primitives, $rows);
}
protected function renderPrimitives(array $primitives, $rows) {
$out = array();
foreach ($primitives as $k => $p) {
$type = $p['type'];
switch ($type) {
case 'old':
case 'new':
case 'old-file':
case 'new-file':
$is_old = ($type == 'old' || $type == 'old-file');
if ($is_old) {
if ($p['htype']) {
$style = 'background: #ffd0d0;';
} else {
$style = null;
}
} else {
if ($p['htype']) {
$style = 'background: #d0ffd0;';
} else {
$style = null;
}
}
$out[] = phutil_tag(
'div',
array(
'style' => $style,
),
$p['render']);
break;
default:
break;
}
}
$style_map = id(new PhabricatorDefaultSyntaxStyle())
->getRemarkupStyleMap();
$styled_body = id(new PhutilPygmentizeParser())
->setMap($style_map)
->parse((string)hsprintf('%s', $out));
return phutil_safe_html($styled_body);
}
}

View file

@ -111,8 +111,11 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
return $this;
}
public function addPlaintextSection($header, $text) {
$this->sections[] = $header."\n".$this->indent($text);
public function addPlaintextSection($header, $text, $indent = true) {
if ($indent) {
$text = $this->indent($text);
}
$this->sections[] = $header."\n".$text;
return $this;
}