add focus controller, manages keyboard focus across multiple embedded decks
This commit is contained in:
95
js/controllers/focus.js
Normal file
95
js/controllers/focus.js
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user