add focus controller, manages keyboard focus across multiple embedded decks

This commit is contained in:
Hakim El Hattab
2020-05-11 09:15:02 +02:00
parent 57107ebe4c
commit 664beff715
6 changed files with 125 additions and 6 deletions

95
js/controllers/focus.js Normal file
View File

@ -0,0 +1,95 @@
/**
* Manages focus when a presentation is embedded. This
* helps us only capture keyboard from the presentation
* a user is currently interacting with in a page where
* multiple presentations are embedded.
*/
const STATE_FOCUS = 'focus';
const STATE_BLUR = 'blur';
export default class Focus {
constructor( Reveal ) {
this.Reveal = Reveal;
this.onRevealPointerDown = this.onRevealPointerDown.bind( this );
this.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );
}
/**
* Called when the reveal.js config is updated.
*/
configure( config, oldConfig ) {
if( config.embedded ) {
this.blur();
}
else {
this.focus();
this.unbind();
}
}
bind() {
if( this.Reveal.getConfig().embedded ) {
this.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );
}
}
unbind() {
this.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );
document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
}
focus() {
if( this.state !== STATE_FOCUS ) {
this.Reveal.getRevealElement().classList.add( 'focused' );
document.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );
}
this.state = STATE_FOCUS;
}
blur() {
if( this.state !== STATE_BLUR ) {
this.Reveal.getRevealElement().classList.remove( 'focused' );
document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
}
this.state = STATE_BLUR;
}
isFocused() {
return this.state === STATE_FOCUS;
}
onRevealPointerDown( event ) {
this.focus();
}
onDocumentPointerDown( event ) {
let revealElement = event.target.closest( '.reveal' );
if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
this.blur();
}
}
}

View File

@ -151,6 +151,12 @@ export default class Keyboard {
return true;
}
// If keyboardCondition is set, only capture keyboard events
// for embedded decks when they are focused
if( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {
return true;
}
// Shorthand
let keyCode = event.keyCode;