1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 06:42:42 +01:00

Make Paste source code line highlighting behavior more generic

Summary: Depends on D19163. Ref T13088. Increase the generality of this code so it can be shared with Harbormaster.

Test Plan: Clicked individual lines, clicked-and-dragged, etc., in Paste. Got sensible URI and highlight behaviors.

Maniphest Tasks: T13088

Differential Revision: https://secure.phabricator.com/D19164
This commit is contained in:
epriestley 2018-03-01 07:43:53 -08:00
parent 49af4165bc
commit fe3de5dd58
4 changed files with 117 additions and 50 deletions

View file

@ -122,7 +122,7 @@ return array(
'rsrc/css/font/font-lato.css' => 'c7ccd872',
'rsrc/css/font/phui-font-icon-base.css' => '870a7360',
'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97',
'rsrc/css/layout/phabricator-source-code-view.css' => 'aea41829',
'rsrc/css/layout/phabricator-source-code-view.css' => '926ced2d',
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
'rsrc/css/phui/button/phui-button.css' => '1863cc6e',
@ -495,7 +495,7 @@ return array(
'rsrc/js/core/behavior-keyboard-pager.js' => 'a8da01f0',
'rsrc/js/core/behavior-keyboard-shortcuts.js' => '01fca1f0',
'rsrc/js/core/behavior-lightbox-attachments.js' => 'e31fad01',
'rsrc/js/core/behavior-line-linker.js' => '1499a8cb',
'rsrc/js/core/behavior-line-linker.js' => 'c479ac01',
'rsrc/js/core/behavior-more.js' => 'a80d0378',
'rsrc/js/core/behavior-object-selector.js' => '77c1f0b0',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
@ -658,7 +658,7 @@ return array(
'javelin-behavior-phabricator-gesture-example' => '558829c2',
'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0',
'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0',
'javelin-behavior-phabricator-line-linker' => '1499a8cb',
'javelin-behavior-phabricator-line-linker' => 'c479ac01',
'javelin-behavior-phabricator-nav' => '836f966d',
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => '77c1f0b0',
@ -802,7 +802,7 @@ return array(
'phabricator-search-results-css' => '505dd8cf',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => 'aea41829',
'phabricator-source-code-view-css' => '926ced2d',
'phabricator-standard-page-view' => '34ee718b',
'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c',
@ -998,12 +998,6 @@ return array(
'javelin-dom',
'javelin-typeahead-normalizer',
),
'1499a8cb' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-history',
),
'15d5ff71' => array(
'aphront-typeahead-control-css',
'phui-tag-view-css',
@ -1937,6 +1931,12 @@ return array(
'javelin-stratcom',
'phabricator-tooltip',
),
'c479ac01' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-history',
),
'c587b80f' => array(
'javelin-install',
),

View file

@ -73,6 +73,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
pht('...')));
}
$base_uri = (string)$this->uri;
foreach ($lines as $line) {
// NOTE: See phabricator-oncopy behavior.
@ -84,17 +85,16 @@ final class PhabricatorSourceCodeView extends AphrontView {
}
if ($this->canClickHighlight) {
$line_uri = $this->uri.'$'.$line_number;
$line_href = (string)new PhutilURI($line_uri);
$line_href = $base_uri.'$'.$line_number;
$tag_number = javelin_tag(
$tag_number = phutil_tag(
'a',
array(
'href' => $line_href,
),
$line_number);
} else {
$tag_number = javelin_tag(
$tag_number = phutil_tag(
'span',
array(),
$line_number);
@ -104,11 +104,10 @@ final class PhabricatorSourceCodeView extends AphrontView {
'tr',
$row_attributes,
array(
javelin_tag(
phutil_tag(
'th',
array(
'class' => 'phabricator-source-line',
'sigil' => 'phabricator-source-line',
),
$tag_number),
phutil_tag(
@ -134,6 +133,9 @@ final class PhabricatorSourceCodeView extends AphrontView {
array(
'class' => implode(' ', $classes),
'sigil' => 'phabricator-source',
'meta' => array(
'uri' => (string)$this->uri,
),
),
phutil_implode_html('', $rows)));
}

View file

@ -31,7 +31,6 @@
.phabricator-source-line {
background-color: {$paste.highlight};
text-align: right;
padding: 2px 6px 1px 12px;
border-right: 1px solid {$paste.border};
color: {$sh-yellowtext};
@ -48,17 +47,23 @@
th.phabricator-source-line a {
color: {$darkbluetext};
display: block;
padding: 2px 6px 1px 12px;
}
th.phabricator-source-line:hover {
th.phabricator-source-line a:hover {
background: {$paste.border};
cursor: pointer;
text-decoration: none;
}
.phabricator-source-highlight {
background: {$paste.highlight};
}
.phabricator-source-highlight th.phabricator-source-line {
background: {$paste.border};
}
.phabricator-source-code-summary {
padding-bottom: 8px;
}

View file

@ -10,6 +10,7 @@ JX.behavior('phabricator-line-linker', function() {
var origin = null;
var target = null;
var root = null;
var highlighted = null;
var editor_link = null;
try {
@ -19,48 +20,101 @@ JX.behavior('phabricator-line-linker', function() {
}
function getRowNumber(tr) {
var th = JX.DOM.find(tr, 'th', 'phabricator-source-line');
var th = tr.firstChild;
return +(th.textContent || th.innerText);
}
JX.Stratcom.listen(
'mousedown',
'phabricator-source-line',
['click', 'mousedown'],
['phabricator-source', 'tag:tr', 'tag:th', 'tag:a'],
function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
origin = e.getNode('tag:tr');
target = origin;
root = e.getNode('phabricator-source');
e.kill();
});
JX.Stratcom.listen(
'click',
'phabricator-source-line',
function(e) {
// Make sure the link we clicked is actually a line number in a source
// table, not some kind of link in some element embedded inside the
// table. The row's immediate ancestor table needs to be the table with
// the "phabricator-source" sigil.
var row = e.getNode('tag:tr');
var table = e.getNode('phabricator-source');
if (JX.DOM.findAbove(row, 'table') !== table) {
return;
}
var number = getRowNumber(row);
if (!number) {
return;
}
e.kill();
// If this is a click event, kill it. We handle mousedown and mouseup
// instead.
if (e.getType() === 'click') {
return;
}
origin = row;
target = origin;
root = table;
});
var highlight = function(e) {
if (!origin || e.getNode('phabricator-source') !== root) {
if (!origin) {
return;
}
if (e.getNode('phabricator-source') !== root) {
return;
}
target = e.getNode('tag:tr');
var highlighting = false;
var source = null;
var trs = JX.DOM.scry(root, 'tr');
for (var i = 0; i < trs.length; i++) {
if (!highlighting && (trs[i] === origin || trs[i] === target)) {
highlighting = true;
source = trs[i];
var min;
var max;
// NOTE: We're using position to figure out which order these rows are in,
// not row numbers. We do this because Harbormaster build logs may have
// multiple rows with the same row number.
if (JX.$V(origin).y <= JX.$V(target).y) {
min = origin;
max = target;
} else {
min = target;
max = origin;
}
// If we haven't changed highlighting, we don't have a list of highlighted
// nodes yet. Assume every row is highlighted.
var ii;
if (highlighted === null) {
highlighted = [];
var rows = JX.DOM.scry(root, 'tr');
for (ii = 0; ii < rows.length; ii++) {
highlighted.push(rows[ii]);
}
JX.DOM.alterClass(trs[i], 'phabricator-source-highlight', highlighting);
if (trs[i] === (source === origin ? target : origin)) {
highlighting = false;
}
// Unhighlight any existing highlighted rows.
for (ii = 0; ii < highlighted.length; ii++) {
JX.DOM.alterClass(highlighted[ii], 'phabricator-source-highlight', false);
}
highlighted = [];
// Highlight the newly selected rows.
var cursor = min;
while (true) {
JX.DOM.alterClass(cursor, 'phabricator-source-highlight', true);
highlighted.push(cursor);
if (cursor === max) {
break;
}
cursor = cursor.nextSibling;
}
};
@ -75,20 +129,26 @@ JX.behavior('phabricator-line-linker', function() {
}
highlight(e);
e.kill();
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', 'phabricator-source-line');
var uri = JX.DOM.find(th, 'a').href;
uri = uri.replace(/(.*\$)\d+/, '$1' + lines);
var uri = JX.Stratcom.getData(root).uri;
origin = null;
target = null;
e.kill();
root = null;
var lines = (o == t ? o : Math.min(o, t) + '-' + Math.max(o, t));
uri = uri + '$' + lines;
JX.History.replace(uri);
if (editor_link.href) {
var editdata = JX.Stratcom.getData(editor_link);
editor_link.href = editdata.link_template.replace('%25l', o);
if (editor_link) {
if (editor_link.href) {
var editdata = JX.Stratcom.getData(editor_link);
editor_link.href = editdata.link_template.replace('%25l', o);
}
}
});