mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-29 18:45:48 -05:00
132 lines
3.6 KiB
JavaScript
132 lines
3.6 KiB
JavaScript
|
$(document).ready(function() {
|
||
|
// https://github.com/NV/flying-focus
|
||
|
|
||
|
if (document.getElementById('flying-focus')) return;
|
||
|
|
||
|
var flyingFocus = document.createElement('flying-focus'); // use uniq element name to decrease the chances of a conflict with website styles
|
||
|
flyingFocus.id = 'flying-focus';
|
||
|
document.body.appendChild(flyingFocus);
|
||
|
|
||
|
var DURATION = 100;
|
||
|
flyingFocus.style.transitionDuration = flyingFocus.style.WebkitTransitionDuration = DURATION / 1000 + 's';
|
||
|
|
||
|
function offsetOf(elem) {
|
||
|
var rect = elem.getBoundingClientRect();
|
||
|
var docElem = document.documentElement;
|
||
|
var win = document.defaultView;
|
||
|
var body = document.body;
|
||
|
|
||
|
var clientTop = docElem.clientTop || body.clientTop || 0,
|
||
|
clientLeft = docElem.clientLeft || body.clientLeft || 0,
|
||
|
scrollTop = win.pageYOffset || docElem.scrollTop || body.scrollTop,
|
||
|
scrollLeft = win.pageXOffset || docElem.scrollLeft || body.scrollLeft,
|
||
|
top = rect.top + scrollTop - clientTop,
|
||
|
left = rect.left + scrollLeft - clientLeft;
|
||
|
|
||
|
return {top: top, left: left};
|
||
|
}
|
||
|
|
||
|
var movingId = 0;
|
||
|
var prevFocused = null;
|
||
|
var isFirstFocus = true;
|
||
|
var keyDownTime = 0;
|
||
|
|
||
|
document.documentElement.addEventListener('keydown', function(event) {
|
||
|
var code = event.which;
|
||
|
// Show animation only upon Tab or Arrow keys press.
|
||
|
if (code === 9 || (code > 36 && code < 41)) {
|
||
|
keyDownTime = now();
|
||
|
}
|
||
|
}, false);
|
||
|
|
||
|
document.documentElement.addEventListener('focus', function(event) {
|
||
|
var target = event.target;
|
||
|
if (target.id === 'flying-focus') {
|
||
|
return;
|
||
|
}
|
||
|
var offset = offsetOf(target);
|
||
|
flyingFocus.style.left = offset.left + 'px';
|
||
|
flyingFocus.style.top = offset.top + 'px';
|
||
|
flyingFocus.style.width = target.offsetWidth + 'px';
|
||
|
flyingFocus.style.height = target.offsetHeight + 'px';
|
||
|
|
||
|
// Would be nice to use:
|
||
|
//
|
||
|
// flyingFocus.style['outline-offset'] = getComputedStyle(target, null)['outline-offset']
|
||
|
//
|
||
|
// but it always '0px' in WebKit and Blink for some reason :(
|
||
|
|
||
|
if (isFirstFocus) {
|
||
|
isFirstFocus = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (now() - keyDownTime > 42) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
onEnd();
|
||
|
target.classList.add('flying-focus_target');
|
||
|
flyingFocus.classList.add('flying-focus_visible');
|
||
|
prevFocused = target;
|
||
|
movingId = setTimeout(onEnd, DURATION);
|
||
|
}, true);
|
||
|
|
||
|
document.documentElement.addEventListener('blur', function() {
|
||
|
onEnd();
|
||
|
}, true);
|
||
|
|
||
|
|
||
|
function onEnd() {
|
||
|
if (!movingId) {
|
||
|
return;
|
||
|
}
|
||
|
clearTimeout(movingId);
|
||
|
movingId = 0;
|
||
|
flyingFocus.classList.remove('flying-focus_visible');
|
||
|
prevFocused.classList.remove('flying-focus_target');
|
||
|
prevFocused = null;
|
||
|
}
|
||
|
|
||
|
function now() {
|
||
|
return new Date().valueOf();
|
||
|
}
|
||
|
|
||
|
|
||
|
var style = document.createElement('style');
|
||
|
style.textContent = "#flying-focus {\
|
||
|
position: absolute;\
|
||
|
margin: 0;\
|
||
|
background: transparent;\
|
||
|
-webkit-transition-property: left, top, width, height, opacity;\
|
||
|
transition-property: left, top, width, height, opacity;\
|
||
|
-webkit-transition-timing-function: cubic-bezier(0, 0.2, 0, 1);\
|
||
|
transition-timing-function: cubic-bezier(0, 0.2, 0, 1);\
|
||
|
visibility: hidden;\
|
||
|
pointer-events: none;\
|
||
|
box-shadow: 0 0 2px 3px #78aeda, 0 0 2px #78aeda inset; border-radius: 2px;\
|
||
|
}\
|
||
|
#flying-focus.flying-focus_visible {\
|
||
|
visibility: visible;\
|
||
|
z-index: 9999;\
|
||
|
}\
|
||
|
.flying-focus_target {\
|
||
|
outline: none !important; /* Doesn't work in Firefox :( */\
|
||
|
}\
|
||
|
/* http://stackoverflow.com/questions/71074/how-to-remove-firefoxs-dotted-outline-on-buttons-as-well-as-links/199319 */\
|
||
|
.flying-focus_target::-moz-focus-inner {\
|
||
|
border: 0 !important;\
|
||
|
}\
|
||
|
/* Replace it with @supports rule when browsers catch up */\
|
||
|
@media screen and (-webkit-min-device-pixel-ratio: 0) {\
|
||
|
#flying-focus {\
|
||
|
box-shadow: none;\
|
||
|
outline: 5px auto -webkit-focus-ring-color;\
|
||
|
outline-offset: -3px;\
|
||
|
}\
|
||
|
}\
|
||
|
";
|
||
|
document.body.appendChild(style);
|
||
|
|
||
|
});
|