Summary: Fixes T8501. When losing focus while holding ctrl, we never get a key-up event; ctrl-f/d/tab make the browser tab lose focus. So treat 'blur' (unfocus) as if the user released ctrl. Test Plan: ctrl-f/ctrl-d/ctrl-tab, ctrl-click-outside-of-window, and move mouse over the content - see no help suggestions. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley Maniphest Tasks: T8501 Differential Revision: https://secure.phabricator.com/D13260
149 lines
3.7 KiB
JavaScript
149 lines
3.7 KiB
JavaScript
/**
|
|
* @provides javelin-behavior-repository-crossreference
|
|
* @requires javelin-behavior
|
|
* javelin-dom
|
|
* javelin-stratcom
|
|
* javelin-uri
|
|
*/
|
|
|
|
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;
|
|
}
|
|
|
|
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,
|
|
['mouseover', 'mouseout', 'click'],
|
|
'tag:span',
|
|
function(e) {
|
|
if (e.getType() === 'mouseout') {
|
|
unhighlight();
|
|
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;
|
|
}
|
|
} else if (e.getType() === 'click') {
|
|
openSearch(highlighted, lang);
|
|
}
|
|
});
|
|
}
|
|
function unhighlight() {
|
|
highlighted && JX.DOM.alterClass(highlighted, classHighlight, false);
|
|
highlighted = null;
|
|
}
|
|
|
|
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) {
|
|
if (blocks[i].hasAttribute('data-code-lang')) {
|
|
var lang = blocks[i].getAttribute('data-code-lang');
|
|
link(blocks[i], lang);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config.container) {
|
|
link(JX.$(config.container), config.lang);
|
|
} else if (config.section) {
|
|
linkAll(JX.$(config.section));
|
|
}
|
|
|
|
JX.Stratcom.listen(
|
|
'differential-preview-update',
|
|
null,
|
|
function(e) {
|
|
linkAll(e.getData().container);
|
|
});
|
|
|
|
|
|
JX.Stratcom.listen(
|
|
['keydown', 'keyup'],
|
|
null,
|
|
function(e) {
|
|
if (e.getRawEvent().keyCode !== signalKey) {
|
|
return;
|
|
}
|
|
setCursorMode(e.getType() === 'keydown');
|
|
|
|
if (!statics.active) {
|
|
unhighlight();
|
|
}
|
|
});
|
|
|
|
JX.Stratcom.listen(
|
|
'blur',
|
|
null,
|
|
function(e) {
|
|
if (e.getTarget()) {
|
|
return;
|
|
}
|
|
unhighlight();
|
|
setCursorMode(false);
|
|
});
|
|
|
|
function setCursorMode(active) {
|
|
statics.active = active;
|
|
linked.forEach(function(element) {
|
|
JX.DOM.alterClass(element, classMouseCursor, statics.active);
|
|
});
|
|
}
|
|
});
|