Improve HTML mail rendering of inline patches
Summary: Fixes T9790. This uses a simple renderer, like the inline context renderer, that emphasizes getting a quick glance at small changes and working reasonably on mobile devices.
Test Plan:
  - Set `inline` setting to `9999`.
  - Created a diff.
  - Saw it render reasonably in HTML mail.
  - Also tested text mail to make sure I didn't break that.
{F1310137, size=full}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9790
Differential Revision: https://secure.phabricator.com/D15901
			
			
This commit is contained in:
		| @@ -362,6 +362,7 @@ phutil_register_library_map(array( | |||||||
|     'DifferentialBlameRevisionField' => 'applications/differential/customfield/DifferentialBlameRevisionField.php', |     'DifferentialBlameRevisionField' => 'applications/differential/customfield/DifferentialBlameRevisionField.php', | ||||||
|     'DifferentialBlockHeraldAction' => 'applications/differential/herald/DifferentialBlockHeraldAction.php', |     'DifferentialBlockHeraldAction' => 'applications/differential/herald/DifferentialBlockHeraldAction.php', | ||||||
|     'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php', |     'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php', | ||||||
|  |     'DifferentialChangeDetailMailView' => 'applications/differential/mail/DifferentialChangeDetailMailView.php', | ||||||
|     'DifferentialChangeHeraldFieldGroup' => 'applications/differential/herald/DifferentialChangeHeraldFieldGroup.php', |     'DifferentialChangeHeraldFieldGroup' => 'applications/differential/herald/DifferentialChangeHeraldFieldGroup.php', | ||||||
|     'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php', |     'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php', | ||||||
|     'DifferentialChangesSinceLastUpdateField' => 'applications/differential/customfield/DifferentialChangesSinceLastUpdateField.php', |     'DifferentialChangesSinceLastUpdateField' => 'applications/differential/customfield/DifferentialChangesSinceLastUpdateField.php', | ||||||
| @@ -471,6 +472,7 @@ phutil_register_library_map(array( | |||||||
|     'DifferentialLintField' => 'applications/differential/customfield/DifferentialLintField.php', |     'DifferentialLintField' => 'applications/differential/customfield/DifferentialLintField.php', | ||||||
|     'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php', |     'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php', | ||||||
|     'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php', |     'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php', | ||||||
|  |     'DifferentialMailView' => 'applications/differential/mail/DifferentialMailView.php', | ||||||
|     'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php', |     'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php', | ||||||
|     'DifferentialModernHunk' => 'applications/differential/storage/DifferentialModernHunk.php', |     'DifferentialModernHunk' => 'applications/differential/storage/DifferentialModernHunk.php', | ||||||
|     'DifferentialNextStepField' => 'applications/differential/customfield/DifferentialNextStepField.php', |     'DifferentialNextStepField' => 'applications/differential/customfield/DifferentialNextStepField.php', | ||||||
| @@ -4551,6 +4553,7 @@ phutil_register_library_map(array( | |||||||
|     'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', |     'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', | ||||||
|     'DifferentialBlockHeraldAction' => 'HeraldAction', |     'DifferentialBlockHeraldAction' => 'HeraldAction', | ||||||
|     'DifferentialBranchField' => 'DifferentialCustomField', |     'DifferentialBranchField' => 'DifferentialCustomField', | ||||||
|  |     'DifferentialChangeDetailMailView' => 'DifferentialMailView', | ||||||
|     'DifferentialChangeHeraldFieldGroup' => 'HeraldFieldGroup', |     'DifferentialChangeHeraldFieldGroup' => 'HeraldFieldGroup', | ||||||
|     'DifferentialChangeType' => 'Phobject', |     'DifferentialChangeType' => 'Phobject', | ||||||
|     'DifferentialChangesSinceLastUpdateField' => 'DifferentialCustomField', |     'DifferentialChangesSinceLastUpdateField' => 'DifferentialCustomField', | ||||||
| @@ -4665,7 +4668,7 @@ phutil_register_library_map(array( | |||||||
|       'PhabricatorInlineCommentInterface', |       'PhabricatorInlineCommentInterface', | ||||||
|     ), |     ), | ||||||
|     'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController', |     'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController', | ||||||
|     'DifferentialInlineCommentMailView' => 'Phobject', |     'DifferentialInlineCommentMailView' => 'DifferentialMailView', | ||||||
|     'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', |     'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', | ||||||
|     'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', |     'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', | ||||||
|     'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', |     'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', | ||||||
| @@ -4676,6 +4679,7 @@ phutil_register_library_map(array( | |||||||
|     'DifferentialLintField' => 'DifferentialHarbormasterField', |     'DifferentialLintField' => 'DifferentialHarbormasterField', | ||||||
|     'DifferentialLintStatus' => 'Phobject', |     'DifferentialLintStatus' => 'Phobject', | ||||||
|     'DifferentialLocalCommitsView' => 'AphrontView', |     'DifferentialLocalCommitsView' => 'AphrontView', | ||||||
|  |     'DifferentialMailView' => 'Phobject', | ||||||
|     'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField', |     'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField', | ||||||
|     'DifferentialModernHunk' => 'DifferentialHunk', |     'DifferentialModernHunk' => 'DifferentialHunk', | ||||||
|     'DifferentialNextStepField' => 'DifferentialCustomField', |     'DifferentialNextStepField' => 'DifferentialCustomField', | ||||||
|   | |||||||
| @@ -1251,21 +1251,18 @@ final class DifferentialTransactionEditor | |||||||
|       $config_attach = PhabricatorEnv::getEnvConfig($config_key_attach); |       $config_attach = PhabricatorEnv::getEnvConfig($config_key_attach); | ||||||
|  |  | ||||||
|       if ($config_inline || $config_attach) { |       if ($config_inline || $config_attach) { | ||||||
|         $patch_section = $this->renderPatchForMail($diff); |         $patch = $this->buildPatchForMail($diff); | ||||||
|         $lines = count(phutil_split_lines($patch_section->getPlaintext())); |         $lines = substr_count($patch, "\n"); | ||||||
|  |  | ||||||
|         if ($config_inline && ($lines <= $config_inline)) { |         if ($config_inline && ($lines <= $config_inline)) { | ||||||
|           $body->addTextSection( |           $this->appendChangeDetailsForMail($object, $diff, $patch, $body); | ||||||
|             pht('CHANGE DETAILS'), |  | ||||||
|             $patch_section); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if ($config_attach) { |         if ($config_attach) { | ||||||
|           $name = pht('D%s.%s.patch', $object->getID(), $diff->getID()); |           $name = pht('D%s.%s.patch', $object->getID(), $diff->getID()); | ||||||
|           $mime_type = 'text/x-patch; charset=utf-8'; |           $mime_type = 'text/x-patch; charset=utf-8'; | ||||||
|           $body->addAttachment( |           $body->addAttachment( | ||||||
|             new PhabricatorMetaMTAAttachment( |             new PhabricatorMetaMTAAttachment($patch, $name, $mime_type)); | ||||||
|               $patch_section->getPlaintext(), $name, $mime_type)); |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -1387,7 +1384,38 @@ final class DifferentialTransactionEditor | |||||||
|     $section_text = "\n".$section->getPlaintext(); |     $section_text = "\n".$section->getPlaintext(); | ||||||
|  |  | ||||||
|     $style = array( |     $style = array( | ||||||
|       'margin: 12px 0;', |       'margin: 6px 0 12px 0;', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     $section_html = phutil_tag( | ||||||
|  |       'div', | ||||||
|  |       array( | ||||||
|  |         'style' => implode(' ', $style), | ||||||
|  |       ), | ||||||
|  |       $section->getHTML()); | ||||||
|  |  | ||||||
|  |     $body->addPlaintextSection($header, $section_text, false); | ||||||
|  |     $body->addHTMLSection($header, $section_html); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private function appendChangeDetailsForMail( | ||||||
|  |     PhabricatorLiskDAO $object, | ||||||
|  |     DifferentialDiff $diff, | ||||||
|  |     $patch, | ||||||
|  |     PhabricatorMetaMTAMailBody $body) { | ||||||
|  |  | ||||||
|  |     $section = id(new DifferentialChangeDetailMailView()) | ||||||
|  |       ->setViewer($this->getActor()) | ||||||
|  |       ->setDiff($diff) | ||||||
|  |       ->setPatch($patch) | ||||||
|  |       ->buildMailSection(); | ||||||
|  |  | ||||||
|  |     $header = pht('CHANGE DETAILS'); | ||||||
|  |  | ||||||
|  |     $section_text = "\n".$section->getPlaintext(); | ||||||
|  |  | ||||||
|  |     $style = array( | ||||||
|  |       'margin: 6px 0 12px 0;', | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     $section_html = phutil_tag( |     $section_html = phutil_tag( | ||||||
| @@ -1659,20 +1687,14 @@ final class DifferentialTransactionEditor | |||||||
|       array('style' => 'font-family: monospace;'), $patch); |       array('style' => 'font-family: monospace;'), $patch); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function renderPatchForMail(DifferentialDiff $diff) { |   private function buildPatchForMail(DifferentialDiff $diff) { | ||||||
|     $format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format'); |     $format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format'); | ||||||
|  |  | ||||||
|     $patch = id(new DifferentialRawDiffRenderer()) |     return id(new DifferentialRawDiffRenderer()) | ||||||
|       ->setViewer($this->getActor()) |       ->setViewer($this->getActor()) | ||||||
|       ->setFormat($format) |       ->setFormat($format) | ||||||
|       ->setChangesets($diff->getChangesets()) |       ->setChangesets($diff->getChangesets()) | ||||||
|       ->buildPatch(); |       ->buildPatch(); | ||||||
|  |  | ||||||
|     $section = new PhabricatorMetaMTAMailSection(); |  | ||||||
|     $section->addHTMLFragment($this->renderPatchHTMLForMail($patch)); |  | ||||||
|     $section->addPlaintextFragment($patch); |  | ||||||
|  |  | ||||||
|     return $section; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected function willPublish(PhabricatorLiskDAO $object, array $xactions) { |   protected function willPublish(PhabricatorLiskDAO $object, array $xactions) { | ||||||
|   | |||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class DifferentialChangeDetailMailView | ||||||
|  |   extends DifferentialMailView { | ||||||
|  |  | ||||||
|  |   private $viewer; | ||||||
|  |   private $diff; | ||||||
|  |   private $patch; | ||||||
|  |  | ||||||
|  |   public function setViewer(PhabricatorUser $viewer) { | ||||||
|  |     $this->viewer = $viewer; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getViewer() { | ||||||
|  |     return $this->viewer; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function setDiff(DifferentialDiff $diff) { | ||||||
|  |     $this->diff = $diff; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getDiff() { | ||||||
|  |     return $this->diff; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function setPatch($patch) { | ||||||
|  |     $this->patch = $patch; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getPatch() { | ||||||
|  |     return $this->patch; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function buildMailSection() { | ||||||
|  |     $viewer = $this->getViewer(); | ||||||
|  |  | ||||||
|  |     $diff = $this->getDiff(); | ||||||
|  |  | ||||||
|  |     $engine = new PhabricatorMarkupEngine(); | ||||||
|  |  | ||||||
|  |     $out = array(); | ||||||
|  |     foreach ($diff->getChangesets() as $changeset) { | ||||||
|  |       $parser = id(new DifferentialChangesetParser()) | ||||||
|  |         ->setUser($viewer) | ||||||
|  |         ->setChangeset($changeset) | ||||||
|  |         ->setLinesOfContext(2) | ||||||
|  |         ->setMarkupEngine($engine); | ||||||
|  |  | ||||||
|  |       $parser->setRenderer(new DifferentialChangesetOneUpMailRenderer()); | ||||||
|  |       $block = $parser->render(); | ||||||
|  |  | ||||||
|  |       $filename = $changeset->getFilename(); | ||||||
|  |       $filename = $this->renderHeaderBold($filename); | ||||||
|  |       $header = $this->renderHeaderBlock($filename); | ||||||
|  |  | ||||||
|  |       $out[] = $this->renderContentBox( | ||||||
|  |         array( | ||||||
|  |           $header, | ||||||
|  |           $this->renderCodeBlock($block), | ||||||
|  |         )); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $out = phutil_implode_html(phutil_tag('br'), $out); | ||||||
|  |  | ||||||
|  |     $patch_html = $out; | ||||||
|  |  | ||||||
|  |     $patch_text = $this->getPatch(); | ||||||
|  |  | ||||||
|  |     return id(new PhabricatorMetaMTAMailSection()) | ||||||
|  |       ->addPlaintextFragment($patch_text) | ||||||
|  |       ->addHTMLFragment($patch_html); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| final class DifferentialInlineCommentMailView | final class DifferentialInlineCommentMailView | ||||||
|   extends Phobject { |   extends DifferentialMailView { | ||||||
|  |  | ||||||
|   private $viewer; |   private $viewer; | ||||||
|   private $inlines; |   private $inlines; | ||||||
| @@ -85,16 +85,7 @@ final class DifferentialInlineCommentMailView | |||||||
|         $section->addPlaintextFragment($spacer_text); |         $section->addPlaintextFragment($spacer_text); | ||||||
|         $section->addPlaintextFragment($render_text); |         $section->addPlaintextFragment($render_text); | ||||||
|  |  | ||||||
|         $style = array( |         $html_fragment = $this->renderContentBox( | ||||||
|           'border: 1px solid #C7CCD9;', |  | ||||||
|           'border-radius: 3px;', |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         $html_fragment = phutil_tag( |  | ||||||
|           'div', |  | ||||||
|           array( |  | ||||||
|             'style' => implode(' ', $style), |  | ||||||
|           ), |  | ||||||
|           array( |           array( | ||||||
|             $context_html, |             $context_html, | ||||||
|             $render_html, |             $render_html, | ||||||
| @@ -374,21 +365,7 @@ final class DifferentialInlineCommentMailView | |||||||
|     $is_html) { |     $is_html) { | ||||||
|  |  | ||||||
|     if ($is_html) { |     if ($is_html) { | ||||||
|       $style = array( |       $patch = $this->renderCodeBlock($patch); | ||||||
|         'font: 11px/15px "Menlo", "Consolas", "Monaco", monospace;', |  | ||||||
|         'white-space: pre-wrap;', |  | ||||||
|         'clear: both;', |  | ||||||
|         'padding: 4px 0;', |  | ||||||
|         'margin: 0;', |  | ||||||
|       ); |  | ||||||
|  |  | ||||||
|       $style = implode(' ', $style); |  | ||||||
|       $patch = phutil_tag( |  | ||||||
|         'div', |  | ||||||
|         array( |  | ||||||
|           'style' => $style, |  | ||||||
|         ), |  | ||||||
|         $patch); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $header = $this->renderHeader($comment, $is_html, false); |     $header = $this->renderHeader($comment, $is_html, false); | ||||||
| @@ -430,12 +407,7 @@ final class DifferentialInlineCommentMailView | |||||||
|  |  | ||||||
|     $header = "{$path}:{$range}"; |     $header = "{$path}:{$range}"; | ||||||
|     if ($is_html) { |     if ($is_html) { | ||||||
|       $header = phutil_tag( |       $header = $this->renderHeaderBold($header); | ||||||
|         'span', |  | ||||||
|         array( |  | ||||||
|           'style' => 'color: #4b4d51; font-weight: bold;', |  | ||||||
|         ), |  | ||||||
|         $header); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if ($with_author) { |     if ($with_author) { | ||||||
| @@ -448,12 +420,7 @@ final class DifferentialInlineCommentMailView | |||||||
|       $byline = $author->getName(); |       $byline = $author->getName(); | ||||||
|  |  | ||||||
|       if ($is_html) { |       if ($is_html) { | ||||||
|         $byline = phutil_tag( |         $byline = $this->renderHeaderBold($byline); | ||||||
|           'span', |  | ||||||
|           array( |  | ||||||
|             'style' => 'color: #4b4d51; font-weight: bold;', |  | ||||||
|           ), |  | ||||||
|           $byline); |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       $header = pht('%s wrote in %s', $byline, $header); |       $header = pht('%s wrote in %s', $byline, $header); | ||||||
| @@ -478,22 +445,7 @@ final class DifferentialInlineCommentMailView | |||||||
|         $link = null; |         $link = null; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       $style = array( |       $header = $this->renderHeaderBlock(array($link, $header)); | ||||||
|         'color: #74777d;', |  | ||||||
|         'background: #eff2f4;', |  | ||||||
|         'padding: 6px 8px;', |  | ||||||
|         'overflow: hidden;', |  | ||||||
|       ); |  | ||||||
|  |  | ||||||
|       $header = phutil_tag( |  | ||||||
|         'div', |  | ||||||
|         array( |  | ||||||
|           'style' => implode(' ', $style), |  | ||||||
|         ), |  | ||||||
|         array( |  | ||||||
|           $link, |  | ||||||
|           $header, |  | ||||||
|         )); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return $header; |     return $header; | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								src/applications/differential/mail/DifferentialMailView.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/applications/differential/mail/DifferentialMailView.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | abstract class DifferentialMailView | ||||||
|  |   extends Phobject { | ||||||
|  |  | ||||||
|  |   protected function renderCodeBlock($block) { | ||||||
|  |     $style = array( | ||||||
|  |       'font: 11px/15px "Menlo", "Consolas", "Monaco", monospace;', | ||||||
|  |       'white-space: pre-wrap;', | ||||||
|  |       'clear: both;', | ||||||
|  |       'padding: 4px 0;', | ||||||
|  |       'margin: 0;', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     return phutil_tag( | ||||||
|  |       'div', | ||||||
|  |       array( | ||||||
|  |         'style' => implode(' ', $style), | ||||||
|  |       ), | ||||||
|  |       $block); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected function renderHeaderBlock($block) { | ||||||
|  |     $style = array( | ||||||
|  |       'color: #74777d;', | ||||||
|  |       'background: #eff2f4;', | ||||||
|  |       'padding: 6px 8px;', | ||||||
|  |       'overflow: hidden;', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     return phutil_tag( | ||||||
|  |       'div', | ||||||
|  |       array( | ||||||
|  |         'style' => implode(' ', $style), | ||||||
|  |       ), | ||||||
|  |       $block); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected function renderHeaderBold($content) { | ||||||
|  |     return phutil_tag( | ||||||
|  |       'span', | ||||||
|  |       array( | ||||||
|  |         'style' => 'color: #4b4d51; font-weight: bold;', | ||||||
|  |       ), | ||||||
|  |       $content); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected function renderContentBox($content) { | ||||||
|  |     $style = array( | ||||||
|  |       'border: 1px solid #C7CCD9;', | ||||||
|  |       'border-radius: 3px;', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     return phutil_tag( | ||||||
|  |       'div', | ||||||
|  |       array( | ||||||
|  |         'style' => implode(' ', $style), | ||||||
|  |       ), | ||||||
|  |       $content); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -55,6 +55,7 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|   private $rangeStart; |   private $rangeStart; | ||||||
|   private $rangeEnd; |   private $rangeEnd; | ||||||
|   private $mask; |   private $mask; | ||||||
|  |   private $linesOfContext = 8; | ||||||
|  |  | ||||||
|   private $highlightEngine; |   private $highlightEngine; | ||||||
|  |  | ||||||
| @@ -195,8 +196,6 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|   const ATTR_WHITELINES = 'attr:white'; |   const ATTR_WHITELINES = 'attr:white'; | ||||||
|   const ATTR_MOVEAWAY   = 'attr:moveaway'; |   const ATTR_MOVEAWAY   = 'attr:moveaway'; | ||||||
|  |  | ||||||
|   const LINES_CONTEXT = 8; |  | ||||||
|  |  | ||||||
|   const WHITESPACE_SHOW_ALL         = 'show-all'; |   const WHITESPACE_SHOW_ALL         = 'show-all'; | ||||||
|   const WHITESPACE_IGNORE_TRAILING  = 'ignore-trailing'; |   const WHITESPACE_IGNORE_TRAILING  = 'ignore-trailing'; | ||||||
|   const WHITESPACE_IGNORE_MOST      = 'ignore-most'; |   const WHITESPACE_IGNORE_MOST      = 'ignore-most'; | ||||||
| @@ -227,6 +226,16 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|     return $this; |     return $this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function setLinesOfContext($lines_of_context) { | ||||||
|  |     $this->linesOfContext = $lines_of_context; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getLinesOfContext() { | ||||||
|  |     return $this->linesOfContext; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Configure which Changeset comments added to the right side of the visible |    * Configure which Changeset comments added to the right side of the visible | ||||||
|    * diff will be attached to. The ID must be the ID of a real Differential |    * diff will be attached to. The ID must be the ID of a real Differential | ||||||
| @@ -724,8 +733,10 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|       self::ATTR_MOVEAWAY   => $moveaway, |       self::ATTR_MOVEAWAY   => $moveaway, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|  |     $lines_context = $this->getLinesOfContext(); | ||||||
|  |  | ||||||
|     $hunk_parser->generateIntraLineDiffs(); |     $hunk_parser->generateIntraLineDiffs(); | ||||||
|     $hunk_parser->generateVisibileLinesMask(); |     $hunk_parser->generateVisibileLinesMask($lines_context); | ||||||
|  |  | ||||||
|     $this->setOldLines($hunk_parser->getOldLines()); |     $this->setOldLines($hunk_parser->getOldLines()); | ||||||
|     $this->setNewLines($hunk_parser->getNewLines()); |     $this->setNewLines($hunk_parser->getNewLines()); | ||||||
| @@ -959,6 +970,7 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|     $old_mask = array(); |     $old_mask = array(); | ||||||
|     $new_mask = array(); |     $new_mask = array(); | ||||||
|     $feedback_mask = array(); |     $feedback_mask = array(); | ||||||
|  |     $lines_context = $this->getLinesOfContext(); | ||||||
|  |  | ||||||
|     if ($this->comments) { |     if ($this->comments) { | ||||||
|       // If there are any comments which appear in sections of the file which |       // If there are any comments which appear in sections of the file which | ||||||
| @@ -1001,10 +1013,10 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $start = max($comment->getLineNumber() - self::LINES_CONTEXT, 0); |         $start = max($comment->getLineNumber() - $lines_context, 0); | ||||||
|         $end = $comment->getLineNumber() + |         $end = $comment->getLineNumber() + | ||||||
|           $comment->getLineLength() + |           $comment->getLineLength() + | ||||||
|           self::LINES_CONTEXT; |           $lines_context; | ||||||
|         for ($ii = $start; $ii <= $end; $ii++) { |         for ($ii = $start; $ii <= $end; $ii++) { | ||||||
|           if ($new_side) { |           if ($new_side) { | ||||||
|             $new_mask[$ii] = true; |             $new_mask[$ii] = true; | ||||||
| @@ -1189,6 +1201,8 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|     $range_start, |     $range_start, | ||||||
|     $range_len) { |     $range_len) { | ||||||
|  |  | ||||||
|  |     $lines_context = $this->getLinesOfContext(); | ||||||
|  |  | ||||||
|     // Calculate gaps and mask first |     // Calculate gaps and mask first | ||||||
|     $gaps = array(); |     $gaps = array(); | ||||||
|     $gap_start = 0; |     $gap_start = 0; | ||||||
| @@ -1199,7 +1213,7 @@ final class DifferentialChangesetParser extends Phobject { | |||||||
|       if (isset($base_mask[$ii])) { |       if (isset($base_mask[$ii])) { | ||||||
|         if ($in_gap) { |         if ($in_gap) { | ||||||
|           $gap_length = $ii - $gap_start; |           $gap_length = $ii - $gap_start; | ||||||
|           if ($gap_length <= self::LINES_CONTEXT) { |           if ($gap_length <= $lines_context) { | ||||||
|             for ($jj = $gap_start; $jj <= $gap_start + $gap_length; $jj++) { |             for ($jj = $gap_start; $jj <= $gap_start + $gap_length; $jj++) { | ||||||
|               $base_mask[$jj] = true; |               $base_mask[$jj] = true; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -353,8 +353,7 @@ final class DifferentialHunkParser extends Phobject { | |||||||
|     return $this; |     return $this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public function generateVisibileLinesMask() { |   public function generateVisibileLinesMask($lines_context) { | ||||||
|     $lines_context = DifferentialChangesetParser::LINES_CONTEXT; |  | ||||||
|     $old = $this->getOldLines(); |     $old = $this->getOldLines(); | ||||||
|     $new = $this->getNewLines(); |     $new = $this->getNewLines(); | ||||||
|     $max_length = max(count($old), count($new)); |     $max_length = max(count($old), count($new)); | ||||||
|   | |||||||
| @@ -51,6 +51,16 @@ final class DifferentialChangesetOneUpMailRenderer | |||||||
|   protected function renderPrimitives(array $primitives, $rows) { |   protected function renderPrimitives(array $primitives, $rows) { | ||||||
|     $out = array(); |     $out = array(); | ||||||
|  |  | ||||||
|  |     $context_style = array( | ||||||
|  |       'background: #F7F7F7;', | ||||||
|  |       'color: #74777D;', | ||||||
|  |       'border-style: dashed;', | ||||||
|  |       'border-color: #C7CCD9;', | ||||||
|  |       'border-width: 1px 0;', | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     $context_style = implode(' ', $context_style); | ||||||
|  |  | ||||||
|     foreach ($primitives as $k => $p) { |     foreach ($primitives as $k => $p) { | ||||||
|       $type = $p['type']; |       $type = $p['type']; | ||||||
|       switch ($type) { |       switch ($type) { | ||||||
| @@ -80,6 +90,15 @@ final class DifferentialChangesetOneUpMailRenderer | |||||||
|             'text' => (string)$p['render'], |             'text' => (string)$p['render'], | ||||||
|           ); |           ); | ||||||
|           break; |           break; | ||||||
|  |         case 'context': | ||||||
|  |           // NOTE: These are being included with no text so they get stripped | ||||||
|  |           // in the header and footer. | ||||||
|  |           $out[] = array( | ||||||
|  |             'style' => $context_style, | ||||||
|  |             'render' => '...', | ||||||
|  |             'text' => '', | ||||||
|  |           ); | ||||||
|  |           break; | ||||||
|         default: |         default: | ||||||
|           break; |           break; | ||||||
|       } |       } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley