Render proper "Show Context" links in DocumentEngine diffs, not just bullets

Summary:
Ref T13513. Currently, viewing a Jupyter document, hidden context just gets a plain "* * *" facade with no way to expand it.

Support click-to-expand, like source changes.

Test Plan:
  - Clicked to expand various Jupyter diffs.
  - Clicked to expand normal source changes.

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21243
This commit is contained in:
epriestley 2020-05-12 15:22:41 -07:00
parent e8109e4a92
commit df139f044b
5 changed files with 203 additions and 31 deletions

View file

@ -1084,6 +1084,22 @@ final class DifferentialChangesetParser extends Phobject {
$vs = $id;
}
if ($mask_force) {
$engine_blocks->setRevealedIndexes(array_keys($mask_force));
}
if ($range_start !== null || $range_len !== null) {
$range_min = $range_start;
if ($range_len === null) {
$range_max = null;
} else {
$range_max = (int)$range_start + (int)$range_len;
}
$engine_blocks->setRange($range_min, $range_max);
}
$renderer
->setDocumentEngine($engine)
->setDocumentEngineBlocks($engine_blocks);

View file

@ -496,7 +496,12 @@ abstract class DifferentialChangesetHTMLRenderer
* @param int Total number of lines in the changeset.
* @return markup Rendered links.
*/
protected function renderShowContextLinks($top, $len, $changeset_length) {
protected function renderShowContextLinks(
$top,
$len,
$changeset_length,
$is_blocks = false) {
$block_size = 20;
$end = ($top + $len) - $block_size;
@ -509,12 +514,22 @@ abstract class DifferentialChangesetHTMLRenderer
$links = array();
$block_display = new PhutilNumber($block_size);
if ($is_large_block) {
$is_first_block = ($top == 0);
if ($is_first_block) {
$text = pht('Show First %d Line(s)', $block_size);
if ($is_blocks) {
$text = pht('Show First %s Block(s)', $block_display);
} else {
$text = pht("\xE2\x96\xB2 Show %d Line(s)", $block_size);
$text = pht('Show First %s Line(s)', $block_display);
}
} else {
if ($is_blocks) {
$text = pht("\xE2\x96\xB2 Show %s Block(s)", $block_display);
} else {
$text = pht("\xE2\x96\xB2 Show %s Line(s)", $block_display);
}
}
$links[] = $this->renderShowContextLink(
@ -523,17 +538,31 @@ abstract class DifferentialChangesetHTMLRenderer
$text);
}
if ($is_blocks) {
$text = pht('Show All %s Block(s)', new PhutilNumber($len));
} else {
$text = pht('Show All %s Line(s)', new PhutilNumber($len));
}
$links[] = $this->renderShowContextLink(
true,
"{$top}-{$len}/{$top}-{$len}",
pht('Show All %d Line(s)', $len));
$text);
if ($is_large_block) {
$is_last_block = (($top + $len) >= $changeset_length);
if ($is_last_block) {
$text = pht('Show Last %d Line(s)', $block_size);
if ($is_blocks) {
$text = pht('Show Last %s Block(s)', $block_display);
} else {
$text = "\xE2\x96\xBC ".pht('Show %d Line(s)', $block_size);
$text = pht('Show Last %s Line(s)', $block_display);
}
} else {
if ($is_blocks) {
$text = pht("\xE2\x96\xBC Show %s Block(s)", $block_display);
} else {
$text = pht("\xE2\x96\xBC Show %s Line(s)", $block_display);
}
}
$links[] = $this->renderShowContextLink(

View file

@ -381,22 +381,17 @@ final class DifferentialChangesetTwoUpRenderer
$old_comments = $this->getOldComments();
$new_comments = $this->getNewComments();
$gap_view = javelin_tag(
'tr',
array(
'sigil' => 'context-target',
),
phutil_tag(
'td',
array(
'colspan' => 6,
'class' => 'show-more',
),
pht("\xE2\x80\xA2 \xE2\x80\xA2 \xE2\x80\xA2")));
$rows = array();
$gap = array();
$in_gap = false;
foreach ($block_list->newTwoUpLayout() as $row) {
// NOTE: The generated layout is affected by range constraints, and may
// represent only a slice of the document.
$layout = $block_list->newTwoUpLayout();
$available_count = $block_list->getLayoutAvailableRowCount();
foreach ($layout as $idx => $row) {
list($old, $new) = $row;
if ($old) {
@ -416,13 +411,17 @@ final class DifferentialChangesetTwoUpRenderer
if (!$is_visible) {
if (!$in_gap) {
$in_gap = true;
$rows[] = $gap_view;
}
$gap[$idx] = $row;
continue;
}
if ($in_gap) {
$in_gap = false;
$rows[] = $this->renderDocumentEngineGap(
$gap,
$available_count);
$gap = array();
}
if ($old) {
@ -577,6 +576,12 @@ final class DifferentialChangesetTwoUpRenderer
);
}
if ($in_gap) {
$rows[] = $this->renderDocumentEngineGap(
$gap,
$available_count);
}
$output = $this->wrapChangeInTable($rows);
return $this->renderChangesetTable($output);
@ -616,4 +621,25 @@ final class DifferentialChangesetTwoUpRenderer
);
}
private function renderDocumentEngineGap(array $gap, $available_count) {
$content = $this->renderShowContextLinks(
head_key($gap),
count($gap),
$available_count,
$is_blocks = true);
return javelin_tag(
'tr',
array(
'sigil' => 'context-target',
),
phutil_tag(
'td',
array(
'colspan' => 6,
'class' => 'show-more',
),
$content));
}
}

View file

@ -5,6 +5,29 @@ final class PhabricatorDocumentEngineBlocks
private $lists = array();
private $messages = array();
private $rangeMin;
private $rangeMax;
private $revealedIndexes;
private $layoutAvailableRowCount;
public function setRange($min, $max) {
$this->rangeMin = $min;
$this->rangeMax = $max;
return $this;
}
public function setRevealedIndexes(array $indexes) {
$this->revealedIndexes = $indexes;
return $this;
}
public function getLayoutAvailableRowCount() {
if ($this->layoutAvailableRowCount === null) {
throw new PhutilInvalidStateException('new...Layout');
}
return $this->layoutAvailableRowCount;
}
public function addMessage($message) {
$this->messages[] = $message;
@ -115,6 +138,11 @@ final class PhabricatorDocumentEngineBlocks
);
}
$this->layoutAvailableRowCount = count($rows);
$rows = $this->revealIndexes($rows, true);
$rows = $this->sliceRows($rows);
return $rows;
}
@ -147,6 +175,11 @@ final class PhabricatorDocumentEngineBlocks
$idx++;
}
$this->layoutAvailableRowCount = count($rows);
$rows = $this->revealIndexes($rows, false);
$rows = $this->sliceRows($rows);
return $rows;
}
@ -172,4 +205,47 @@ final class PhabricatorDocumentEngineBlocks
);
}
private function sliceRows(array $rows) {
$min = $this->rangeMin;
$max = $this->rangeMax;
if ($min === null && $max === null) {
return $rows;
}
if ($max === null) {
return array_slice($rows, $min, null, true);
}
if ($min === null) {
$min = 0;
}
return array_slice($rows, $min, $max - $min, true);
}
private function revealIndexes(array $rows, $is_vector) {
if ($this->revealedIndexes === null) {
return $rows;
}
foreach ($this->revealedIndexes as $index) {
if (!isset($rows[$index])) {
continue;
}
if ($is_vector) {
foreach ($rows[$index] as $block) {
if ($block !== null) {
$block->setIsVisible(true);
}
}
} else {
$rows[$index]->setIsVisible(true);
}
}
return $rows;
}
}

