* reveal.js 2.1 r35
* http://lab.hakim.se/reveal-js
* MIT licensed
- *
+ *
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
var Reveal = (function(){
'use strict';
-
+
var HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
- // Configurations defaults, can be overridden at initialization time
+ // Configurations defaults, can be overridden at initialization time
config = {
// Display controls in the bottom right corner
controls: true,
// Loop the presentation
loop: false,
- // Number of milliseconds between automatically proceeding to the
+ // Number of milliseconds between automatically proceeding to the
// next slide, disabled when set to 0, this value can be overwritten
// by using a data-autoslide attribute on your slides
autoSlide: 0,
rollingLinks: true,
// Transition style (see /css/theme)
- theme: null,
+ theme: null,
// Transition style
transition: 'default', // default/cube/page/concave/zoom/linear/none
previousSlide,
currentSlide,
- // Slides may hold a data-state attribute which we pick up and apply
- // as a class to the body. This list contains the combined state of
+ // Slides may hold a data-state attribute which we pick up and apply
+ // as a class to the body. This list contains the combined state of
// all current slides.
state = [],
'msPerspective' in document.body.style ||
'OPerspective' in document.body.style ||
'perspective' in document.body.style,
-
+
supports2DTransforms = 'WebkitTransform' in document.body.style ||
'MozTransform' in document.body.style ||
'msTransform' in document.body.style ||
'OTransform' in document.body.style ||
'transform' in document.body.style,
-
+
// Throttles mouse wheel navigation
mouseWheelTimeout = 0,
handled: false,
threshold: 80
};
-
+
/**
* Starts up the presentation if the client is capable.
*/
if( ( !supports2DTransforms && !supports3DTransforms ) ) {
document.body.setAttribute( 'class', 'no-transforms' );
- // If the browser doesn't support core features we won't be
+ // If the browser doesn't support core features we won't be
// using JavaScript to control the presentation
return;
}
// Loads the dependencies and continues to #start() once done
load();
-
+
}
/**
- * Finds and stores references to DOM elements which are
- * required by the presentation. If a required element is
+ * Finds and stores references to DOM elements which are
+ * required by the presentation. If a required element is
* not found, it is created.
*/
function setupDOM() {
}
/**
- * Loads the dependencies of reveal.js. Dependencies are
- * defined via the configuration option 'dependencies'
- * and will be loaded prior to starting/binding reveal.js.
- * Some dependencies may have an 'async' flag, if so they
+ * Loads the dependencies of reveal.js. Dependencies are
+ * defined via the configuration option 'dependencies'
+ * and will be loaded prior to starting/binding reveal.js.
+ * Some dependencies may have an 'async' flag, if so they
* will load after reveal.js has been started up.
*/
function load() {
function proceed() {
// Load asynchronous scripts
head.js.apply( null, scriptsAsync );
-
+
start();
}
}
/**
- * Starts up reveal.js by binding input events and navigating
+ * Starts up reveal.js by binding input events and navigating
* to the current URL deeplink if there is one.
*/
function start() {
// Make sure we've got all the DOM elements we need
setupDOM();
-
+
// Subscribe to input
addEventListeners();
dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false );
dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false );
dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false );
- dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false );
+ dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false );
}
}
if ( config.progress && dom.progress ) {
dom.progress.removeEventListener( 'click', preventAndForward( onProgressClick ), false );
}
-
+
if ( config.controls && dom.controls ) {
dom.controlsLeft.removeEventListener( 'click', preventAndForward( navigateLeft ), false );
dom.controlsRight.removeEventListener( 'click', preventAndForward( navigateRight ), false );
}
/**
- * Extend object a with the properties of object b.
+ * Extend object a with the properties of object b.
* If there's a conflict, object b takes precedence.
*/
function extend( a, b ) {
/**
* Measures the distance in pixels between point a
- * and point b.
- *
+ * and point b.
+ *
* @param {Object} a point with x/y properties
* @param {Object} b point with x/y properties
*/
}
/**
- * Prevents an events defaults behavior calls the
+ * Prevents an events defaults behavior calls the
* specified delegate.
- *
- * @param {Function} delegate The method to call
+ *
+ * @param {Function} delegate The method to call
* after the wrapper has been executed
*/
function preventAndForward( delegate ) {
}
/**
- * Causes the address bar to hide on mobile devices,
+ * Causes the address bar to hide on mobile devices,
* more vertical space ftw.
*/
function removeAddressBar() {
}
/**
- * Dispatches an event of the specified type from the
+ * Dispatches an event of the specified type from the
* reveal DOM element.
*/
function dispatchEvent( type, properties ) {
for( var i = 0, len = nodes.length; i < len; i++ ) {
var node = nodes[i];
-
+
if( node.textContent && !node.querySelector( 'img' ) && ( !node.className || !node.classList.contains( node, 'roll' ) ) ) {
node.classList.add( 'roll' );
node.innerHTML = '<span data-title="'+ node.text +'">' + node.innerHTML + '</span>';
}
/**
- * Displays the overview of slides (quick nav) by
+ * Displays the overview of slides (quick nav) by
* scaling down and arranging all slide elements.
- *
- * Experimental feature, might be dropped if perf
+ *
+ * Experimental feature, might be dropped if perf
* can't be improved.
*/
function activateOverview() {
// Only proceed if enabled in config
if( config.overview ) {
-
+
dom.wrapper.classList.add( 'overview' );
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
var hslide = horizontalSlides[i],
htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * 105 ) + '%, 0%)';
-
+
hslide.setAttribute( 'data-index-h', i );
hslide.style.display = 'block';
hslide.style.WebkitTransform = htransform;
hslide.style.msTransform = htransform;
hslide.style.OTransform = htransform;
hslide.style.transform = htransform;
-
+
if( !hslide.classList.contains( 'stack' ) ) {
// Navigate to this slide on click
hslide.addEventListener( 'click', onOverviewSlideClicked, true );
}
-
+
var verticalSlides = hslide.querySelectorAll( 'section' );
for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
// Navigate to this slide on click
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
}
-
+
}
}
}
-
+
/**
* Exits the slide overview and enters the currently
* active slide.
*/
function deactivateOverview() {
-
+
// Only proceed if enabled in config
if( config.overview ) {
}
slide();
-
+
}
}
/**
* Toggles the slide overview mode on and off.
*
- * @param {Boolean} override Optional flag which overrides the
- * toggle logic and forcibly sets the desired state. True means
+ * @param {Boolean} override Optional flag which overrides the
+ * toggle logic and forcibly sets the desired state. True means
* overview is open, false means it's closed.
*/
function toggleOverview( override ) {
/**
* Checks if the overview is currently active.
- *
+ *
* @return {Boolean} true if the overview is active,
* false otherwise
*/
/**
* Handling the fullscreen functionality via the fullscreen API
- *
- * @see http://fullscreen.spec.whatwg.org/
- * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
+ *
+ * @see http://fullscreen.spec.whatwg.org/
+ * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
*/
function enterFullscreen() {
var element = document.body;
-
+
// Check which implementation is available
var requestMethod = element.requestFullScreen ||
element.webkitRequestFullScreen ||
element.mozRequestFullScreen ||
element.msRequestFullScreen;
-
+
if( requestMethod ) {
requestMethod.apply( element );
}
}
/**
- * Enters the paused mode which fades everything on screen to
+ * Enters the paused mode which fades everything on screen to
* black.
*/
function pause() {
function isPaused() {
return dom.wrapper.classList.contains( 'paused' );
}
-
+
/**
- * Steps from the current point in the presentation to the
- * slide which matches the specified horizontal and vertical
- * indices.
+ * Steps from the current point in the presentation to the
+ * slide which matches the specified horizontal and vertical
+ * indices.
*
* @param {int} h Horizontal index of the target slide
* @param {int} v Vertical index of the target slide
// Apply the new state
stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
- // Check if this state existed on the previous slide. If it
+ // Check if this state existed on the previous slide. If it
// did, we will avoid adding it repeatedly.
for( var j = 0; j < stateBefore.length; j++ ) {
if( stateBefore[j] === state[i] ) {
}
updateControls();
-
+
// Update the URL hash after a delay since updating it mid-transition
// is likely to cause visual lag
clearTimeout( writeURLTimeout );
// Dispatch an event if the slide changed
if( indexh !== indexhBefore || indexv !== indexvBefore ) {
dispatchEvent( 'slidechanged', {
- 'indexh': indexh,
+ 'indexh': indexh,
'indexv': indexv,
'previousSlide': previousSlide,
'currentSlide': currentSlide
previousSlide = null;
}
- // Solves an edge case where the previous slide maintains the
- // 'present' class when navigating between adjacent vertical
+ // Solves an edge case where the previous slide maintains the
+ // 'present' class when navigating between adjacent vertical
// stacks
if( previousSlide ) {
previousSlide.classList.remove( 'present' );
/**
* Updates one dimension of slides by showing the slide
* with the specified index.
- *
+ *
* @param {String} selector A CSS selector that will fetch
* the group of slides we are working with
* @param {Number} index The index of the slide that should be
* shown
- *
+ *
* @return {Number} The index of the slide that is now shown,
- * might differ from the passed in index if it was out of
+ * might differ from the passed in index if it was out of
* bounds.
*/
function updateSlides( selector, index ) {
// an array
var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) ),
slidesLength = slides.length;
-
+
if( slidesLength ) {
// Should the index loop?
index = slidesLength + index;
}
}
-
+
// Enforce max and minimum index bounds
index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
-
+
for( var i = 0; i < slidesLength; i++ ) {
var element = slides[i];
- // Optimization; hide all slides that are three or more steps
+ // Optimization; hide all slides that are three or more steps
// away from the present slide
if( isOverviewActive() === false ) {
// The distance loops so that it measures 1 between the first
state = state.concat( slideState.split( ' ' ) );
}
- // If this slide has a data-autoslide attribtue associated use this as
+ // If this slide has a data-autoslide attribtue associated use this as
// autoSlide value otherwise use the global configured time
var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' );
if( slideAutoSlide ) {
}
else {
- // Since there are no slides we can't be anywhere beyond the
+ // Since there are no slides we can't be anywhere beyond the
// zeroth index
index = 0;
}
-
+
return index;
-
+
}
/**
*/
function updateControls() {
if ( config.controls && dom.controls ) {
-
+
var routes = availableRoutes();
// Remove the 'enabled' class from all directions
/**
* Determine what available routes there are for navigation.
- *
+ *
* @return {Object} containing four booleans: left/right/up/down
*/
function availableRoutes() {
down: indexv < verticalSlides.length - 1
};
}
-
+
/**
* Reads the current URL (hash) and navigates accordingly.
*/
var bits = hash.slice( 2 ).split( '/' ),
name = hash.replace( /#|\//gi, '' );
- // If the first bit is invalid and there is a name we can
+ // If the first bit is invalid and there is a name we can
// assume that this is a named link
if( isNaN( parseInt( bits[0], 10 ) ) && name.length ) {
// Find the slide with the specified name
slide( h, v );
}
}
-
+
/**
* Updates the page URL (hash) to reflect the current
- * state.
+ * state.
*/
function writeURL() {
if( config.history ) {
var url = '/';
-
+
// Only include the minimum possible number of components in
// the URL
if( indexh > 0 || indexv > 0 ) url += indexh;
if( indexv > 0 ) url += '/' + indexv;
-
+
window.location.hash = url;
}
}
/**
- * Retrieves the h/v location of the current, or specified,
+ * Retrieves the h/v location of the current, or specified,
* slide.
- *
- * @param {HTMLElement} slide If specified, the returned
- * index will be for this slide rather than the currently
+ *
+ * @param {HTMLElement} slide If specified, the returned
+ * index will be for this slide rather than the currently
* active one
- *
+ *
* @return {Object} { h: <int>, v: <int> }
*/
function getIndices( slide ) {
/**
* Navigate to the next slide fragment.
- *
+ *
* @return {Boolean} true if there was a next fragment,
* false otherwise
*/
/**
* Navigate to the previous slide fragment.
- *
+ *
* @return {Boolean} true if there was a previous fragment,
* false otherwise
*/
return true;
}
}
-
+
return false;
}
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
}
}
-
+
function navigateLeft() {
// Prioritize hiding fragments
if( isOverviewActive() || previousFragment() === false ) {
availableRoutes().down ? navigateDown() : navigateRight();
}
- // If auto-sliding is enabled we need to cue up
+ // If auto-sliding is enabled we need to cue up
// another timeout
cueAutoSlide();
}
/**
* Handler for the document level 'keydown' event.
- *
+ *
* @param {Object} event
*/
function onDocumentKeyDown( event ) {
- // Disregard the event if the target is editable or a
+ // Disregard the event if the target is editable or a
// modifier is present
if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
switch( event.keyCode ) {
// p, page up
- case 80: case 33: navigatePrev(); break;
+ case 80: case 33: navigatePrev(); break;
// n, page down
case 78: case 34: navigateNext(); break;
// h, left
triggered = false;
}
- // If the input resulted in a triggered action we should prevent
+ // If the input resulted in a triggered action we should prevent
// the browsers default behavior
if( triggered ) {
event.preventDefault();
}
else if ( event.keyCode === 27 && supports3DTransforms ) {
toggleOverview();
-
+
event.preventDefault();
}
- // If auto-sliding is enabled we need to cue up
+ // If auto-sliding is enabled we need to cue up
// another timeout
cueAutoSlide();
touch.startY = event.touches[0].clientY;
touch.startCount = event.touches.length;
- // If there's two touches we need to memorize the distance
+ // If there's two touches we need to memorize the distance
// between those two points to detect pinching
if( event.touches.length === 2 && config.overview ) {
touch.startSpan = distanceBetween( {
} );
}
}
-
+
/**
* Handler for the document level 'touchmove' event.
*/
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
- // If the touch started off with two points and still has
+ // If the touch started off with two points and still has
// two active touches; test for the pinch gesture
if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
y: touch.startY
} );
- // If the span is larger than the desire amount we've got
+ // If the span is larger than the desire amount we've got
// ourselves a pinch
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
touch.handled = true;
if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
touch.handled = true;
navigateLeft();
- }
+ }
else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
touch.handled = true;
navigateRight();
- }
+ }
else if( deltaY > touch.threshold ) {
touch.handled = true;
navigateUp();
- }
+ }
else if( deltaY < -touch.threshold ) {
touch.handled = true;
navigateDown();
}
}
- // There's a bug with swiping on some Android devices unless
+ // There's a bug with swiping on some Android devices unless
// the default action is always prevented
else if( navigator.userAgent.match( /android/gi ) ) {
event.preventDefault();
}
/**
- * Handles mouse wheel scrolling, throttled to avoid skipping
+ * Handles mouse wheel scrolling, throttled to avoid skipping
* multiple slides.
*/
function onDocumentMouseScroll( event ){
}
/**
- * Clicking on the progress bar results in a navigation to the
+ * Clicking on the progress bar results in a navigation to the
* closest approximate horizontal slide using this equation:
*
* ( clickX / presentationWidth ) * numberOfSlides
slide( slideIndex );
}
-
+
/**
* Handler for the window level 'hashchange' event.
- *
+ *
* @param {Object} event
*/
function onWindowHashChange( event ) {
* Invoked when a slide is and we're in the overview.
*/
function onOverviewSlideClicked( event ) {
- // TODO There's a bug here where the event listeners are not
+ // TODO There's a bug here where the event listeners are not
// removed after deactivating the overview.
if( isOverviewActive() ) {
event.preventDefault();
}
}
-
+
// --------------------------------------------------------------------//
// ------------------------------- API --------------------------------//
// --------------------------------------------------------------------//
return {
initialize: initialize,
-
+
// Navigation methods
slide: slide,
left: navigateLeft,
}
}
};
-
+
})();
\ No newline at end of file