1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

Make repository symbol references work with DocumentEngine

Summary: Ref T13105. Ref T13047. This makes symbol indexes work with DocumentEngine in Files, and restores support in Diffusion.

Test Plan: Command-clicked stuff, got taken to the symbol index with reasonable metadata in Diffusion, Differential and Files.

Reviewers: mydeveloperday

Reviewed By: mydeveloperday

Maniphest Tasks: T13105, T13047

Differential Revision: https://secure.phabricator.com/D19307
This commit is contained in:
epriestley 2018-04-08 09:10:03 -07:00
parent 0363febeb2
commit 90a614778c
11 changed files with 201 additions and 68 deletions

View file

@ -9,10 +9,10 @@ return array(
'names' => array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
'core.pkg.css' => '29452b31',
'core.pkg.css' => '4a83e174',
'core.pkg.js' => '1ea38af8',
'differential.pkg.css' => '113e692c',
'differential.pkg.js' => 'f6d809c0',
'differential.pkg.js' => '3da2650a',
'diffusion.pkg.css' => 'a2d17c7d',
'diffusion.pkg.js' => '6134c5a1',
'maniphest.pkg.css' => '4845691a',
@ -113,14 +113,14 @@ return array(
'rsrc/css/application/uiexample/example.css' => '528b19de',
'rsrc/css/core/core.css' => '62fa3ace',
'rsrc/css/core/remarkup.css' => '924fc97d',
'rsrc/css/core/syntax.css' => 'cae95e89',
'rsrc/css/core/syntax.css' => 'e9c95dd4',
'rsrc/css/core/z-index.css' => '9d8f7c4b',
'rsrc/css/diviner/diviner-shared.css' => '896f1d43',
'rsrc/css/font/font-awesome.css' => 'e838e088',
'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' => '31ee3c83',
'rsrc/css/layout/phabricator-source-code-view.css' => 'c6fc6834',
'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',
@ -423,7 +423,7 @@ return array(
'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf',
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'a0b57eb8',
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'de2e896f',
'rsrc/js/application/repository/repository-crossreference.js' => '2ab10a76',
'rsrc/js/application/repository/repository-crossreference.js' => '9a860428',
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
@ -676,7 +676,7 @@ return array(
'javelin-behavior-reorder-applications' => '76b9fc3e',
'javelin-behavior-reorder-columns' => 'e1d25dfb',
'javelin-behavior-reorder-profile-menu-items' => 'e2e0a072',
'javelin-behavior-repository-crossreference' => '2ab10a76',
'javelin-behavior-repository-crossreference' => '9a860428',
'javelin-behavior-scrollbar' => '834a1173',
'javelin-behavior-search-reorder-queries' => 'e9581f08',
'javelin-behavior-select-content' => 'bf5374ef',
@ -784,7 +784,7 @@ return array(
'phabricator-search-results-css' => '505dd8cf',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => '31ee3c83',
'phabricator-source-code-view-css' => 'c6fc6834',
'phabricator-standard-page-view' => '34ee718b',
'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c',
@ -884,7 +884,7 @@ return array(
'sprite-login-css' => '396f3c3a',
'sprite-tokens-css' => '9cdfd599',
'syntax-default-css' => '9923583c',
'syntax-highlighting-css' => 'cae95e89',
'syntax-highlighting-css' => 'e9c95dd4',
'tokens-css' => '3d0f239e',
'typeahead-browse-css' => 'f2818435',
'unhandled-exception-css' => '4c96257a',
@ -1050,12 +1050,6 @@ return array(
'javelin-install',
'javelin-util',
),
'2ab10a76' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'javelin-uri',
),
'2ae077e1' => array(
'javelin-behavior',
'javelin-dom',
@ -1683,6 +1677,12 @@ return array(
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'9a860428' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'javelin-uri',
),
'9bbf3762' => array(
'javelin-behavior',
'javelin-dom',
@ -1972,9 +1972,6 @@ return array(
'phabricator-title',
'phabricator-favicon',
),
'cae95e89' => array(
'syntax-default-css',
),
'cd2b9b77' => array(
'phui-oi-list-view-css',
),
@ -2103,6 +2100,9 @@ return array(
'javelin-dom',
'phabricator-draggable-list',
),
'e9c95dd4' => array(
'syntax-default-css',
),
'ec1f3669' => array(
'javelin-behavior',
'javelin-util',

View file

@ -69,4 +69,24 @@ final class DiffusionDocumentRenderingEngine
return;
}
protected function willRenderRef(PhabricatorDocumentRef $ref) {
$ref->setSymbolMetadata($this->getSymbolMetadata());
}
private function getSymbolMetadata() {
$drequest = $this->getDiffusionRequest();
$repo = $drequest->getRepository();
$symbol_repos = nonempty($repo->getSymbolSources(), array());
$symbol_repos[] = $repo->getPHID();
$lang = last(explode('.', $drequest->getPath()));
return array(
'repositories' => $symbol_repos,
'lang' => $lang,
'path' => $drequest->getPath(),
);
}
}

View file

@ -8,6 +8,7 @@ final class PhabricatorDocumentRef
private $file;
private $byteLength;
private $snippet;
private $symbolMetadata = array();
public function setFile(PhabricatorFile $file) {
$this->file = $file;
@ -131,4 +132,15 @@ final class PhabricatorDocumentRef
return $this->snippet;
}
public function setSymbolMetadata(array $metadata) {
$this->symbolMetadata = $metadata;
return $this;
}
public function getSymbolMetadata() {
return $this->symbolMetadata;
}
}

View file

@ -52,7 +52,7 @@ final class PhabricatorJSONDocumentEngine
return array(
$message,
$this->newTextDocumentContent($content),
$this->newTextDocumentContent($ref, $content),
);
}

View file

@ -47,7 +47,7 @@ final class PhabricatorSourceDocumentEngine
return array(
$messages,
$this->newTextDocumentContent($content),
$this->newTextDocumentContent($ref, $content),
);
}

View file

@ -13,12 +13,15 @@ abstract class PhabricatorTextDocumentEngine
return true;
}
protected function newTextDocumentContent($content) {
protected function newTextDocumentContent(
PhabricatorDocumentRef $ref,
$content) {
$lines = phutil_split_lines($content);
$view = id(new PhabricatorSourceCodeView())
->setHighlights($this->getHighlightedLines())
->setLines($lines);
->setLines($lines)
->setSymbolMetadata($ref->getSymbolMetadata());
$message = null;
if ($this->encodingMessage !== null) {

View file

@ -105,6 +105,7 @@ abstract class PhabricatorDocumentRenderingEngine
'renderControlID' => $control_id,
);
} else {
$this->willRenderRef($ref);
$content = $engine->newDocument($ref);
$config = array();
}
@ -158,6 +159,8 @@ abstract class PhabricatorDocumentRenderingEngine
}
final public function newRenderResponse(PhabricatorDocumentRef $ref) {
$this->willRenderRef($ref);
$request = $this->getRequest();
$viewer = $request->getViewer();
@ -290,4 +293,8 @@ abstract class PhabricatorDocumentRenderingEngine
return;
}
protected function willRenderRef(PhabricatorDocumentRef $ref) {
return;
}
}

View file

@ -8,6 +8,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
private $canClickHighlight = true;
private $truncatedFirstBytes = false;
private $truncatedFirstLines = false;
private $symbolMetadata;
public function setLines(array $lines) {
$this->lines = $lines;
@ -39,6 +40,15 @@ final class PhabricatorSourceCodeView extends AphrontView {
return $this;
}
public function setSymbolMetadata(array $symbol_metadata) {
$this->symbolMetadata = $symbol_metadata;
return $this;
}
public function getSymbolMetadata() {
return $this->symbolMetadata;
}
public function render() {
require_celerity_resource('phabricator-source-code-view-css');
require_celerity_resource('syntax-highlighting-css');
@ -130,15 +140,24 @@ final class PhabricatorSourceCodeView extends AphrontView {
$classes[] = 'remarkup-code';
$classes[] = 'PhabricatorMonospaced';
$symbol_metadata = $this->getSymbolMetadata();
$sigils = array();
$sigils[] = 'phabricator-source';
$sigils[] = 'has-symbols';
Javelin::initBehavior('repository-crossreference');
return phutil_tag_div(
'phabricator-source-code-container',
javelin_tag(
'table',
array(
'class' => implode(' ', $classes),
'sigil' => 'phabricator-source',
'sigil' => implode(' ', $sigils),
'meta' => array(
'uri' => (string)$this->uri,
'symbols' => $symbol_metadata,
),
),
phutil_implode_html('', $rows)));

View file

@ -6,11 +6,6 @@
color: #aa0066;
}
.remarkup-code .over-the-line {
color: #aa0066;
margin-right: 1px;
}
.remarkup-code td > span {
display: inline;
word-break: break-all;
@ -24,11 +19,9 @@
.remarkup-code .rbw_i { color: indigo; }
.remarkup-code .rbw_v { color: violet; }
.repository-crossreference .remarkup-code .crossreference-item {
background: lightyellow;
border-bottom: 1px dotted #bbddbb;
}
.crossreference-cursor {
span.crossreference-item {
background: {$lightyellow};
border-bottom: 1px solid {$yellow};
cursor: help;
}

View file

@ -7,7 +7,6 @@
overflow-y: hidden;
border: 1px solid {$paste.border};
border-radius: 3px;
background-color: {$paste.content};
}
.phui-oi .phabricator-source-code-container {

View file

@ -11,12 +11,29 @@ JX.behavior('repository-crossreference', function(config, statics) {
var highlighted;
var linked = [];
var isMac = navigator.platform.indexOf('Mac') > -1;
var signalKey = isMac ? 91 /*COMMAND*/ : 17 /*CTRL*/;
function isSignalkey(event) {
return isMac ?
event.getRawEvent().metaKey :
event.getRawEvent().ctrlKey;
function isMacOS() {
return (navigator.platform.indexOf('Mac') > -1);
}
function isHighlightModifierKey(e) {
var signal_key;
if (isMacOS()) {
// On macOS, use the "Command" key.
signal_key = 91;
} else {
// On other platforms, use the "Control" key.
signal_key = 17;
}
return (e.getRawEvent().keyCode === signal_key);
}
function hasHighlightModifierKey(e) {
if (isMacOS()) {
return e.getRawEvent().metaKey;
} else {
return e.getRawEvent().ctrlKey;
}
}
var classHighlight = 'crossreference-item';
@ -43,7 +60,7 @@ JX.behavior('repository-crossreference', function(config, statics) {
unhighlight();
return;
}
if (!isSignalkey(e)) {
if (!hasHighlightModifierKey(e)) {
return;
}
@ -76,7 +93,7 @@ JX.behavior('repository-crossreference', function(config, statics) {
target = target.parentNode;
}
} else if (e.getType() === 'click') {
openSearch(target, lang);
openSearch(target, {lang: lang});
}
});
}
@ -85,13 +102,24 @@ JX.behavior('repository-crossreference', function(config, statics) {
highlighted = null;
}
function openSearch(target, lang) {
function openSearch(target, context) {
var symbol = target.textContent || target.innerText;
var query = {
lang : lang,
repositories : config.repositories.join(','),
jump : true
};
context = context || {};
context.lang = context.lang || null;
context.repositories =
context.repositories ||
(config && config.repositories) ||
[];
var query = JX.copy({}, context);
if (query.repositories.length) {
query.repositories = query.repositories.join(',');
} else {
delete query.repositories;
}
query.jump = true;
var c = target.className;
c = c.replace(classHighlight, '').trim();
@ -112,10 +140,12 @@ JX.behavior('repository-crossreference', function(config, statics) {
query.line = line;
}
if (!query.hasOwnProperty('path')) {
var path = getPath(target);
if (path !== null) {
query.path = path;
}
}
var char = getChar(target);
if (char !== null) {
@ -124,7 +154,8 @@ JX.behavior('repository-crossreference', function(config, statics) {
var uri = JX.$U('/diffusion/symbol/' + symbol + '/');
uri.addQueryParams(query);
window.open(uri);
window.open(uri.toString());
}
function linkAll() {
@ -188,16 +219,6 @@ JX.behavior('repository-crossreference', function(config, statics) {
// Ignore.
}
// This method works in Diffusion, when viewing the content of a file at
// a particular commit.
var file;
try {
file = JX.DOM.findAbove(target, 'div', 'diffusion-file-content-view');
return JX.Stratcom.getData(file).path;
} catch (ex) {
// Ignore.
}
return null;
}
@ -227,12 +248,6 @@ JX.behavior('repository-crossreference', function(config, statics) {
return null;
}
if (config.container) {
link(JX.$(config.container), config.lang);
} else if (config.section) {
linkAll(JX.$(config.section));
}
JX.Stratcom.listen(
'differential-preview-update',
null,
@ -245,9 +260,10 @@ JX.behavior('repository-crossreference', function(config, statics) {
['keydown', 'keyup'],
null,
function(e) {
if (e.getRawEvent().keyCode !== signalKey) {
if (!isHighlightModifierKey(e)) {
return;
}
setCursorMode(e.getType() === 'keydown');
if (!statics.active) {
@ -272,4 +288,68 @@ JX.behavior('repository-crossreference', function(config, statics) {
JX.DOM.alterClass(element, classMouseCursor, statics.active);
});
}
if (config && config.container) {
link(JX.$(config.container), config.lang);
}
JX.Stratcom.listen(
['mouseover', 'mouseout', 'click'],
['has-symbols', 'tag:span'],
function(e) {
var type = e.getType();
if (type === 'mouseout') {
unhighlight();
return;
}
if (!hasHighlightModifierKey(e)) {
return;
}
var target = e.getTarget();
try {
// If we're in an inline comment, don't link symbols.
if (JX.DOM.findAbove(target, 'div', 'differential-inline-comment')) {
return;
}
} catch (ex) {
// Continue if we're not inside an inline comment.
}
// If only part of the symbol was edited, the symbol name itself will
// have another "<span />" inside of it which highlights only the
// edited part. Skip over it.
if (JX.DOM.isNode(target, 'span') && (target.className === 'bright')) {
target = target.parentNode;
}
if (type === 'click') {
openSearch(target, e.getNodeData('has-symbols').symbols);
e.kill();
return;
}
if (e.getType() === 'mouseover') {
while (target && target !== document.body) {
if (!JX.DOM.isNode(target, 'span')) {
target = target.parentNode;
continue;
}
if (!class_map.hasOwnProperty(target.className)) {
target = target.parentNode;
continue;
}
highlighted = target;
JX.DOM.alterClass(highlighted, classHighlight, true);
break;
}
}
});
});