mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-27 15:08:20 +01:00
Line highlighting for pastes
Summary: Add the ability to select singular and multiple lines in paste to highlight. This is related to T3627 Test Plan: Create a paste, select one or more lines. Reviewers: epriestley, tberman Reviewed By: epriestley CC: aran, chad Maniphest Tasks: T3627 Differential Revision: https://secure.phabricator.com/D6668
This commit is contained in:
parent
a5f790e192
commit
40cf765ca2
9 changed files with 98 additions and 48 deletions
|
@ -1140,7 +1140,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'diffusion-source-css' =>
|
||||
array(
|
||||
'uri' => '/res/e76bcd50/rsrc/css/application/diffusion/diffusion-source.css',
|
||||
'uri' => '/res/162c8794/rsrc/css/application/diffusion/diffusion-source.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1667,19 +1667,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/diffusion/behavior-jump-to.js',
|
||||
),
|
||||
'javelin-behavior-diffusion-line-linker' =>
|
||||
array(
|
||||
'uri' => '/res/12866f13/rsrc/js/application/diffusion/behavior-line-linker.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-dom',
|
||||
3 => 'javelin-history',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/diffusion/behavior-line-linker.js',
|
||||
),
|
||||
'javelin-behavior-diffusion-pull-lastmodified' =>
|
||||
array(
|
||||
'uri' => '/res/29fe2790/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
|
||||
|
@ -2067,6 +2054,19 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/core/behavior-keyboard-shortcuts.js',
|
||||
),
|
||||
'javelin-behavior-phabricator-line-linker' =>
|
||||
array(
|
||||
'uri' => '/res/1cefdb6a/rsrc/js/core/behavior-line-linker.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-dom',
|
||||
3 => 'javelin-history',
|
||||
),
|
||||
'disk' => '/rsrc/js/core/behavior-line-linker.js',
|
||||
),
|
||||
'javelin-behavior-phabricator-nav' =>
|
||||
array(
|
||||
'uri' => '/res/afabcf16/rsrc/js/core/behavior-phabricator-nav.js',
|
||||
|
@ -2249,7 +2249,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-pholio-mock-view' =>
|
||||
array(
|
||||
'uri' => '/res/3ff82e28/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
|
||||
'uri' => '/res/f9588dcf/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -3498,7 +3498,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-source-code-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/979d5280/rsrc/css/layout/phabricator-source-code-view.css',
|
||||
'uri' => '/res/70bcbea4/rsrc/css/layout/phabricator-source-code-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
|
|
@ -241,7 +241,7 @@ final class DiffusionBrowseFileController extends DiffusionController {
|
|||
'table',
|
||||
array(
|
||||
'class' => "diffusion-source remarkup-code PhabricatorMonospaced",
|
||||
'sigil' => 'diffusion-source',
|
||||
'sigil' => 'phabricator-source',
|
||||
),
|
||||
$rows);
|
||||
|
||||
|
@ -728,12 +728,12 @@ final class DiffusionBrowseFileController extends DiffusionController {
|
|||
'th',
|
||||
array(
|
||||
'class' => 'diffusion-line-link',
|
||||
'sigil' => 'diffusion-line-link',
|
||||
'sigil' => 'phabricator-source-line',
|
||||
'style' => $style,
|
||||
),
|
||||
$line_link);
|
||||
|
||||
Javelin::initBehavior('diffusion-line-linker');
|
||||
Javelin::initBehavior('phabricator-line-linker');
|
||||
|
||||
if ($line['target']) {
|
||||
Javelin::initBehavior(
|
||||
|
@ -768,7 +768,9 @@ final class DiffusionBrowseFileController extends DiffusionController {
|
|||
$rows[] = phutil_tag(
|
||||
'tr',
|
||||
array(
|
||||
'class' => ($line['highlighted'] ? 'highlighted' : null),
|
||||
'class' => ($line['highlighted'] ?
|
||||
'phabricator-source-highlight' :
|
||||
null),
|
||||
),
|
||||
$blame);
|
||||
|
||||
|
|
|
@ -33,12 +33,13 @@ final class PhabricatorApplicationPaste extends PhabricatorApplication {
|
|||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/P(?P<id>[1-9]\d*)' => 'PhabricatorPasteViewController',
|
||||
'/P(?P<id>[1-9]\d*)(?:\$(?P<lines>\d+(?:-\d+)?))?'
|
||||
=> 'PhabricatorPasteViewController',
|
||||
'/paste/' => array(
|
||||
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController',
|
||||
'create/' => 'PhabricatorPasteEditController',
|
||||
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController',
|
||||
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteCommentController',
|
||||
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteCommentController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,13 +42,16 @@ abstract class PhabricatorPasteController extends PhabricatorController {
|
|||
|
||||
public function buildSourceCodeView(
|
||||
PhabricatorPaste $paste,
|
||||
$max_lines = null) {
|
||||
$max_lines = null,
|
||||
$highlights = array()) {
|
||||
|
||||
$lines = phutil_split_lines($paste->getContent());
|
||||
|
||||
return id(new PhabricatorSourceCodeView())
|
||||
->setLimit($max_lines)
|
||||
->setLines($lines);
|
||||
->setLines($lines)
|
||||
->setHighlights($highlights)
|
||||
->setURI(new PhutilURI($paste->getURI()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
final class PhabricatorPasteViewController extends PhabricatorPasteController {
|
||||
|
||||
private $id;
|
||||
private $highlightMap;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
|
@ -13,6 +14,21 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
|
|||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
$raw_lines = idx($data, 'lines');
|
||||
$map = array();
|
||||
if ($raw_lines) {
|
||||
$lines = explode('-', $raw_lines);
|
||||
$first = idx($lines, 0, 0);
|
||||
$last = idx($lines, 1);
|
||||
if ($last) {
|
||||
$min = min($first, $last);
|
||||
$max = max($first, $last);
|
||||
$map = array_fuse(range($min, $max));
|
||||
} else {
|
||||
$map[$first] = $first;
|
||||
}
|
||||
}
|
||||
$this->highlightMap = $map;
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
@ -52,7 +68,10 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
|
|||
$header = $this->buildHeaderView($paste);
|
||||
$actions = $this->buildActionView($user, $paste, $file);
|
||||
$properties = $this->buildPropertyView($paste, $fork_phids);
|
||||
$source_code = $this->buildSourceCodeView($paste);
|
||||
$source_code = $this->buildSourceCodeView(
|
||||
$paste,
|
||||
null,
|
||||
$this->highlightMap);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView())
|
||||
->setActionList($actions)
|
||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
|
|||
|
||||
private $lines;
|
||||
private $limit;
|
||||
private $uri;
|
||||
private $highlights = array();
|
||||
|
||||
public function setLimit($limit) {
|
||||
|
@ -16,8 +17,13 @@ final class PhabricatorSourceCodeView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setHighlights(array $highlights) {
|
||||
$this->highlights = array_fuse($highlights);
|
||||
public function setURI(PhutilURI $uri) {
|
||||
$this->uri = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHighlights(array $array) {
|
||||
$this->highlights = array_fuse($array);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -26,10 +32,12 @@ final class PhabricatorSourceCodeView extends AphrontView {
|
|||
require_celerity_resource('syntax-highlighting-css');
|
||||
|
||||
Javelin::initBehavior('phabricator-oncopy', array());
|
||||
Javelin::initBehavior('phabricator-line-linker');
|
||||
|
||||
$line_number = 1;
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($this->lines as $line) {
|
||||
$hit_limit = $this->limit &&
|
||||
($line_number == $this->limit) &&
|
||||
|
@ -53,16 +61,33 @@ final class PhabricatorSourceCodeView extends AphrontView {
|
|||
$row_attributes['class'] = 'phabricator-source-highlight';
|
||||
}
|
||||
|
||||
// TODO: Provide nice links.
|
||||
$line_uri = $this->uri . "$" . $line_number;
|
||||
$line_href = (string) new PhutilURI($line_uri);
|
||||
|
||||
$tag_number = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $line_href
|
||||
),
|
||||
$line_number);
|
||||
|
||||
$rows[] = phutil_tag(
|
||||
'tr',
|
||||
$row_attributes,
|
||||
hsprintf(
|
||||
'<th class="phabricator-source-line">%s</th>'.
|
||||
'<td class="phabricator-source-code">%s</td>',
|
||||
$content_number,
|
||||
$content_line));
|
||||
array(
|
||||
javelin_tag(
|
||||
'th',
|
||||
array(
|
||||
'class' => 'phabricator-source-line',
|
||||
'sigil' => 'phabricator-source-line'
|
||||
),
|
||||
$tag_number),
|
||||
phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phabricator-source-code'
|
||||
),
|
||||
$content_line)));
|
||||
|
||||
if ($hit_limit) {
|
||||
break;
|
||||
|
@ -81,10 +106,11 @@ final class PhabricatorSourceCodeView extends AphrontView {
|
|||
array(
|
||||
'class' => 'phabricator-source-code-container',
|
||||
),
|
||||
phutil_tag(
|
||||
javelin_tag(
|
||||
'table',
|
||||
array(
|
||||
'class' => implode(' ', $classes),
|
||||
'sigil' => 'phabricator-source'
|
||||
),
|
||||
phutil_implode_html('', $rows)));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
font-size: 10px;
|
||||
}
|
||||
|
||||
.diffusion-source tr.highlighted {
|
||||
.diffusion-source tr.phabricator-source-highlight {
|
||||
background: #ffff00;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
.phabricator-source-code {
|
||||
white-space: pre-wrap;
|
||||
padding: 2px 8px 1px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.phabricator-source-line {
|
||||
|
|
|
@ -1,44 +1,43 @@
|
|||
/**
|
||||
* @provides javelin-behavior-diffusion-line-linker
|
||||
* @provides javelin-behavior-phabricator-line-linker
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-dom
|
||||
* javelin-history
|
||||
*/
|
||||
|
||||
JX.behavior('diffusion-line-linker', function() {
|
||||
|
||||
JX.behavior('phabricator-line-linker', function() {
|
||||
var origin = null;
|
||||
var target = null;
|
||||
var root = null;
|
||||
|
||||
function getRowNumber(tr) {
|
||||
var th = JX.DOM.find(tr, 'th', 'diffusion-line-link');
|
||||
var th = JX.DOM.find(tr, 'th', 'phabricator-source-line');
|
||||
return +(th.textContent || th.innerText);
|
||||
}
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'mousedown',
|
||||
'diffusion-line-link',
|
||||
'phabricator-source-line',
|
||||
function(e) {
|
||||
if (e.isRightButton()) {
|
||||
if (!e.isNormalMouseEvent()) {
|
||||
return;
|
||||
}
|
||||
origin = e.getNode('tag:tr');
|
||||
target = origin;
|
||||
root = e.getNode('diffusion-source');
|
||||
root = e.getNode('phabricator-source');
|
||||
e.kill();
|
||||
});
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'click',
|
||||
'diffusion-line-link',
|
||||
'phabricator-source-line',
|
||||
function(e) {
|
||||
e.kill();
|
||||
});
|
||||
|
||||
var highlight = function(e) {
|
||||
if (!origin || e.getNode('diffusion-source') !== root) {
|
||||
if (!origin || e.getNode('phabricator-source') !== root) {
|
||||
return;
|
||||
}
|
||||
target = e.getNode('tag:tr');
|
||||
|
@ -51,14 +50,14 @@ JX.behavior('diffusion-line-linker', function() {
|
|||
highlighting = true;
|
||||
source = trs[i];
|
||||
}
|
||||
JX.DOM.alterClass(trs[i], 'highlighted', highlighting);
|
||||
JX.DOM.alterClass(trs[i], 'phabricator-source-highlight', highlighting);
|
||||
if (trs[i] === (source === origin ? target : origin)) {
|
||||
highlighting = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JX.Stratcom.listen('mouseover', 'diffusion-source', highlight);
|
||||
JX.Stratcom.listen('mouseover', 'phabricator-source', highlight);
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'mouseup',
|
||||
|
@ -73,10 +72,9 @@ JX.behavior('diffusion-line-linker', function() {
|
|||
var o = getRowNumber(origin);
|
||||
var t = getRowNumber(target);
|
||||
var lines = (o == t ? o : Math.min(o, t) + '-' + Math.max(o, t));
|
||||
var th = JX.DOM.find(origin, 'th', 'diffusion-line-link');
|
||||
var th = JX.DOM.find(origin, 'th', 'phabricator-source-line');
|
||||
var uri = JX.DOM.find(th, 'a').href;
|
||||
uri = uri.replace(/(.*\$)\d+/, '$1' + lines);
|
||||
|
||||
origin = null;
|
||||
target = null;
|
||||
e.kill();
|
Loading…
Add table
Reference in a new issue