View file

@ -1069,29 +1069,54 @@ final class PhabricatorUSEnglishTranslation
),
),
'Show First %d Line(s)' => array(
'Show First %s Line(s)' => array(
'Show First Line',
'Show First %d Lines',
'Show First %s Lines',
),
"\xE2\x96\xB2 Show %d Line(s)" => array(
'Show First %s Block(s)' => array(
'Show First Block',
'Show First %s Blocks',
),
"\xE2\x96\xB2 Show %s Line(s)" => array(
"\xE2\x96\xB2 Show Line",
"\xE2\x96\xB2 Show %d Lines",
"\xE2\x96\xB2 Show %s Lines",
),
'Show All %d Line(s)' => array(
"\xE2\x96\xB2 Show %s Block(s)" => array(
"\xE2\x96\xB2 Show Block",
"\xE2\x96\xB2 Show %s Blocks",
),
'Show All %s Line(s)' => array(
'Show Line',
'Show All %d Lines',
'Show All %s Lines',
),
"\xE2\x96\xBC Show %d Line(s)" => array(
'Show All %s Block(s)' => array(
'Show Block',
'Show All %s Blocks',
),
"\xE2\x96\xBC Show %s Line(s)" => array(
"\xE2\x96\xBC Show Line",
"\xE2\x96\xBC Show %d Lines",
"\xE2\x96\xBC Show %s Lines",
),
'Show Last %d Line(s)' => array(
"\xE2\x96\xBC Show %s Block(s)" => array(
"\xE2\x96\xBC Show Block",
"\xE2\x96\xBC Show %s Blocks",
),
'Show Last %s Line(s)' => array(
'Show Last Line',
'Show Last %d Lines',
'Show Last %s Lines',
),
'Show Last %s Block(s)' => array(
'Show Last Block',
'Show Last %s Blocks',
),
'%s marked %s inline comment(s) as done and %s inline comment(s) as '.