playable
Version:
Video player based on HTML5Video
175 lines (156 loc) • 4.17 kB
text/typescript
// Code from ally.js
/*
Observe keyboard-, pointer-, mouse- and touch-events so that a query for
the current interaction type can be made at any time. For pointer interaction
this observer is limited to pointer button down/up - move is not observed!
USAGE:
var listener = engage();
listener.get() === {pointer: Boolean, key: Boolean}
*/
// counters to track primary input
let _activePointers = 0;
let _activeKeys = 0;
const pointerStartEvents = [
'touchstart',
'pointerdown',
'MSPointerDown',
'mousedown',
];
const pointerEndEvents = [
'touchend',
'touchcancel',
'pointerup',
'MSPointerUp',
'pointercancel',
'MSPointerCancel',
'mouseup',
];
function handleWindowBlurEvent() {
// reset internal counters when window loses focus
_activePointers = 0;
_activeKeys = 0;
}
function handlePointerStartEvent(event: PointerEvent) {
if (event.isPrimary === false) {
// ignore non-primary pointer events
// https://w3c.github.io/pointerevents/#widl-PointerEvent-isPrimary
return;
}
// mousedown without following mouseup
// (likely not possible in Chrome)
_activePointers += 1;
}
function handlePointerEndEvent(event: any) {
if (event.isPrimary === false) {
// ignore non-primary pointer events
// https://w3c.github.io/pointerevents/#widl-PointerEvent-isPrimary
return;
} else if (event.touches) {
_activePointers = event.touches.length;
return;
}
// delay reset to when the current handlers are executed
((window as any).setImmediate || window.setTimeout)(() => {
// mouseup without prior mousedown
// (drag something out of the window)
_activePointers = Math.max(_activePointers - 1, 0);
});
}
function handleKeyStartEvent(event: KeyboardEvent) {
// ignore modifier keys
switch (event.keyCode || event.which) {
case 16: // space
case 17: // control
case 18: // alt
case 91: // command left
case 93: // command right
return;
default:
break;
}
// keydown without a following keyup
// (may happen on CMD+TAB)
_activeKeys += 1;
}
function handleKeyEndEvent(event: KeyboardEvent) {
// ignore modifier keys
switch (event.keyCode || event.which) {
case 16: // space
case 17: // control
case 18: // alt
case 91: // command left
case 93: // command right
return;
default:
break;
}
// delay reset to when the current handlers are executed
((window as any).setImmediate || window.setTimeout)(() => {
// keyup without prior keydown
// (may happen on CMD+R)
_activeKeys = Math.max(_activeKeys - 1, 0);
});
}
function getInteractionType() {
return {
pointer: Boolean(_activePointers),
key: Boolean(_activeKeys),
};
}
function disengage() {
_activePointers = _activeKeys = 0;
window.removeEventListener('blur', handleWindowBlurEvent, false);
document.documentElement.removeEventListener(
'keydown',
handleKeyStartEvent,
true,
);
document.documentElement.removeEventListener(
'keyup',
handleKeyEndEvent,
true,
);
pointerStartEvents.forEach(event => {
document.documentElement.removeEventListener(
event,
handlePointerStartEvent,
true,
);
});
pointerEndEvents.forEach(event => {
document.documentElement.removeEventListener(
event,
handlePointerEndEvent,
true,
);
});
}
function engage() {
// window blur must be in bubble phase so it won't capture regular blurs
window.addEventListener('blur', handleWindowBlurEvent, false);
// handlers to identify the method of focus change
document.documentElement.addEventListener(
'keydown',
handleKeyStartEvent,
true,
);
document.documentElement.addEventListener('keyup', handleKeyEndEvent, true);
pointerStartEvents.forEach(event => {
document.documentElement.addEventListener(
event,
handlePointerStartEvent,
true,
);
});
pointerEndEvents.forEach(event => {
document.documentElement.addEventListener(
event,
handlePointerEndEvent,
true,
);
});
return {
get: getInteractionType,
};
}
export default { engage, disengage };