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

View file

@ -69,4 +69,24 @@ final class DiffusionDocumentRenderingEngine
return; 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 $file;
private $byteLength; private $byteLength;
private $snippet; private $snippet;
private $symbolMetadata = array();
public function setFile(PhabricatorFile $file) { public function setFile(PhabricatorFile $file) {
$this->file = $file; $this->file = $file;
@ -131,4 +132,15 @@ final class PhabricatorDocumentRef
return $this->snippet; 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( return array(
$message, $message,
$this->newTextDocumentContent($content), $this->newTextDocumentContent($ref, $content),
); );
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,12 +11,29 @@ JX.behavior('repository-crossreference', function(config, statics) {
var highlighted; var highlighted;
var linked = []; var linked = [];
var isMac = navigator.platform.indexOf('Mac') > -1; function isMacOS() {
var signalKey = isMac ? 91 /*COMMAND*/ : 17 /*CTRL*/; return (navigator.platform.indexOf('Mac') > -1);
function isSignalkey(event) { }
return isMac ?
event.getRawEvent().metaKey : function isHighlightModifierKey(e) {
event.getRawEvent().ctrlKey; 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'; var classHighlight = 'crossreference-item';
@ -43,7 +60,7 @@ JX.behavior('repository-crossreference', function(config, statics) {
unhighlight(); unhighlight();
return; return;
} }
if (!isSignalkey(e)) { if (!hasHighlightModifierKey(e)) {
return; return;
} }
@ -76,7 +93,7 @@ JX.behavior('repository-crossreference', function(config, statics) {
target = target.parentNode; target = target.parentNode;
} }
} else if (e.getType() === 'click') { } 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; highlighted = null;
} }
function openSearch(target, lang) { function openSearch(target, context) {
var symbol = target.textContent || target.innerText; var symbol = target.textContent || target.innerText;
var query = {
lang : lang, context = context || {};
repositories : config.repositories.join(','), context.lang = context.lang || null;
jump : true 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; var c = target.className;
c = c.replace(classHighlight, '').trim(); c = c.replace(classHighlight, '').trim();
@ -112,9 +140,11 @@ JX.behavior('repository-crossreference', function(config, statics) {
query.line = line; query.line = line;
} }
var path = getPath(target); if (!query.hasOwnProperty('path')) {
if (path !== null) { var path = getPath(target);
query.path = path; if (path !== null) {
query.path = path;
}
} }
var char = getChar(target); var char = getChar(target);
@ -124,7 +154,8 @@ JX.behavior('repository-crossreference', function(config, statics) {
var uri = JX.$U('/diffusion/symbol/' + symbol + '/'); var uri = JX.$U('/diffusion/symbol/' + symbol + '/');
uri.addQueryParams(query); uri.addQueryParams(query);
window.open(uri);
window.open(uri.toString());
} }
function linkAll() { function linkAll() {
@ -188,16 +219,6 @@ JX.behavior('repository-crossreference', function(config, statics) {
// Ignore. // 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; return null;
} }
@ -227,12 +248,6 @@ JX.behavior('repository-crossreference', function(config, statics) {
return null; return null;
} }
if (config.container) {
link(JX.$(config.container), config.lang);
} else if (config.section) {
linkAll(JX.$(config.section));
}
JX.Stratcom.listen( JX.Stratcom.listen(
'differential-preview-update', 'differential-preview-update',
null, null,
@ -245,9 +260,10 @@ JX.behavior('repository-crossreference', function(config, statics) {
['keydown', 'keyup'], ['keydown', 'keyup'],
null, null,
function(e) { function(e) {
if (e.getRawEvent().keyCode !== signalKey) { if (!isHighlightModifierKey(e)) {
return; return;
} }
setCursorMode(e.getType() === 'keydown'); setCursorMode(e.getType() === 'keydown');
if (!statics.active) { if (!statics.active) {
@ -272,4 +288,68 @@ JX.behavior('repository-crossreference', function(config, statics) {
JX.DOM.alterClass(element, classMouseCursor, statics.active); 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;
}
}
});
}); });