add focus controller, manages keyboard focus across multiple embedded decks
This commit is contained in:
parent
57107ebe4c
commit
664beff715
6 changed files with 125 additions and 6 deletions
4
dist/reveal.esm.js
vendored
4
dist/reveal.esm.js
vendored
File diff suppressed because one or more lines are too long
4
dist/reveal.js
vendored
4
dist/reveal.js
vendored
File diff suppressed because one or more lines are too long
|
@ -57,6 +57,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.reveal {
|
||||
border: 4px solid #ccc;
|
||||
}
|
||||
.reveal.focused {
|
||||
border-color: #94b5ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../dist/reveal.js"></script>
|
||||
<script src="../dist/plugin/highlight.js"></script>
|
||||
<script src="../dist/plugin/markdown.js"></script>
|
||||
|
@ -65,7 +74,8 @@
|
|||
|
||||
let deck1 = new Reveal( document.querySelector( '.deck1' ), {
|
||||
embedded: true,
|
||||
keyboard: false,
|
||||
progress: false,
|
||||
keyboardCondition: 'focused',
|
||||
plugins: [ RevealHighlight ]
|
||||
} );
|
||||
deck1.on( 'slidechanged', () => {
|
||||
|
@ -75,7 +85,8 @@
|
|||
|
||||
let deck2 = new Reveal( document.querySelector( '.deck2' ), {
|
||||
embedded: true,
|
||||
keyboard: true,
|
||||
progress: false,
|
||||
keyboardCondition: 'focused',
|
||||
plugins: [ RevealMarkdown, RevealMath ]
|
||||
} );
|
||||
deck2.initialize().then( () => {
|
||||
|
|
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;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import Pointer from './controllers/pointer.js'
|
|||
import Plugins from './controllers/plugins.js'
|
||||
import Print from './controllers/print.js'
|
||||
import Touch from './controllers/touch.js'
|
||||
import Focus from './controllers/focus.js'
|
||||
import Notes from './controllers/notes.js'
|
||||
import Playback from './components/playback.js'
|
||||
import defaultConfig from './config.js'
|
||||
|
@ -111,6 +112,7 @@ export default function( revealElement, options ) {
|
|||
pointer = new Pointer( Reveal ),
|
||||
plugins = new Plugins( Reveal ),
|
||||
print = new Print( Reveal ),
|
||||
focus = new Focus( Reveal ),
|
||||
touch = new Touch( Reveal ),
|
||||
notes = new Notes( Reveal );
|
||||
|
||||
|
@ -464,6 +466,7 @@ export default function( revealElement, options ) {
|
|||
}
|
||||
|
||||
notes.configure( config, oldConfig );
|
||||
focus.configure( config, oldConfig );
|
||||
pointer.configure( config, oldConfig );
|
||||
controls.configure( config, oldConfig );
|
||||
progress.configure( config, oldConfig );
|
||||
|
@ -489,6 +492,7 @@ export default function( revealElement, options ) {
|
|||
if( config.progress ) progress.bind();
|
||||
if( config.respondToHashChanges ) location.bind();
|
||||
controls.bind();
|
||||
focus.bind();
|
||||
|
||||
dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
|
||||
dom.pauseOverlay.addEventListener( 'click', resume, false );
|
||||
|
@ -507,6 +511,7 @@ export default function( revealElement, options ) {
|
|||
eventsAreBound = false;
|
||||
|
||||
touch.unbind();
|
||||
focus.unbind();
|
||||
keyboard.unbind();
|
||||
controls.unbind();
|
||||
progress.unbind();
|
||||
|
@ -2438,6 +2443,7 @@ export default function( revealElement, options ) {
|
|||
isAutoSliding,
|
||||
isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),
|
||||
isOverview: overview.isActive.bind( overview ),
|
||||
isFocused: focus.isFocused.bind( focus ),
|
||||
isPrintingPDF: print.isPrintingPDF.bind( print ),
|
||||
|
||||
// Checks if reveal.js has been loaded and is ready for use
|
||||
|
@ -2548,6 +2554,7 @@ export default function( revealElement, options ) {
|
|||
|
||||
// Controllers
|
||||
print,
|
||||
focus,
|
||||
progress,
|
||||
controls,
|
||||
location,
|
||||
|
|
Loading…
Reference in a new issue