new keyboard module
This commit is contained in:
parent
ddbe06eb7e
commit
3d6212378a
2
dist/reveal.min.js
vendored
2
dist/reveal.min.js
vendored
File diff suppressed because one or more lines are too long
362
js/controllers/keyboard.js
Normal file
362
js/controllers/keyboard.js
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
import { extend, toArray, enterFullscreen } from '../utils/util.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export default class Keyboard {
|
||||||
|
|
||||||
|
constructor( Reveal ) {
|
||||||
|
|
||||||
|
this.Reveal = Reveal;
|
||||||
|
|
||||||
|
// A key:value map of keyboard keys and descriptions of
|
||||||
|
// the actions they trigger
|
||||||
|
this.shortcuts = {};
|
||||||
|
|
||||||
|
// Holds custom key code mappings
|
||||||
|
this.bindings = {};
|
||||||
|
|
||||||
|
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
||||||
|
this.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshSortcuts() {
|
||||||
|
|
||||||
|
// Define our contextual list of keyboard shortcuts
|
||||||
|
if( this.Reveal.getConfig().navigationMode === 'linear' ) {
|
||||||
|
this.shortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide';
|
||||||
|
this.shortcuts['← , ↑ , P , H , K'] = 'Previous slide';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.shortcuts['N , SPACE'] = 'Next slide';
|
||||||
|
this.shortcuts['P'] = 'Previous slide';
|
||||||
|
this.shortcuts['← , H'] = 'Navigate left';
|
||||||
|
this.shortcuts['→ , L'] = 'Navigate right';
|
||||||
|
this.shortcuts['↑ , K'] = 'Navigate up';
|
||||||
|
this.shortcuts['↓ , J'] = 'Navigate down';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.shortcuts['Home , Shift ←'] = 'First slide';
|
||||||
|
this.shortcuts['End , Shift →'] = 'Last slide';
|
||||||
|
this.shortcuts['B , .'] = 'Pause';
|
||||||
|
this.shortcuts['F'] = 'Fullscreen';
|
||||||
|
this.shortcuts['ESC, O'] = 'Slide overview';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bind() {
|
||||||
|
|
||||||
|
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
|
document.addEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unbind() {
|
||||||
|
|
||||||
|
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
|
document.removeEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom key binding with optional description to
|
||||||
|
* be added to the help screen.
|
||||||
|
*/
|
||||||
|
addKeyBinding( binding, callback ) {
|
||||||
|
|
||||||
|
if( typeof binding === 'object' && binding.keyCode ) {
|
||||||
|
this.bindings[binding.keyCode] = {
|
||||||
|
callback: callback,
|
||||||
|
key: binding.key,
|
||||||
|
description: binding.description
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.bindings[binding] = {
|
||||||
|
callback: callback,
|
||||||
|
key: null,
|
||||||
|
description: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the specified custom key binding.
|
||||||
|
*/
|
||||||
|
removeKeyBinding( keyCode ) {
|
||||||
|
|
||||||
|
delete this.bindings[keyCode];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Programmatically triggers a keyboard event
|
||||||
|
*
|
||||||
|
* @param {int} keyCode
|
||||||
|
*/
|
||||||
|
triggerKey( keyCode ) {
|
||||||
|
|
||||||
|
this.onDocumentKeyDown( { keyCode } );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new shortcut to include in the help overlay
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
registerKeyboardShortcut( key, value ) {
|
||||||
|
|
||||||
|
this.shortcuts[key] = value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the document level 'keypress' event.
|
||||||
|
*
|
||||||
|
* @param {object} event
|
||||||
|
*/
|
||||||
|
onDocumentKeyPress( event ) {
|
||||||
|
|
||||||
|
// Check if the pressed key is question mark
|
||||||
|
if( event.shiftKey && event.charCode === 63 ) {
|
||||||
|
this.Reveal.toggleHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the document level 'keydown' event.
|
||||||
|
*
|
||||||
|
* @param {object} event
|
||||||
|
*/
|
||||||
|
onDocumentKeyDown( event ) {
|
||||||
|
|
||||||
|
let config = this.Reveal.getConfig();
|
||||||
|
|
||||||
|
// If there's a condition specified and it returns false,
|
||||||
|
// ignore this event
|
||||||
|
if( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shorthand
|
||||||
|
let keyCode = event.keyCode;
|
||||||
|
|
||||||
|
// Remember if auto-sliding was paused so we can toggle it
|
||||||
|
let autoSlideWasPaused = !this.Reveal.isAutoSliding();
|
||||||
|
|
||||||
|
this.Reveal.onUserInput( event );
|
||||||
|
|
||||||
|
// Is there a focused element that could be using the keyboard?
|
||||||
|
let activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit';
|
||||||
|
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
||||||
|
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
||||||
|
|
||||||
|
// Whitelist specific modified + keycode combinations
|
||||||
|
let prevSlideShortcut = event.shiftKey && event.keyCode === 32;
|
||||||
|
let firstSlideShortcut = event.shiftKey && keyCode === 37;
|
||||||
|
let lastSlideShortcut = event.shiftKey && keyCode === 39;
|
||||||
|
|
||||||
|
// Prevent all other events when a modifier is pressed
|
||||||
|
let unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&
|
||||||
|
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
||||||
|
|
||||||
|
// Disregard the event if there's a focused element or a
|
||||||
|
// keyboard modifier key is present
|
||||||
|
if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
|
||||||
|
|
||||||
|
// While paused only allow resume keyboard events; 'b', 'v', '.'
|
||||||
|
let resumeKeyCodes = [66,86,190,191];
|
||||||
|
let key;
|
||||||
|
|
||||||
|
// Custom key bindings for togglePause should be able to resume
|
||||||
|
if( typeof config.keyboard === 'object' ) {
|
||||||
|
for( key in config.keyboard ) {
|
||||||
|
if( config.keyboard[key] === 'togglePause' ) {
|
||||||
|
resumeKeyCodes.push( parseInt( key, 10 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use linear navigation if we're configured to OR if
|
||||||
|
// the presentation is one-dimensional
|
||||||
|
let useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();
|
||||||
|
|
||||||
|
let triggered = false;
|
||||||
|
|
||||||
|
// 1. User defined key bindings
|
||||||
|
if( typeof config.keyboard === 'object' ) {
|
||||||
|
|
||||||
|
for( key in config.keyboard ) {
|
||||||
|
|
||||||
|
// Check if this binding matches the pressed key
|
||||||
|
if( parseInt( key, 10 ) === keyCode ) {
|
||||||
|
|
||||||
|
let value = config.keyboard[ key ];
|
||||||
|
|
||||||
|
// Callback function
|
||||||
|
if( typeof value === 'function' ) {
|
||||||
|
value.apply( null, [ event ] );
|
||||||
|
}
|
||||||
|
// String shortcuts to reveal.js API
|
||||||
|
else if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {
|
||||||
|
this.Reveal[ value ].call();
|
||||||
|
}
|
||||||
|
|
||||||
|
triggered = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Registered custom key bindings
|
||||||
|
if( triggered === false ) {
|
||||||
|
|
||||||
|
for( key in this.bindings ) {
|
||||||
|
|
||||||
|
// Check if this binding matches the pressed key
|
||||||
|
if( parseInt( key, 10 ) === keyCode ) {
|
||||||
|
|
||||||
|
let action = this.bindings[ key ].callback;
|
||||||
|
|
||||||
|
// Callback function
|
||||||
|
if( typeof action === 'function' ) {
|
||||||
|
action.apply( null, [ event ] );
|
||||||
|
}
|
||||||
|
// String shortcuts to reveal.js API
|
||||||
|
else if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {
|
||||||
|
this.Reveal[ action ].call();
|
||||||
|
}
|
||||||
|
|
||||||
|
triggered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. System defined key bindings
|
||||||
|
if( triggered === false ) {
|
||||||
|
|
||||||
|
// Assume true and try to prove false
|
||||||
|
triggered = true;
|
||||||
|
|
||||||
|
// P, PAGE UP
|
||||||
|
if( keyCode === 80 || keyCode === 33 ) {
|
||||||
|
this.Reveal.prev();
|
||||||
|
}
|
||||||
|
// N, PAGE DOWN
|
||||||
|
else if( keyCode === 78 || keyCode === 34 ) {
|
||||||
|
this.Review.next();
|
||||||
|
}
|
||||||
|
// H, LEFT
|
||||||
|
else if( keyCode === 72 || keyCode === 37 ) {
|
||||||
|
if( firstSlideShortcut ) {
|
||||||
|
this.Reveal.slide( 0 );
|
||||||
|
}
|
||||||
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Reveal.prev();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Reveal.left();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// L, RIGHT
|
||||||
|
else if( keyCode === 76 || keyCode === 39 ) {
|
||||||
|
if( lastSlideShortcut ) {
|
||||||
|
this.Reveal.slide( Number.MAX_VALUE );
|
||||||
|
}
|
||||||
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Review.next();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Reveal.right();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// K, UP
|
||||||
|
else if( keyCode === 75 || keyCode === 38 ) {
|
||||||
|
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Reveal.prev();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Reveal.up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// J, DOWN
|
||||||
|
else if( keyCode === 74 || keyCode === 40 ) {
|
||||||
|
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Review.next();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Reveal.down();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// HOME
|
||||||
|
else if( keyCode === 36 ) {
|
||||||
|
this.Reveal.slide( 0 );
|
||||||
|
}
|
||||||
|
// END
|
||||||
|
else if( keyCode === 35 ) {
|
||||||
|
this.Reveal.slide( Number.MAX_VALUE );
|
||||||
|
}
|
||||||
|
// SPACE
|
||||||
|
else if( keyCode === 32 ) {
|
||||||
|
if( this.Reveal.overview.isActive() ) {
|
||||||
|
this.Reveal.overview.deactivate();
|
||||||
|
}
|
||||||
|
if( event.shiftKey ) {
|
||||||
|
this.Reveal.prev();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Review.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
||||||
|
else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
|
||||||
|
this.Reveal.togglePause();
|
||||||
|
}
|
||||||
|
// F
|
||||||
|
else if( keyCode === 70 ) {
|
||||||
|
enterFullscreen();
|
||||||
|
}
|
||||||
|
// A
|
||||||
|
else if( keyCode === 65 ) {
|
||||||
|
if ( config.autoSlideStoppable ) {
|
||||||
|
this.Reveal.toggleAutoSlide( autoSlideWasPaused );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
triggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the input resulted in a triggered action we should prevent
|
||||||
|
// the browsers default behavior
|
||||||
|
if( triggered ) {
|
||||||
|
event.preventDefault && event.preventDefault();
|
||||||
|
}
|
||||||
|
// ESC or O key
|
||||||
|
else if( keyCode === 27 || keyCode === 79 ) {
|
||||||
|
if( this.Reveal.closeOverlay() === false ) {
|
||||||
|
this.Reveal.overview.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault && event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If auto-sliding is enabled we need to cue up
|
||||||
|
// another timeout
|
||||||
|
this.Reveal.cueAutoSlide();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
361
js/reveal.js
361
js/reveal.js
@ -2,6 +2,7 @@ import SlideContent from './controllers/slidecontent.js'
|
|||||||
import AutoAnimate from './controllers/autoanimate.js'
|
import AutoAnimate from './controllers/autoanimate.js'
|
||||||
import Fragments from './controllers/fragments.js'
|
import Fragments from './controllers/fragments.js'
|
||||||
import Overview from './controllers/overview.js'
|
import Overview from './controllers/overview.js'
|
||||||
|
import Keyboard from './controllers/keyboard.js'
|
||||||
import Plugins from './controllers/plugins.js'
|
import Plugins from './controllers/plugins.js'
|
||||||
import Playback from './components/playback.js'
|
import Playback from './components/playback.js'
|
||||||
import defaultConfig from './config.js'
|
import defaultConfig from './config.js'
|
||||||
@ -85,8 +86,12 @@ export default function( revealElement, options ) {
|
|||||||
// Controls navigation between slide fragments
|
// Controls navigation between slide fragments
|
||||||
fragments = new Fragments( Reveal ),
|
fragments = new Fragments( Reveal ),
|
||||||
|
|
||||||
|
// Controls the birds-eye overview of slides
|
||||||
overview = new Overview( Reveal ),
|
overview = new Overview( Reveal ),
|
||||||
|
|
||||||
|
// Controls all keyboard interactions
|
||||||
|
keyboard = new Keyboard( Reveal ),
|
||||||
|
|
||||||
// List of asynchronously loaded reveal.js dependencies
|
// List of asynchronously loaded reveal.js dependencies
|
||||||
asyncDependencies = [],
|
asyncDependencies = [],
|
||||||
|
|
||||||
@ -121,14 +126,7 @@ export default function( revealElement, options ) {
|
|||||||
startCount: 0,
|
startCount: 0,
|
||||||
captured: false,
|
captured: false,
|
||||||
threshold: 40
|
threshold: 40
|
||||||
},
|
};
|
||||||
|
|
||||||
// A key:value map of shortcut keyboard keys and descriptions of
|
|
||||||
// the actions they trigger, generated in #configure()
|
|
||||||
keyboardShortcuts = {},
|
|
||||||
|
|
||||||
// Holds custom key code mappings
|
|
||||||
registeredKeyBindings = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts up the presentation if the client is capable.
|
* Starts up the presentation if the client is capable.
|
||||||
@ -949,25 +947,7 @@ export default function( revealElement, options ) {
|
|||||||
dom.wrapper.removeAttribute( 'data-navigation-mode' );
|
dom.wrapper.removeAttribute( 'data-navigation-mode' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define our contextual list of keyboard shortcuts
|
keyboard.refreshSortcuts();
|
||||||
if( config.navigationMode === 'linear' ) {
|
|
||||||
keyboardShortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide';
|
|
||||||
keyboardShortcuts['← , ↑ , P , H , K'] = 'Previous slide';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
keyboardShortcuts['N , SPACE'] = 'Next slide';
|
|
||||||
keyboardShortcuts['P'] = 'Previous slide';
|
|
||||||
keyboardShortcuts['← , H'] = 'Navigate left';
|
|
||||||
keyboardShortcuts['→ , L'] = 'Navigate right';
|
|
||||||
keyboardShortcuts['↑ , K'] = 'Navigate up';
|
|
||||||
keyboardShortcuts['↓ , J'] = 'Navigate down';
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboardShortcuts['Home , Shift ←'] = 'First slide';
|
|
||||||
keyboardShortcuts['End , Shift →'] = 'Last slide';
|
|
||||||
keyboardShortcuts['B , .'] = 'Pause';
|
|
||||||
keyboardShortcuts['F'] = 'Fullscreen';
|
|
||||||
keyboardShortcuts['ESC, O'] = 'Slide overview';
|
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
|
|
||||||
@ -1005,8 +985,7 @@ export default function( revealElement, options ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( config.keyboard ) {
|
if( config.keyboard ) {
|
||||||
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
keyboard.bind();
|
||||||
document.addEventListener( 'keypress', onDocumentKeyPress, false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( config.progress && dom.progress ) {
|
if( config.progress && dom.progress ) {
|
||||||
@ -1047,8 +1026,8 @@ export default function( revealElement, options ) {
|
|||||||
|
|
||||||
eventsAreBound = false;
|
eventsAreBound = false;
|
||||||
|
|
||||||
document.removeEventListener( 'keydown', onDocumentKeyDown, false );
|
keyboard.unbind();
|
||||||
document.removeEventListener( 'keypress', onDocumentKeyPress, false );
|
|
||||||
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
||||||
window.removeEventListener( 'resize', onWindowResize, false );
|
window.removeEventListener( 'resize', onWindowResize, false );
|
||||||
|
|
||||||
@ -1081,38 +1060,6 @@ export default function( revealElement, options ) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a custom key binding with optional description to
|
|
||||||
* be added to the help screen.
|
|
||||||
*/
|
|
||||||
function addKeyBinding( binding, callback ) {
|
|
||||||
|
|
||||||
if( typeof binding === 'object' && binding.keyCode ) {
|
|
||||||
registeredKeyBindings[binding.keyCode] = {
|
|
||||||
callback: callback,
|
|
||||||
key: binding.key,
|
|
||||||
description: binding.description
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
registeredKeyBindings[binding] = {
|
|
||||||
callback: callback,
|
|
||||||
key: null,
|
|
||||||
description: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the specified custom key binding.
|
|
||||||
*/
|
|
||||||
function removeKeyBinding( keyCode ) {
|
|
||||||
|
|
||||||
delete registeredKeyBindings[keyCode];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies CSS transforms to the slides container. The container
|
* Applies CSS transforms to the slides container. The container
|
||||||
* is transformed from two separate sources: layout and the overview
|
* is transformed from two separate sources: layout and the overview
|
||||||
@ -1327,14 +1274,14 @@ export default function( revealElement, options ) {
|
|||||||
let html = '<p class="title">Keyboard Shortcuts</p><br/>';
|
let html = '<p class="title">Keyboard Shortcuts</p><br/>';
|
||||||
|
|
||||||
html += '<table><th>KEY</th><th>ACTION</th>';
|
html += '<table><th>KEY</th><th>ACTION</th>';
|
||||||
for( let key in keyboardShortcuts ) {
|
for( let key in keyboard.shortcuts ) {
|
||||||
html += `<tr><td>${key}</td><td>${keyboardShortcuts[ key ]}</td></tr>`;
|
html += `<tr><td>${key}</td><td>${keyboard.shortcuts[ key ]}</td></tr>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add custom key bindings that have associated descriptions
|
// Add custom key bindings that have associated descriptions
|
||||||
for( let binding in registeredKeyBindings ) {
|
for( let binding in keyboard.registeredKeyBindings ) {
|
||||||
if( registeredKeyBindings[binding].key && registeredKeyBindings[binding].description ) {
|
if( keyboard.registeredKeyBindings[binding].key && keyboard.registeredKeyBindings[binding].description ) {
|
||||||
html += `<tr><td>${registeredKeyBindings[binding].key}</td><td>${registeredKeyBindings[binding].description}</td></tr>`;
|
html += `<tr><td>${keyboard.registeredKeyBindings[binding].key}</td><td>${keyboard.registeredKeyBindings[binding].description}</td></tr>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,8 +1313,11 @@ export default function( revealElement, options ) {
|
|||||||
if( dom.overlay ) {
|
if( dom.overlay ) {
|
||||||
dom.overlay.parentNode.removeChild( dom.overlay );
|
dom.overlay.parentNode.removeChild( dom.overlay );
|
||||||
dom.overlay = null;
|
dom.overlay = null;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3482,252 +3432,6 @@ export default function( revealElement, options ) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for the document level 'keypress' event.
|
|
||||||
*
|
|
||||||
* @param {object} event
|
|
||||||
*/
|
|
||||||
function onDocumentKeyPress( event ) {
|
|
||||||
|
|
||||||
// Check if the pressed key is question mark
|
|
||||||
if( event.shiftKey && event.charCode === 63 ) {
|
|
||||||
toggleHelp();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for the document level 'keydown' event.
|
|
||||||
*
|
|
||||||
* @param {object} event
|
|
||||||
*/
|
|
||||||
function onDocumentKeyDown( event ) {
|
|
||||||
|
|
||||||
// If there's a condition specified and it returns false,
|
|
||||||
// ignore this event
|
|
||||||
if( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shorthand
|
|
||||||
let keyCode = event.keyCode;
|
|
||||||
|
|
||||||
// Remember if auto-sliding was paused so we can toggle it
|
|
||||||
let autoSlideWasPaused = autoSlidePaused;
|
|
||||||
|
|
||||||
onUserInput( event );
|
|
||||||
|
|
||||||
// Is there a focused element that could be using the keyboard?
|
|
||||||
let activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit';
|
|
||||||
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
|
||||||
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
|
||||||
|
|
||||||
// Whitelist specific modified + keycode combinations
|
|
||||||
let prevSlideShortcut = event.shiftKey && event.keyCode === 32;
|
|
||||||
let firstSlideShortcut = event.shiftKey && keyCode === 37;
|
|
||||||
let lastSlideShortcut = event.shiftKey && keyCode === 39;
|
|
||||||
|
|
||||||
// Prevent all other events when a modifier is pressed
|
|
||||||
let unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&
|
|
||||||
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
|
||||||
|
|
||||||
// Disregard the event if there's a focused element or a
|
|
||||||
// keyboard modifier key is present
|
|
||||||
if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
|
|
||||||
|
|
||||||
// While paused only allow resume keyboard events; 'b', 'v', '.'
|
|
||||||
let resumeKeyCodes = [66,86,190,191];
|
|
||||||
let key;
|
|
||||||
|
|
||||||
// Custom key bindings for togglePause should be able to resume
|
|
||||||
if( typeof config.keyboard === 'object' ) {
|
|
||||||
for( key in config.keyboard ) {
|
|
||||||
if( config.keyboard[key] === 'togglePause' ) {
|
|
||||||
resumeKeyCodes.push( parseInt( key, 10 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use linear navigation if we're configured to OR if
|
|
||||||
// the presentation is one-dimensional
|
|
||||||
let useLinearMode = config.navigationMode === 'linear' || !hasHorizontalSlides() || !hasVerticalSlides();
|
|
||||||
|
|
||||||
let triggered = false;
|
|
||||||
|
|
||||||
// 1. User defined key bindings
|
|
||||||
if( typeof config.keyboard === 'object' ) {
|
|
||||||
|
|
||||||
for( key in config.keyboard ) {
|
|
||||||
|
|
||||||
// Check if this binding matches the pressed key
|
|
||||||
if( parseInt( key, 10 ) === keyCode ) {
|
|
||||||
|
|
||||||
let value = config.keyboard[ key ];
|
|
||||||
|
|
||||||
// Callback function
|
|
||||||
if( typeof value === 'function' ) {
|
|
||||||
value.apply( null, [ event ] );
|
|
||||||
}
|
|
||||||
// String shortcuts to reveal.js API
|
|
||||||
else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) {
|
|
||||||
Reveal[ value ].call();
|
|
||||||
}
|
|
||||||
|
|
||||||
triggered = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Registered custom key bindings
|
|
||||||
if( triggered === false ) {
|
|
||||||
|
|
||||||
for( key in registeredKeyBindings ) {
|
|
||||||
|
|
||||||
// Check if this binding matches the pressed key
|
|
||||||
if( parseInt( key, 10 ) === keyCode ) {
|
|
||||||
|
|
||||||
let action = registeredKeyBindings[ key ].callback;
|
|
||||||
|
|
||||||
// Callback function
|
|
||||||
if( typeof action === 'function' ) {
|
|
||||||
action.apply( null, [ event ] );
|
|
||||||
}
|
|
||||||
// String shortcuts to reveal.js API
|
|
||||||
else if( typeof action === 'string' && typeof Reveal[ action ] === 'function' ) {
|
|
||||||
Reveal[ action ].call();
|
|
||||||
}
|
|
||||||
|
|
||||||
triggered = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. System defined key bindings
|
|
||||||
if( triggered === false ) {
|
|
||||||
|
|
||||||
// Assume true and try to prove false
|
|
||||||
triggered = true;
|
|
||||||
|
|
||||||
// P, PAGE UP
|
|
||||||
if( keyCode === 80 || keyCode === 33 ) {
|
|
||||||
navigatePrev();
|
|
||||||
}
|
|
||||||
// N, PAGE DOWN
|
|
||||||
else if( keyCode === 78 || keyCode === 34 ) {
|
|
||||||
navigateNext();
|
|
||||||
}
|
|
||||||
// H, LEFT
|
|
||||||
else if( keyCode === 72 || keyCode === 37 ) {
|
|
||||||
if( firstSlideShortcut ) {
|
|
||||||
slide( 0 );
|
|
||||||
}
|
|
||||||
else if( !overview.isActive() && useLinearMode ) {
|
|
||||||
navigatePrev();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
navigateLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// L, RIGHT
|
|
||||||
else if( keyCode === 76 || keyCode === 39 ) {
|
|
||||||
if( lastSlideShortcut ) {
|
|
||||||
slide( Number.MAX_VALUE );
|
|
||||||
}
|
|
||||||
else if( !overview.isActive() && useLinearMode ) {
|
|
||||||
navigateNext();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
navigateRight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// K, UP
|
|
||||||
else if( keyCode === 75 || keyCode === 38 ) {
|
|
||||||
if( !overview.isActive() && useLinearMode ) {
|
|
||||||
navigatePrev();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
navigateUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// J, DOWN
|
|
||||||
else if( keyCode === 74 || keyCode === 40 ) {
|
|
||||||
if( !overview.isActive() && useLinearMode ) {
|
|
||||||
navigateNext();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
navigateDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// HOME
|
|
||||||
else if( keyCode === 36 ) {
|
|
||||||
slide( 0 );
|
|
||||||
}
|
|
||||||
// END
|
|
||||||
else if( keyCode === 35 ) {
|
|
||||||
slide( Number.MAX_VALUE );
|
|
||||||
}
|
|
||||||
// SPACE
|
|
||||||
else if( keyCode === 32 ) {
|
|
||||||
if( overview.isActive() ) {
|
|
||||||
overview.deactivate();
|
|
||||||
}
|
|
||||||
if( event.shiftKey ) {
|
|
||||||
navigatePrev();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
navigateNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
|
||||||
else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
|
|
||||||
togglePause();
|
|
||||||
}
|
|
||||||
// F
|
|
||||||
else if( keyCode === 70 ) {
|
|
||||||
enterFullscreen();
|
|
||||||
}
|
|
||||||
// A
|
|
||||||
else if( keyCode === 65 ) {
|
|
||||||
if ( config.autoSlideStoppable ) {
|
|
||||||
toggleAutoSlide( autoSlideWasPaused );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
triggered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input resulted in a triggered action we should prevent
|
|
||||||
// the browsers default behavior
|
|
||||||
if( triggered ) {
|
|
||||||
event.preventDefault && event.preventDefault();
|
|
||||||
}
|
|
||||||
// ESC or O key
|
|
||||||
else if( keyCode === 27 || keyCode === 79 ) {
|
|
||||||
if( dom.overlay ) {
|
|
||||||
closeOverlay();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
overview.toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault && event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If auto-sliding is enabled we need to cue up
|
|
||||||
// another timeout
|
|
||||||
cueAutoSlide();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the 'touchstart' event, enables support for
|
* Handler for the 'touchstart' event, enables support for
|
||||||
* swipe and pinch gestures.
|
* swipe and pinch gestures.
|
||||||
@ -4069,6 +3773,14 @@ export default function( revealElement, options ) {
|
|||||||
prevFragment: fragments.prev.bind( fragments ),
|
prevFragment: fragments.prev.bind( fragments ),
|
||||||
nextFragment: fragments.next.bind( fragments ),
|
nextFragment: fragments.next.bind( fragments ),
|
||||||
|
|
||||||
|
// Forward event binding to the reveal DOM element
|
||||||
|
addEventListener: ( type, listener, useCapture ) => {
|
||||||
|
Reveal.getRevealElement().addEventListener( type, listener, useCapture );
|
||||||
|
},
|
||||||
|
removeEventListener: ( type, listener, useCapture ) => {
|
||||||
|
Reveal.getRevealElement().removeEventListener( type, listener, useCapture );
|
||||||
|
},
|
||||||
|
|
||||||
// Forces an update in slide layout
|
// Forces an update in slide layout
|
||||||
layout,
|
layout,
|
||||||
|
|
||||||
@ -4155,29 +3867,19 @@ export default function( revealElement, options ) {
|
|||||||
hasVerticalSlides,
|
hasVerticalSlides,
|
||||||
|
|
||||||
// Adds/removes a custom key binding
|
// Adds/removes a custom key binding
|
||||||
addKeyBinding,
|
addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
|
||||||
removeKeyBinding,
|
removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
|
||||||
|
|
||||||
// Programmatically triggers a keyboard event
|
// Programmatically triggers a keyboard event
|
||||||
triggerKey: keyCode => onDocumentKeyDown( { keyCode } ),
|
triggerKey: keyboard.triggerKey.bind( keyboard ),
|
||||||
|
|
||||||
// Registers a new shortcut to include in the help overlay
|
// Registers a new shortcut to include in the help overlay
|
||||||
registerKeyboardShortcut: ( key, value ) => keyboardShortcuts[key] = value,
|
registerKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),
|
||||||
|
|
||||||
// Forward event binding to the reveal DOM element
|
|
||||||
addEventListener: ( type, listener, useCapture ) => {
|
|
||||||
Reveal.getRevealElement().addEventListener( type, listener, useCapture );
|
|
||||||
},
|
|
||||||
removeEventListener: ( type, listener, useCapture ) => {
|
|
||||||
Reveal.getRevealElement().removeEventListener( type, listener, useCapture );
|
|
||||||
},
|
|
||||||
|
|
||||||
// API for registering and retrieving plugins
|
// API for registering and retrieving plugins
|
||||||
registerPlugin: plugins.registerPlugin.bind( plugins ),
|
registerPlugin: plugins.registerPlugin.bind( plugins ),
|
||||||
hasPlugin: plugins.hasPlugin.bind( plugins ),
|
hasPlugin: plugins.hasPlugin.bind( plugins ),
|
||||||
getPlugin: plugins.getPlugin.bind( plugins ),
|
getPlugin: plugins.getPlugin.bind( plugins ),
|
||||||
|
|
||||||
// Returns a hash with all registered plugins
|
|
||||||
getPlugins: plugins.getRegisteredPlugins.bind( plugins ),
|
getPlugins: plugins.getRegisteredPlugins.bind( plugins ),
|
||||||
|
|
||||||
getComputedSlideSize,
|
getComputedSlideSize,
|
||||||
@ -4232,7 +3934,10 @@ export default function( revealElement, options ) {
|
|||||||
announceStatus,
|
announceStatus,
|
||||||
getStatusText,
|
getStatusText,
|
||||||
|
|
||||||
|
overview,
|
||||||
slideContent,
|
slideContent,
|
||||||
|
onUserInput,
|
||||||
|
closeOverlay,
|
||||||
updateControls,
|
updateControls,
|
||||||
updateProgress,
|
updateProgress,
|
||||||
updateSlidesVisibility,
|
updateSlidesVisibility,
|
||||||
|
Loading…
Reference in New Issue
Block a user