Path: blob/master/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php
12256 views
<?php12final class DifferentialChangesetOneUpRenderer3extends DifferentialChangesetHTMLRenderer {45private $simpleMode;67public function setSimpleMode($simple_mode) {8$this->simpleMode = $simple_mode;9return $this;10}1112public function getSimpleMode() {13return $this->simpleMode;14}1516public function isOneUpRenderer() {17return true;18}1920protected function getRendererTableClass() {21return 'diff-1up';22}2324public function getRendererKey() {25return '1up';26}2728protected function renderColgroup() {29return phutil_tag('colgroup', array(), array(30phutil_tag('col', array('class' => 'num')),31phutil_tag('col', array('class' => 'num')),32phutil_tag('col', array('class' => 'copy')),33phutil_tag('col', array('class' => 'unified')),34));35}3637public function renderTextChange(38$range_start,39$range_len,40$rows) {4142$primitives = $this->buildPrimitives($range_start, $range_len);43return $this->renderPrimitives($primitives, $rows);44}4546protected function renderPrimitives(array $primitives, $rows) {47list($left_prefix, $right_prefix) = $this->getLineIDPrefixes();4849$is_simple = $this->getSimpleMode();5051$no_copy = phutil_tag('td', array('class' => 'copy'));52$no_coverage = null;5354$column_width = 4;5556$aural_minus = javelin_tag(57'span',58array(59'aural' => true,60'data-aural' => true,61),62'- ');6364$aural_plus = javelin_tag(65'span',66array(67'aural' => true,68'data-aural' => true,69),70'+ ');7172$out = array();73foreach ($primitives as $k => $p) {74$type = $p['type'];75switch ($type) {76case 'old':77case 'new':78case 'old-file':79case 'new-file':80$is_old = ($type == 'old' || $type == 'old-file');8182$cells = array();83if ($is_old) {84if ($p['htype']) {85if ($p['htype'] === '\\') {86$class = 'comment';87} else if (empty($p['oline'])) {88$class = 'left old old-full';89} else {90$class = 'left old';91}92$aural = $aural_minus;93} else {94$class = 'left';95$aural = null;96}9798if ($type == 'old-file') {99$class = "{$class} differential-old-image";100}101102if ($left_prefix) {103$left_id = $left_prefix.$p['line'];104} else {105$left_id = null;106}107108$line = $p['line'];109110$cells[] = phutil_tag(111'td',112array(113'id' => $left_id,114'class' => $class.' n',115'data-n' => $line,116));117118$render = $p['render'];119if ($aural !== null) {120$render = array($aural, $render);121}122123$cells[] = phutil_tag(124'td',125array(126'class' => $class.' n',127));128$cells[] = $no_copy;129$cells[] = phutil_tag('td', array('class' => $class), $render);130$cells[] = $no_coverage;131} else {132if ($p['htype']) {133if ($p['htype'] === '\\') {134$class = 'comment';135} else if (empty($p['oline'])) {136$class = 'right new new-full';137} else {138$class = 'right new';139}140$cells[] = phutil_tag(141'td',142array(143'class' => $class.' n',144));145$aural = $aural_plus;146} else {147$class = 'right';148if ($left_prefix) {149$left_id = $left_prefix.$p['oline'];150} else {151$left_id = null;152}153154$oline = $p['oline'];155156$cells[] = phutil_tag(157'td',158array(159'id' => $left_id,160'class' => 'n',161'data-n' => $oline,162));163$aural = null;164}165166if ($type == 'new-file') {167$class = "{$class} differential-new-image";168}169170if ($right_prefix) {171$right_id = $right_prefix.$p['line'];172} else {173$right_id = null;174}175176$line = $p['line'];177178$cells[] = phutil_tag(179'td',180array(181'id' => $right_id,182'class' => $class.' n',183'data-n' => $line,184));185186$render = $p['render'];187if ($aural !== null) {188$render = array($aural, $render);189}190191$cells[] = $no_copy;192193$cells[] = phutil_tag(194'td',195array(196'class' => $class,197'data-copy-mode' => 'copy-unified',198),199$render);200201$cells[] = $no_coverage;202}203204// In simple mode, only render the text. This is used to render205// "Edit Suggestions" in inline comments.206if ($is_simple) {207$cells = array($cells[3]);208}209210$out[] = phutil_tag('tr', array(), $cells);211212break;213case 'inline':214$inline = $this->buildInlineComment(215$p['comment'],216$p['right']);217$out[] = $this->getRowScaffoldForInline($inline);218break;219case 'no-context':220$out[] = phutil_tag(221'tr',222array(),223phutil_tag(224'td',225array(226'class' => 'show-more',227'colspan' => $column_width,228),229pht('Context not available.')));230break;231case 'context':232$top = $p['top'];233$len = $p['len'];234235$links = $this->renderShowContextLinks($top, $len, $rows);236237$out[] = javelin_tag(238'tr',239array(240'sigil' => 'context-target',241),242phutil_tag(243'td',244array(245'class' => 'show-more',246'colspan' => $column_width,247),248$links));249break;250default:251$out[] = hsprintf('<tr><th /><th /><td>%s</td></tr>', $type);252break;253}254}255256$result = null;257258if ($out) {259if ($is_simple) {260$result = $this->newSimpleTable($out);261} else {262$result = $this->wrapChangeInTable(phutil_implode_html('', $out));263}264}265266return $result;267}268269public function renderDocumentEngineBlocks(270PhabricatorDocumentEngineBlocks $block_list,271$old_changeset_key,272$new_changeset_key) {273274$engine = $this->getDocumentEngine();275$layout = $block_list->newTwoUpLayout();276277$old_comments = $this->getOldComments();278$new_comments = $this->getNewComments();279280$unchanged = array();281foreach ($layout as $key => $row) {282list($old, $new) = $row;283284if (!$old) {285continue;286}287288if (!$new) {289continue;290}291292if ($old->getDifferenceType() !== null) {293continue;294}295296if ($new->getDifferenceType() !== null) {297continue;298}299300$unchanged[$key] = true;301}302303$rows = array();304$count = count($layout);305for ($ii = 0; $ii < $count;) {306$start = $ii;307308for ($jj = $ii; $jj < $count; $jj++) {309list($old, $new) = $layout[$jj];310311if (empty($unchanged[$jj])) {312break;313}314315$rows[] = array(316'type' => 'unchanged',317'layoutKey' => $jj,318);319}320$ii = $jj;321322for ($jj = $ii; $jj < $count; $jj++) {323list($old, $new) = $layout[$jj];324325if (!empty($unchanged[$jj])) {326break;327}328329$rows[] = array(330'type' => 'old',331'layoutKey' => $jj,332);333}334335for ($jj = $ii; $jj < $count; $jj++) {336list($old, $new) = $layout[$jj];337338if (!empty($unchanged[$jj])) {339break;340}341342$rows[] = array(343'type' => 'new',344'layoutKey' => $jj,345);346}347$ii = $jj;348349// We always expect to consume at least one row when iterating through350// the loop and make progress. If we don't, bail out to avoid spinning351// to death.352if ($ii === $start) {353throw new Exception(354pht(355'Failed to make progress during 1up diff layout.'));356}357}358359$old_ref = null;360$new_ref = null;361$refs = $block_list->getDocumentRefs();362if ($refs) {363list($old_ref, $new_ref) = $refs;364}365366$view = array();367foreach ($rows as $row) {368$row_type = $row['type'];369$layout_key = $row['layoutKey'];370$row_layout = $layout[$layout_key];371list($old, $new) = $row_layout;372373if ($old) {374$old_key = $old->getBlockKey();375} else {376$old_key = null;377}378379if ($new) {380$new_key = $new->getBlockKey();381} else {382$new_key = null;383}384385$cells = array();386$cell_classes = array();387388if ($row_type === 'unchanged') {389$cell_content = $engine->newBlockContentView(390$old_ref,391$old);392} else if ($old && $new) {393$block_diff = $engine->newBlockDiffViews(394$old_ref,395$old,396$new_ref,397$new);398399// TODO: We're currently double-rendering this: once when building400// the old row, and once when building the new one. In both cases,401// we throw away the other half of the output. We could cache this402// to improve performance.403404if ($row_type === 'old') {405$cell_content = $block_diff->getOldContent();406$cell_classes = $block_diff->getOldClasses();407} else {408$cell_content = $block_diff->getNewContent();409$cell_classes = $block_diff->getNewClasses();410}411} else if ($row_type === 'old') {412if (!$old_ref || !$old) {413continue;414}415416$cell_content = $engine->newBlockContentView(417$old_ref,418$old);419420$cell_classes[] = 'old';421$cell_classes[] = 'old-full';422423$new_key = null;424} else if ($row_type === 'new') {425if (!$new_ref || !$new) {426continue;427}428429$cell_content = $engine->newBlockContentView(430$new_ref,431$new);432433$cell_classes[] = 'new';434$cell_classes[] = 'new-full';435436$old_key = null;437}438439if ($old_key === null) {440$old_id = null;441} else {442$old_id = "C{$old_changeset_key}OL{$old_key}";443}444445if ($new_key === null) {446$new_id = null;447} else {448$new_id = "C{$new_changeset_key}NL{$new_key}";449}450451$cells[] = phutil_tag(452'td',453array(454'id' => $old_id,455'data-n' => $old_key,456'class' => 'n',457));458459$cells[] = phutil_tag(460'td',461array(462'id' => $new_id,463'data-n' => $new_key,464'class' => 'n',465));466467$cells[] = phutil_tag(468'td',469array(470'class' => 'copy',471));472473$cell_classes[] = 'diff-flush';474$cell_classes = implode(' ', $cell_classes);475476$cells[] = phutil_tag(477'td',478array(479'class' => $cell_classes,480'data-copy-mode' => 'copy-unified',481),482$cell_content);483484$view[] = phutil_tag(485'tr',486array(),487$cells);488489if ($old_key !== null) {490$old_inlines = idx($old_comments, $old_key, array());491foreach ($old_inlines as $inline) {492$inline = $this->buildInlineComment(493$inline,494$on_right = false);495$view[] = $this->getRowScaffoldForInline($inline);496}497}498499if ($new_key !== null) {500$new_inlines = idx($new_comments, $new_key, array());501foreach ($new_inlines as $inline) {502$inline = $this->buildInlineComment(503$inline,504$on_right = true);505$view[] = $this->getRowScaffoldForInline($inline);506}507}508}509510$output = $this->wrapChangeInTable($view);511return $this->renderChangesetTable($output);512}513514public function getRowScaffoldForInline(PHUIDiffInlineCommentView $view) {515return id(new PHUIDiffOneUpInlineCommentRowScaffold())516->addInlineView($view);517}518519520private function newSimpleTable($content) {521return phutil_tag(522'table',523array(524'class' => 'diff-1up-simple-table',525),526$content);527}528529}530531532