mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +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:
parent
49af4165bc
commit
fe3de5dd58
4 changed files with 117 additions and 50 deletions
|
@ -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',
|
||||
),
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue