Page MenuHomePhabricator

D13034.id31426.diff
No OneTemporary

D13034.id31426.diff

diff --git a/webroot/rsrc/css/core/syntax.css b/webroot/rsrc/css/core/syntax.css
--- a/webroot/rsrc/css/core/syntax.css
+++ b/webroot/rsrc/css/core/syntax.css
@@ -131,12 +131,13 @@
.remarkup-code .rbw_i { color: indigo; }
.remarkup-code .rbw_v { color: violet; }
-.repository-crossreference .remarkup-code .nc,
-.repository-crossreference .remarkup-code .na,
-.repository-crossreference .remarkup-code .nf {
- cursor: help;
+.repository-crossreference .remarkup-code .crossreference-item {
+ background: lightyellow;
border-bottom: 1px dotted #bbddbb;
}
+.crossreference-cursor {
+ cursor: help;
+}
.remarkup-code .invisible {
color: #222222;
diff --git a/webroot/rsrc/externals/javelin/lib/DOM.js b/webroot/rsrc/externals/javelin/lib/DOM.js
--- a/webroot/rsrc/externals/javelin/lib/DOM.js
+++ b/webroot/rsrc/externals/javelin/lib/DOM.js
@@ -716,7 +716,7 @@
node.className += ' '+className;
} else if (has && !add) {
node.className = node.className.replace(
- new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' ');
+ new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' ').trim();
}
},
diff --git a/webroot/rsrc/js/application/repository/repository-crossreference.js b/webroot/rsrc/js/application/repository/repository-crossreference.js
--- a/webroot/rsrc/js/application/repository/repository-crossreference.js
+++ b/webroot/rsrc/js/application/repository/repository-crossreference.js
@@ -6,54 +6,87 @@
* javelin-uri
*/
-JX.behavior('repository-crossreference', function(config) {
+JX.behavior('repository-crossreference', function(config, statics) {
- // NOTE: Pretty much everything in this file is a worst practice. We're
- // constrained by the markup generated by the syntax highlighters.
+ 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;
+ }
+
+ var classHighlight = 'crossreference-item';
+ var classMouseCursor = 'crossreference-cursor';
+
+ // TODO maybe move the dictionary part of this list to the server?
+ var class_map = {
+ nc : 'class',
+ nf : 'function',
+ na : null,
+ nb : 'builtin',
+ n : null,
+ };
function link(element, lang) {
JX.DOM.alterClass(element, 'repository-crossreference', true);
+ linked.push(element);
JX.DOM.listen(
element,
- 'click',
+ ['mouseover', 'mouseout', 'click'],
'tag:span',
function(e) {
- var target = e.getTarget();
- var map = {nc : 'class', nf : 'function', na : null};
- while (target !== document.body) {
- if (JX.DOM.isNode(target, 'span') && (target.className in map)) {
- var timeout = function() {
- if (window.getSelection && !window.getSelection().isCollapsed) {
- return;
- }
- var symbol = target.textContent || target.innerText;
- var query = {
- lang : lang,
- repositories : config.repositories.join(','),
- jump : true
- };
- if (map[target.className]) {
- query.type = map[target.className];
- }
- if (target.hasAttribute('data-symbol-context')) {
- query.context = target.getAttribute('data-symbol-context');
- }
- if (target.hasAttribute('data-symbol-name')) {
- symbol = target.getAttribute('data-symbol-name');
- }
- var uri = JX.$U('/diffusion/symbol/' + symbol + '/');
- uri.addQueryParams(query);
- window.open(uri);
- };
- setTimeout(timeout, 250);
- e.kill();
- break;
+ if (e.getType() === 'mouseout') {
+ highlighted && JX.DOM.alterClass(highlighted, classHighlight, false);
+ highlighted = null;
+ return;
+ }
+ if (!isSignalkey(e)) {
+ return;
+ }
+ if (e.getType() === 'mouseover') {
+ var target = e.getTarget();
+ while (target !== document.body) {
+ if (JX.DOM.isNode(target, 'span') &&
+ (target.className in class_map)) {
+ highlighted = target;
+ JX.DOM.alterClass(highlighted, classHighlight, true);
+ break;
+ }
+ target = target.parentNode;
}
- target = target.parentNode;
+ } else if (e.getType() === 'click') {
+ openSearch(highlighted, lang);
}
});
}
+ function openSearch(target, lang) {
+ var symbol = target.textContent || target.innerText;
+ var query = {
+ lang : lang,
+ repositories : config.repositories.join(','),
+ jump : true
+ };
+ var c = target.className;
+ c = c.replace(classHighlight, '').trim();
+ if (class_map[c]) {
+ query.type = class_map[c];
+ }
+ if (target.hasAttribute('data-symbol-context')) {
+ query.context = target.getAttribute('data-symbol-context');
+ }
+ if (target.hasAttribute('data-symbol-name')) {
+ symbol = target.getAttribute('data-symbol-name');
+ }
+ var uri = JX.$U('/diffusion/symbol/' + symbol + '/');
+ uri.addQueryParams(query);
+ window.open(uri);
+ }
+
function linkAll() {
var blocks = JX.DOM.scry(document.body, 'div', 'remarkup-code-block');
for (var i = 0; i < blocks.length; ++i) {
@@ -77,4 +110,21 @@
linkAll(e.getData().container);
});
+ JX.Stratcom.listen(
+ ['keydown', 'keyup'],
+ null,
+ function(e) {
+ if (e.getRawEvent().keyCode !== signalKey) {
+ return;
+ }
+ statics.active = (e.getType() === 'keydown');
+ linked.forEach(function(element) {
+ JX.DOM.alterClass(element, classMouseCursor, statics.active);
+ });
+
+ if (!statics.active) {
+ highlighted && JX.DOM.alterClass(highlighted, classHighlight, false);
+ highlighted = null;
+ }
+ });
});

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 29, 5:05 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7729842
Default Alt Text
D13034.id31426.diff (6 KB)

Event Timeline