diff --git a/src/applications/differential/render/DifferentialChangesetHTMLRenderer.php b/src/applications/differential/render/DifferentialChangesetHTMLRenderer.php --- a/src/applications/differential/render/DifferentialChangesetHTMLRenderer.php +++ b/src/applications/differential/render/DifferentialChangesetHTMLRenderer.php @@ -439,4 +439,92 @@ ->setAllowReply($allow_reply); } + + /** + * Build links which users can click to show more context in a changeset. + * + * @param int Beginning of the line range to build links for. + * @param int Length of the line range to build links for. + * @param int Total number of lines in the changeset. + * @return markup Rendered links. + */ + protected function renderShowContextLinks($top, $len, $changeset_length) { + $block_size = 20; + $end = ($top + $len) - $block_size; + + // If this is a large block, such that the "top" and "bottom" ranges are + // non-overlapping, we'll provide options to show the top, bottom or entire + // block. For smaller blocks, we only provide an option to show the entire + // block, since it would be silly to show the bottom 20 lines of a 25-line + // block. + $is_large_block = ($len > ($block_size * 2)); + + $links = array(); + + if ($is_large_block) { + $is_first_block = ($top == 0); + if ($is_first_block) { + $text = pht('Show First %d Line(s)', $block_size); + } else { + $text = pht("\xE2\x96\xB2 Show %d Line(s)", $block_size); + } + + $links[] = $this->renderShowContextLink( + false, + "{$top}-{$len}/{$top}-20", + $text); + } + + $links[] = $this->renderShowContextLink( + true, + "{$top}-{$len}/{$top}-{$len}", + pht('Show All %d Line(s)', $len)); + + if ($is_large_block) { + $is_last_block = (($top + $len) >= $changeset_length); + if ($is_last_block) { + $text = pht('Show Last %d Line(s)', $block_size); + } else { + $text = pht("\xE2\x96\xBC Show %d Line(s)", $block_size); + } + + $links[] = $this->renderShowContextLink( + false, + "{$top}-{$len}/{$end}-20", + $text); + } + + return phutil_implode_html(" \xE2\x80\xA2 ", $links); + } + + + /** + * Build a link that shows more context in a changeset. + * + * See @{method:renderShowContextLinks}. + * + * @param bool Does this link show all context when clicked? + * @param string Range specification for lines to show. + * @param string Text of the link. + * @return markup Rendered link. + */ + private function renderShowContextLink($is_all, $range, $text) { + $reference = $this->getRenderingReference(); + + return javelin_tag( + 'a', + array( + 'href' => '#', + 'mustcapture' => true, + 'sigil' => 'show-more', + 'meta' => array( + 'type' => ($is_all ? 'all' : null), + 'ref' => $reference, + 'range' => $range, + ), + ), + $text); + } + + } diff --git a/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php b/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php --- a/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php +++ b/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php @@ -69,9 +69,28 @@ break; case 'no-context': $out[] = hsprintf( - '<tr><td class="show-more" colspan="3">%s</th></tr>', + '<tr><td class="show-more" colspan="3">%s</td></tr>', pht('Context not available.')); break; + case 'context': + $top = $p['top']; + $len = $p['len']; + + $links = $this->renderShowContextLinks($top, $len, $rows); + + $out[] = javelin_tag( + 'tr', + array( + 'sigil' => 'context-target', + ), + phutil_tag( + 'td', + array( + 'class' => 'show-more', + 'colspan' => 3, + ), + $links)); + break; default: $out[] = hsprintf('<tr><th /><th /><td>%s</td></tr>', $type); break; diff --git a/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php b/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php --- a/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php +++ b/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php @@ -84,6 +84,9 @@ // increments $ii by the entire size of the gap and then continues // the loop. $gap = array_pop($gaps); + + // TODO: Move this to renderShowContextLinks() once that is stable. + $top = $gap[0]; $len = $gap[1]; diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -941,6 +941,32 @@ 'allowed domains will be able to register an account: %3$s', ), ), + + 'Show First %d Line(s)' => array( + 'Show First Line', + 'Show First %d Lines', + ), + + "\xE2\x96\xB2 Show %d Line(s)" => array( + "\xE2\x96\xB2 Show %d Line(s)", + "\xE2\x96\xB2 Show %d Line(s)", + ), + + 'Show All %d Line(s)' => array( + 'Show Line', + 'Show All %d Lines', + ), + + "\xE2\x96\xBC Show %d Line(s)" => array( + "\xE2\x96\xBC Show Line", + "\xE2\x96\xBC Show %d Lines", + ), + + 'Show Last %d Line(s)' => array( + 'Show Last Line', + 'Show Last %d Lines', + ), + ); }