Add a framework for synchronously executed preInit and preStepLeave plugins.
This allows plugins to register to be executed at the beginning of impress().init() and impress().goto() respectively. By returning false, a plugin can also cancel the event. Also adds 3 plugins that use this: rel, goto and stop.
This commit is contained in:
161
js/impress.js
161
js/impress.js
@@ -131,9 +131,6 @@
|
|||||||
|
|
||||||
// We can't be sure that `classList` is supported
|
// We can't be sure that `classList` is supported
|
||||||
body.className += " impress-not-supported ";
|
body.className += " impress-not-supported ";
|
||||||
} else {
|
|
||||||
body.classList.remove( "impress-not-supported" );
|
|
||||||
body.classList.add( "impress-supported" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLOBALS AND DEFAULTS
|
// GLOBALS AND DEFAULTS
|
||||||
@@ -143,6 +140,9 @@
|
|||||||
// sure if it makes any sense in practice ;)
|
// sure if it makes any sense in practice ;)
|
||||||
var roots = {};
|
var roots = {};
|
||||||
|
|
||||||
|
var preInitPlugins = [];
|
||||||
|
var preStepLeavePlugins = [];
|
||||||
|
|
||||||
// Some default config values.
|
// Some default config values.
|
||||||
var defaults = {
|
var defaults = {
|
||||||
width: 1024,
|
width: 1024,
|
||||||
@@ -238,12 +238,12 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// `onStepLeave` is called whenever the step element is left
|
// `onStepLeave` is called whenever the currentStep element is left
|
||||||
// but the event is triggered only if the step is the same as
|
// but the event is triggered only if the currentStep is the same as
|
||||||
// last entered step.
|
// lastEntered step.
|
||||||
var onStepLeave = function( step ) {
|
var onStepLeave = function( currentStep, nextStep ) {
|
||||||
if ( lastEntered === step ) {
|
if ( lastEntered === currentStep ) {
|
||||||
lib.util.triggerEvent( step, "impress:stepleave" );
|
lib.util.triggerEvent( currentStep, "impress:stepleave", { next: nextStep } );
|
||||||
lastEntered = null;
|
lastEntered = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -283,9 +283,17 @@
|
|||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize all steps.
|
||||||
|
// Read the data-* attributes, store in internal stepsData, and render with CSS.
|
||||||
|
var initAllSteps = function() {
|
||||||
|
steps = lib.util.$$( ".step", root );
|
||||||
|
steps.forEach( initStep );
|
||||||
|
};
|
||||||
|
|
||||||
// `init` API function that initializes (and runs) the presentation.
|
// `init` API function that initializes (and runs) the presentation.
|
||||||
var init = function() {
|
var init = function() {
|
||||||
if ( initialized ) { return; }
|
if ( initialized ) { return; }
|
||||||
|
execPreInitPlugins( root );
|
||||||
|
|
||||||
// First we set up the viewport for mobile devices.
|
// First we set up the viewport for mobile devices.
|
||||||
// For some reason iPad goes nuts when it is not done properly.
|
// For some reason iPad goes nuts when it is not done properly.
|
||||||
@@ -345,8 +353,7 @@
|
|||||||
body.classList.add( "impress-enabled" );
|
body.classList.add( "impress-enabled" );
|
||||||
|
|
||||||
// Get and init steps
|
// Get and init steps
|
||||||
steps = lib.util.$$( ".step", root );
|
initAllSteps();
|
||||||
steps.forEach( initStep );
|
|
||||||
|
|
||||||
// Set a default initial state of the canvas
|
// Set a default initial state of the canvas
|
||||||
currentState = {
|
currentState = {
|
||||||
@@ -379,11 +386,23 @@
|
|||||||
|
|
||||||
// `goto` API function that moves to step given as `el` parameter (by index, id or element).
|
// `goto` API function that moves to step given as `el` parameter (by index, id or element).
|
||||||
// `duration` optionally given as second parameter, is the transition duration in css.
|
// `duration` optionally given as second parameter, is the transition duration in css.
|
||||||
var goto = function( el, duration ) {
|
// `reason` is the string "next", "prev" or "goto" (default) and will be made available to
|
||||||
|
// preStepLeave plugins.
|
||||||
|
// `origEvent` may contain event that caused the calll to goto, such as a key press event
|
||||||
|
var goto = function( el, duration, reason, origEvent ) {
|
||||||
|
reason = reason || "goto";
|
||||||
|
origEvent = origEvent || null;
|
||||||
|
|
||||||
if ( !initialized || !( el = getStep( el ) ) ) {
|
if ( !initialized ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Presentation not initialized or given element is not a step
|
// Re-execute initAllSteps for each transition. This allows to edit step attributes
|
||||||
|
// dynamically, such as change their coordinates, or even remove or add steps, and have
|
||||||
|
// that change apply when goto() is called.
|
||||||
|
initAllSteps();
|
||||||
|
|
||||||
|
if ( !( el = getStep( el ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +419,31 @@
|
|||||||
|
|
||||||
var step = stepsData[ "impress-" + el.id ];
|
var step = stepsData[ "impress-" + el.id ];
|
||||||
|
|
||||||
|
// If we are in fact moving to another step, start with executing the registered
|
||||||
|
// preStepLeave plugins.
|
||||||
|
if ( activeStep && activeStep !== el ) {
|
||||||
|
var event = { target: activeStep, detail: {} };
|
||||||
|
event.detail.next = el;
|
||||||
|
event.detail.transitionDuration = duration;
|
||||||
|
event.detail.reason = reason;
|
||||||
|
if ( origEvent ) {
|
||||||
|
event.origEvent = origEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( execPreStepLeavePlugins( event ) === false ) {
|
||||||
|
|
||||||
|
// PreStepLeave plugins are allowed to abort the transition altogether, by
|
||||||
|
// returning false.
|
||||||
|
// see stop and substep plugins for an example of doing just that
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugins are allowed to change the detail values
|
||||||
|
el = event.detail.next;
|
||||||
|
step = stepsData[ "impress-" + el.id ];
|
||||||
|
duration = event.detail.transitionDuration;
|
||||||
|
}
|
||||||
|
|
||||||
if ( activeStep ) {
|
if ( activeStep ) {
|
||||||
activeStep.classList.remove( "active" );
|
activeStep.classList.remove( "active" );
|
||||||
body.classList.remove( "impress-on-" + activeStep.id );
|
body.classList.remove( "impress-on-" + activeStep.id );
|
||||||
@@ -444,7 +488,7 @@
|
|||||||
|
|
||||||
// Trigger leave of currently active element (if it's not the same step again)
|
// Trigger leave of currently active element (if it's not the same step again)
|
||||||
if ( activeStep && activeStep !== el ) {
|
if ( activeStep && activeStep !== el ) {
|
||||||
onStepLeave( activeStep );
|
onStepLeave( activeStep, el );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we alter transforms of `root` and `canvas` to trigger transitions.
|
// Now we alter transforms of `root` and `canvas` to trigger transitions.
|
||||||
@@ -522,19 +566,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// `prev` API function goes to previous step (in document order)
|
// `prev` API function goes to previous step (in document order)
|
||||||
var prev = function() {
|
// `event` is optional, may contain the event that caused the need to call prev()
|
||||||
|
var prev = function( origEvent ) {
|
||||||
var prev = steps.indexOf( activeStep ) - 1;
|
var prev = steps.indexOf( activeStep ) - 1;
|
||||||
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length - 1 ];
|
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length - 1 ];
|
||||||
|
|
||||||
return goto( prev );
|
return goto( prev, undefined, "prev", origEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
// `next` API function goes to next step (in document order)
|
// `next` API function goes to next step (in document order)
|
||||||
var next = function() {
|
// `event` is optional, may contain the event that caused the need to call next()
|
||||||
|
var next = function( origEvent ) {
|
||||||
var next = steps.indexOf( activeStep ) + 1;
|
var next = steps.indexOf( activeStep ) + 1;
|
||||||
next = next < steps.length ? steps[ next ] : steps[ 0 ];
|
next = next < steps.length ? steps[ next ] : steps[ 0 ];
|
||||||
|
|
||||||
return goto( next );
|
return goto( next, undefined, "next", origEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Teardown impress
|
// Teardown impress
|
||||||
@@ -659,6 +705,64 @@
|
|||||||
return lib;
|
return lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// `addPreInitPlugin` allows plugins to register a function that should
|
||||||
|
// be run (synchronously) at the beginning of init, before
|
||||||
|
// impress().init() itself executes.
|
||||||
|
impress.addPreInitPlugin = function( plugin, weight ) {
|
||||||
|
weight = parseInt( weight ) || 10;
|
||||||
|
if ( weight <= 0 ) {
|
||||||
|
throw "addPreInitPlugin: weight must be a positive integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( preInitPlugins[ weight ] === undefined ) {
|
||||||
|
preInitPlugins[ weight ] = [];
|
||||||
|
}
|
||||||
|
preInitPlugins[ weight ].push( plugin );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called at beginning of init, to execute all pre-init plugins.
|
||||||
|
var execPreInitPlugins = function( root ) { //jshint ignore:line
|
||||||
|
for ( var i = 0; i < preInitPlugins.length; i++ ) {
|
||||||
|
var thisLevel = preInitPlugins[ i ];
|
||||||
|
if ( thisLevel !== undefined ) {
|
||||||
|
for ( var j = 0; j < thisLevel.length; j++ ) {
|
||||||
|
thisLevel[ j ]( root );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// `addPreStepLeavePlugin` allows plugins to register a function that should
|
||||||
|
// be run (synchronously) at the beginning of goto()
|
||||||
|
impress.addPreStepLeavePlugin = function( plugin, weight ) { //jshint ignore:line
|
||||||
|
weight = parseInt( weight ) || 10;
|
||||||
|
if ( weight <= 0 ) {
|
||||||
|
throw "addPreStepLeavePlugin: weight must be a positive integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( preStepLeavePlugins[ weight ] === undefined ) {
|
||||||
|
preStepLeavePlugins[ weight ] = [];
|
||||||
|
}
|
||||||
|
preStepLeavePlugins[ weight ].push( plugin );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called at beginning of goto(), to execute all preStepLeave plugins.
|
||||||
|
var execPreStepLeavePlugins = function( event ) { //jshint ignore:line
|
||||||
|
for ( var i = 0; i < preStepLeavePlugins.length; i++ ) {
|
||||||
|
var thisLevel = preStepLeavePlugins[ i ];
|
||||||
|
if ( thisLevel !== undefined ) {
|
||||||
|
for ( var j = 0; j < thisLevel.length; j++ ) {
|
||||||
|
if ( thisLevel[ j ]( event ) === false ) {
|
||||||
|
|
||||||
|
// If a plugin returns false, the stepleave event (and related transition)
|
||||||
|
// is aborted
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} )( document, window );
|
} )( document, window );
|
||||||
|
|
||||||
// THAT'S ALL FOLKS!
|
// THAT'S ALL FOLKS!
|
||||||
@@ -702,34 +806,43 @@
|
|||||||
recordStartingState( rootId );
|
recordStartingState( rootId );
|
||||||
|
|
||||||
// LIBRARY FUNCTIONS
|
// LIBRARY FUNCTIONS
|
||||||
// Below are definitions of the library functions we return at the end
|
// Definitions of the library functions we return as an object at the end
|
||||||
|
|
||||||
|
// `pushElement` adds a DOM element to the gc stack
|
||||||
var pushElement = function( element ) {
|
var pushElement = function( element ) {
|
||||||
elementList.push( element );
|
elementList.push( element );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience wrapper that combines DOM appendChild with gc.pushElement
|
// `appendChild` is a convenience wrapper that combines DOM appendChild with gc.pushElement
|
||||||
var appendChild = function( parent, element ) {
|
var appendChild = function( parent, element ) {
|
||||||
parent.appendChild( element );
|
parent.appendChild( element );
|
||||||
pushElement( element );
|
pushElement( element );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// `pushEventListener` adds an event listener to the gc stack
|
||||||
var pushEventListener = function( target, type, listenerFunction ) {
|
var pushEventListener = function( target, type, listenerFunction ) {
|
||||||
eventListenerList.push( { target:target, type:type, listener:listenerFunction } );
|
eventListenerList.push( { target:target, type:type, listener:listenerFunction } );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience wrapper that combines DOM addEventListener with gc.pushEventListener
|
// `addEventListener` combines DOM addEventListener with gc.pushEventListener
|
||||||
var addEventListener = function( target, type, listenerFunction ) {
|
var addEventListener = function( target, type, listenerFunction ) {
|
||||||
target.addEventListener( type, listenerFunction );
|
target.addEventListener( type, listenerFunction );
|
||||||
pushEventListener( target, type, listenerFunction );
|
pushEventListener( target, type, listenerFunction );
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the above utilities are not enough, plugins can add their own callback function
|
// `addCallback` If the above utilities are not enough, plugins can add their own callback
|
||||||
// to do arbitrary things.
|
// function to do arbitrary things.
|
||||||
var addCallback = function( callback ) {
|
var addCallback = function( callback ) {
|
||||||
callbackList.push( callback );
|
callbackList.push( callback );
|
||||||
};
|
};
|
||||||
addCallback( function( rootId ) { resetStartingState( rootId ); } );
|
addCallback( function( rootId ) { resetStartingState( rootId ); } );
|
||||||
|
|
||||||
|
// `teardown` will
|
||||||
|
// - execute all callbacks in LIFO order
|
||||||
|
// - call `removeChild` on all DOM elements in LIFO order
|
||||||
|
// - call `removeEventListener` on all event listeners in LIFO order
|
||||||
|
// The goal of a teardown is to return to the same state that the DOM was before
|
||||||
|
// `impress().init()` was called.
|
||||||
var teardown = function() {
|
var teardown = function() {
|
||||||
|
|
||||||
// Execute the callbacks in LIFO order
|
// Execute the callbacks in LIFO order
|
||||||
|
|||||||
142
src/impress.js
142
src/impress.js
@@ -131,9 +131,6 @@
|
|||||||
|
|
||||||
// We can't be sure that `classList` is supported
|
// We can't be sure that `classList` is supported
|
||||||
body.className += " impress-not-supported ";
|
body.className += " impress-not-supported ";
|
||||||
} else {
|
|
||||||
body.classList.remove( "impress-not-supported" );
|
|
||||||
body.classList.add( "impress-supported" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLOBALS AND DEFAULTS
|
// GLOBALS AND DEFAULTS
|
||||||
@@ -143,6 +140,9 @@
|
|||||||
// sure if it makes any sense in practice ;)
|
// sure if it makes any sense in practice ;)
|
||||||
var roots = {};
|
var roots = {};
|
||||||
|
|
||||||
|
var preInitPlugins = [];
|
||||||
|
var preStepLeavePlugins = [];
|
||||||
|
|
||||||
// Some default config values.
|
// Some default config values.
|
||||||
var defaults = {
|
var defaults = {
|
||||||
width: 1024,
|
width: 1024,
|
||||||
@@ -238,12 +238,12 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// `onStepLeave` is called whenever the step element is left
|
// `onStepLeave` is called whenever the currentStep element is left
|
||||||
// but the event is triggered only if the step is the same as
|
// but the event is triggered only if the currentStep is the same as
|
||||||
// last entered step.
|
// lastEntered step.
|
||||||
var onStepLeave = function( step ) {
|
var onStepLeave = function( currentStep, nextStep ) {
|
||||||
if ( lastEntered === step ) {
|
if ( lastEntered === currentStep ) {
|
||||||
lib.util.triggerEvent( step, "impress:stepleave" );
|
lib.util.triggerEvent( currentStep, "impress:stepleave", { next: nextStep } );
|
||||||
lastEntered = null;
|
lastEntered = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -283,9 +283,17 @@
|
|||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize all steps.
|
||||||
|
// Read the data-* attributes, store in internal stepsData, and render with CSS.
|
||||||
|
var initAllSteps = function() {
|
||||||
|
steps = lib.util.$$( ".step", root );
|
||||||
|
steps.forEach( initStep );
|
||||||
|
};
|
||||||
|
|
||||||
// `init` API function that initializes (and runs) the presentation.
|
// `init` API function that initializes (and runs) the presentation.
|
||||||
var init = function() {
|
var init = function() {
|
||||||
if ( initialized ) { return; }
|
if ( initialized ) { return; }
|
||||||
|
execPreInitPlugins( root );
|
||||||
|
|
||||||
// First we set up the viewport for mobile devices.
|
// First we set up the viewport for mobile devices.
|
||||||
// For some reason iPad goes nuts when it is not done properly.
|
// For some reason iPad goes nuts when it is not done properly.
|
||||||
@@ -345,8 +353,7 @@
|
|||||||
body.classList.add( "impress-enabled" );
|
body.classList.add( "impress-enabled" );
|
||||||
|
|
||||||
// Get and init steps
|
// Get and init steps
|
||||||
steps = lib.util.$$( ".step", root );
|
initAllSteps();
|
||||||
steps.forEach( initStep );
|
|
||||||
|
|
||||||
// Set a default initial state of the canvas
|
// Set a default initial state of the canvas
|
||||||
currentState = {
|
currentState = {
|
||||||
@@ -379,11 +386,23 @@
|
|||||||
|
|
||||||
// `goto` API function that moves to step given as `el` parameter (by index, id or element).
|
// `goto` API function that moves to step given as `el` parameter (by index, id or element).
|
||||||
// `duration` optionally given as second parameter, is the transition duration in css.
|
// `duration` optionally given as second parameter, is the transition duration in css.
|
||||||
var goto = function( el, duration ) {
|
// `reason` is the string "next", "prev" or "goto" (default) and will be made available to
|
||||||
|
// preStepLeave plugins.
|
||||||
|
// `origEvent` may contain event that caused the calll to goto, such as a key press event
|
||||||
|
var goto = function( el, duration, reason, origEvent ) {
|
||||||
|
reason = reason || "goto";
|
||||||
|
origEvent = origEvent || null;
|
||||||
|
|
||||||
if ( !initialized || !( el = getStep( el ) ) ) {
|
if ( !initialized ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Presentation not initialized or given element is not a step
|
// Re-execute initAllSteps for each transition. This allows to edit step attributes
|
||||||
|
// dynamically, such as change their coordinates, or even remove or add steps, and have
|
||||||
|
// that change apply when goto() is called.
|
||||||
|
initAllSteps();
|
||||||
|
|
||||||
|
if ( !( el = getStep( el ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +419,31 @@
|
|||||||
|
|
||||||
var step = stepsData[ "impress-" + el.id ];
|
var step = stepsData[ "impress-" + el.id ];
|
||||||
|
|
||||||
|
// If we are in fact moving to another step, start with executing the registered
|
||||||
|
// preStepLeave plugins.
|
||||||
|
if ( activeStep && activeStep !== el ) {
|
||||||
|
var event = { target: activeStep, detail: {} };
|
||||||
|
event.detail.next = el;
|
||||||
|
event.detail.transitionDuration = duration;
|
||||||
|
event.detail.reason = reason;
|
||||||
|
if ( origEvent ) {
|
||||||
|
event.origEvent = origEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( execPreStepLeavePlugins( event ) === false ) {
|
||||||
|
|
||||||
|
// PreStepLeave plugins are allowed to abort the transition altogether, by
|
||||||
|
// returning false.
|
||||||
|
// see stop and substep plugins for an example of doing just that
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugins are allowed to change the detail values
|
||||||
|
el = event.detail.next;
|
||||||
|
step = stepsData[ "impress-" + el.id ];
|
||||||
|
duration = event.detail.transitionDuration;
|
||||||
|
}
|
||||||
|
|
||||||
if ( activeStep ) {
|
if ( activeStep ) {
|
||||||
activeStep.classList.remove( "active" );
|
activeStep.classList.remove( "active" );
|
||||||
body.classList.remove( "impress-on-" + activeStep.id );
|
body.classList.remove( "impress-on-" + activeStep.id );
|
||||||
@@ -444,7 +488,7 @@
|
|||||||
|
|
||||||
// Trigger leave of currently active element (if it's not the same step again)
|
// Trigger leave of currently active element (if it's not the same step again)
|
||||||
if ( activeStep && activeStep !== el ) {
|
if ( activeStep && activeStep !== el ) {
|
||||||
onStepLeave( activeStep );
|
onStepLeave( activeStep, el );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we alter transforms of `root` and `canvas` to trigger transitions.
|
// Now we alter transforms of `root` and `canvas` to trigger transitions.
|
||||||
@@ -522,19 +566,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// `prev` API function goes to previous step (in document order)
|
// `prev` API function goes to previous step (in document order)
|
||||||
var prev = function() {
|
// `event` is optional, may contain the event that caused the need to call prev()
|
||||||
|
var prev = function( origEvent ) {
|
||||||
var prev = steps.indexOf( activeStep ) - 1;
|
var prev = steps.indexOf( activeStep ) - 1;
|
||||||
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length - 1 ];
|
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length - 1 ];
|
||||||
|
|
||||||
return goto( prev );
|
return goto( prev, undefined, "prev", origEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
// `next` API function goes to next step (in document order)
|
// `next` API function goes to next step (in document order)
|
||||||
var next = function() {
|
// `event` is optional, may contain the event that caused the need to call next()
|
||||||
|
var next = function( origEvent ) {
|
||||||
var next = steps.indexOf( activeStep ) + 1;
|
var next = steps.indexOf( activeStep ) + 1;
|
||||||
next = next < steps.length ? steps[ next ] : steps[ 0 ];
|
next = next < steps.length ? steps[ next ] : steps[ 0 ];
|
||||||
|
|
||||||
return goto( next );
|
return goto( next, undefined, "next", origEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Teardown impress
|
// Teardown impress
|
||||||
@@ -659,6 +705,64 @@
|
|||||||
return lib;
|
return lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// `addPreInitPlugin` allows plugins to register a function that should
|
||||||
|
// be run (synchronously) at the beginning of init, before
|
||||||
|
// impress().init() itself executes.
|
||||||
|
impress.addPreInitPlugin = function( plugin, weight ) {
|
||||||
|
weight = parseInt( weight ) || 10;
|
||||||
|
if ( weight <= 0 ) {
|
||||||
|
throw "addPreInitPlugin: weight must be a positive integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( preInitPlugins[ weight ] === undefined ) {
|
||||||
|
preInitPlugins[ weight ] = [];
|
||||||
|
}
|
||||||
|
preInitPlugins[ weight ].push( plugin );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called at beginning of init, to execute all pre-init plugins.
|
||||||
|
var execPreInitPlugins = function( root ) { //jshint ignore:line
|
||||||
|
for ( var i = 0; i < preInitPlugins.length; i++ ) {
|
||||||
|
var thisLevel = preInitPlugins[ i ];
|
||||||
|
if ( thisLevel !== undefined ) {
|
||||||
|
for ( var j = 0; j < thisLevel.length; j++ ) {
|
||||||
|
thisLevel[ j ]( root );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// `addPreStepLeavePlugin` allows plugins to register a function that should
|
||||||
|
// be run (synchronously) at the beginning of goto()
|
||||||
|
impress.addPreStepLeavePlugin = function( plugin, weight ) { //jshint ignore:line
|
||||||
|
weight = parseInt( weight ) || 10;
|
||||||
|
if ( weight <= 0 ) {
|
||||||
|
throw "addPreStepLeavePlugin: weight must be a positive integer";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( preStepLeavePlugins[ weight ] === undefined ) {
|
||||||
|
preStepLeavePlugins[ weight ] = [];
|
||||||
|
}
|
||||||
|
preStepLeavePlugins[ weight ].push( plugin );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called at beginning of goto(), to execute all preStepLeave plugins.
|
||||||
|
var execPreStepLeavePlugins = function( event ) { //jshint ignore:line
|
||||||
|
for ( var i = 0; i < preStepLeavePlugins.length; i++ ) {
|
||||||
|
var thisLevel = preStepLeavePlugins[ i ];
|
||||||
|
if ( thisLevel !== undefined ) {
|
||||||
|
for ( var j = 0; j < thisLevel.length; j++ ) {
|
||||||
|
if ( thisLevel[ j ]( event ) === false ) {
|
||||||
|
|
||||||
|
// If a plugin returns false, the stepleave event (and related transition)
|
||||||
|
// is aborted
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} )( document, window );
|
} )( document, window );
|
||||||
|
|
||||||
// THAT'S ALL FOLKS!
|
// THAT'S ALL FOLKS!
|
||||||
|
|||||||
24
src/plugins/goto/README.md
Normal file
24
src/plugins/goto/README.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Goto Plugin
|
||||||
|
===========
|
||||||
|
|
||||||
|
The goto plugin is a pre-stepleave plugin. It is executed before
|
||||||
|
`impress:stepleave` event, and will alter the destination where to transition next.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<!-- When leaving this step, go directly to "step-5" -->
|
||||||
|
<div class="step" data-goto="step-5">
|
||||||
|
|
||||||
|
<!-- When leaving this step with next(), go directly to "step-5", instead of the next step.
|
||||||
|
If moving backwards to previous step - e.g. prev() instead of next() - then go to "step-1". -->
|
||||||
|
<div class="step" data-goto-next="step-5" data-goto-prev="step-1">
|
||||||
|
|
||||||
|
<!-- data-goto-key-list and data-goto-next-list allow you to build advanced non-linear navigation. -->
|
||||||
|
<div class="step" data-goto-key-list="ArrowUp ArrowDown ArrowRight ArrowLeft" data-goto-next-list="step-4 step-3 step-2 step-5">
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
Copyright 2016 Henrik Ingo (@henrikingo)
|
||||||
|
Released under the MIT license.
|
||||||
|
|
||||||
171
src/plugins/goto/goto.js
Normal file
171
src/plugins/goto/goto.js
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/**
|
||||||
|
* Goto Plugin
|
||||||
|
*
|
||||||
|
* The goto plugin is a pre-stepleave plugin. It is executed before impress:stepleave,
|
||||||
|
* and will alter the destination where to transition next.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <!-- When leaving this step, go directly to "step-5" -->
|
||||||
|
* <div class="step" data-goto="step-5">
|
||||||
|
*
|
||||||
|
* <!-- When leaving this step with next(), go directly to "step-5", instead of next step.
|
||||||
|
* If moving backwards to previous step - e.g. prev() instead of next() -
|
||||||
|
* then go to "step-1". -->
|
||||||
|
* <div class="step" data-goto-next="step-5" data-goto-prev="step-1">
|
||||||
|
*
|
||||||
|
* <!-- data-goto-key-list and data-goto-next-list allow you to build advanced non-linear
|
||||||
|
* navigation. -->
|
||||||
|
* <div class="step"
|
||||||
|
* data-goto-key-list="ArrowUp ArrowDown ArrowRight ArrowLeft"
|
||||||
|
* data-goto-next-list="step-4 step-3 step-2 step-5">
|
||||||
|
*
|
||||||
|
* Copyright 2016-2017 Henrik Ingo (@henrikingo)
|
||||||
|
* Released under the MIT license.
|
||||||
|
*/
|
||||||
|
/* global window, document, impress */
|
||||||
|
|
||||||
|
( function( document, window ) {
|
||||||
|
"use strict";
|
||||||
|
var lib;
|
||||||
|
|
||||||
|
var isNumber = function( numeric ) {
|
||||||
|
return !isNaN( numeric );
|
||||||
|
};
|
||||||
|
|
||||||
|
var goto = function( event ) {
|
||||||
|
if ( ( !event ) || ( !event.target ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = event.target.dataset;
|
||||||
|
var steps = document.querySelectorAll( ".step" );
|
||||||
|
|
||||||
|
// Data-goto-key-list="" & data-goto-next-list="" //////////////////////////////////////////
|
||||||
|
if ( data.gotoKeyList !== undefined &&
|
||||||
|
data.gotoNextList !== undefined &&
|
||||||
|
event.origEvent !== undefined &&
|
||||||
|
event.origEvent.key !== undefined ) {
|
||||||
|
var keylist = data.gotoKeyList.split( " " );
|
||||||
|
var nextlist = data.gotoNextList.split( " " );
|
||||||
|
|
||||||
|
if ( keylist.length !== nextlist.length ) {
|
||||||
|
window.console.log(
|
||||||
|
"impress goto plugin: data-goto-key-list and data-goto-next-list don't match:"
|
||||||
|
);
|
||||||
|
window.console.log( keylist );
|
||||||
|
window.console.log( nextlist );
|
||||||
|
|
||||||
|
// Don't return, allow the other categories to work despite this error
|
||||||
|
} else {
|
||||||
|
var index = keylist.indexOf( event.origEvent.key );
|
||||||
|
if ( index >= 0 ) {
|
||||||
|
var next = nextlist[ index ];
|
||||||
|
if ( isNumber( next ) ) {
|
||||||
|
event.detail.next = steps[ next ];
|
||||||
|
|
||||||
|
// If the new next element has its own transitionDuration, we're responsible
|
||||||
|
// for setting that on the event as well
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration,
|
||||||
|
event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
var newTarget = document.getElementById( next );
|
||||||
|
if ( newTarget && newTarget.classList.contains( "step" ) ) {
|
||||||
|
event.detail.next = newTarget;
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration,
|
||||||
|
event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
window.console.log( "impress goto plugin: " + next +
|
||||||
|
" is not a step in this impress presentation." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data-goto-next="" & data-goto-prev="" ///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Handle event.target data-goto-next attribute
|
||||||
|
if ( isNumber( data.gotoNext ) && event.detail.reason === "next" ) {
|
||||||
|
event.detail.next = steps[ data.gotoNext ];
|
||||||
|
|
||||||
|
// If the new next element has its own transitionDuration, we're responsible for setting
|
||||||
|
// that on the event as well
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration, event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( data.gotoNext && event.detail.reason === "next" ) {
|
||||||
|
var newTarget = document.getElementById( data.gotoNext ); // jshint ignore:line
|
||||||
|
if ( newTarget && newTarget.classList.contains( "step" ) ) {
|
||||||
|
event.detail.next = newTarget;
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration,
|
||||||
|
event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
window.console.log( "impress goto plugin: " + data.gotoNext +
|
||||||
|
" is not a step in this impress presentation." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle event.target data-goto-prev attribute
|
||||||
|
if ( isNumber( data.gotoPrev ) && event.detail.reason === "prev" ) {
|
||||||
|
event.detail.next = steps[ data.gotoPrev ];
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration, event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( data.gotoPrev && event.detail.reason === "prev" ) {
|
||||||
|
var newTarget = document.getElementById( data.gotoPrev ); // jshint ignore:line
|
||||||
|
if ( newTarget && newTarget.classList.contains( "step" ) ) {
|
||||||
|
event.detail.next = newTarget;
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration, event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
window.console.log( "impress goto plugin: " + data.gotoPrev +
|
||||||
|
" is not a step in this impress presentation." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data-goto="" ///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Handle event.target data-goto attribute
|
||||||
|
if ( isNumber( data.goto ) ) {
|
||||||
|
event.detail.next = steps[ data.goto ];
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration, event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( data.goto ) {
|
||||||
|
var newTarget = document.getElementById( data.goto ); // jshint ignore:line
|
||||||
|
if ( newTarget && newTarget.classList.contains( "step" ) ) {
|
||||||
|
event.detail.next = newTarget;
|
||||||
|
event.detail.transitionDuration = lib.util.toNumber(
|
||||||
|
event.detail.next.dataset.transitionDuration, event.detail.transitionDuration
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
window.console.log( "impress goto plugin: " + data.goto +
|
||||||
|
" is not a step in this impress presentation." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the plugin to be called in pre-stepleave phase
|
||||||
|
impress.addPreStepLeavePlugin( goto );
|
||||||
|
|
||||||
|
} )( document, window );
|
||||||
|
|
||||||
89
src/plugins/rel/README.md
Normal file
89
src/plugins/rel/README.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
Relative Positioning Plugin
|
||||||
|
===========================
|
||||||
|
|
||||||
|
This plugin provides support for defining the coordinates of a step relative
|
||||||
|
to the previous step. This is often more convenient when creating presentations,
|
||||||
|
since as you add, remove or move steps, you may not need to edit the positions
|
||||||
|
as much as is the case with the absolute coordinates supported by impress.js
|
||||||
|
core.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<!-- Position step 1000 px to the right and 500 px up from the previous step. -->
|
||||||
|
<div class="step" data-rel-x="1000" data-rel-y="500">
|
||||||
|
|
||||||
|
Following html attributes are supported for step elements:
|
||||||
|
|
||||||
|
data-rel-x
|
||||||
|
data-rel-y
|
||||||
|
data-rel-z
|
||||||
|
|
||||||
|
Non-zero values are also inherited from the previous step. This makes it easy to
|
||||||
|
create a boring presentation where each slide shifts for example 1000px down
|
||||||
|
from the previous.
|
||||||
|
|
||||||
|
The above relative values are ignored, or set to zero, if the corresponding
|
||||||
|
absolute value (`data-x` etc...) is set. Note that this also has the effect of
|
||||||
|
resetting the inheritance functionality.
|
||||||
|
|
||||||
|
In addition to plain numbers, which are pixel values, it is also possible to
|
||||||
|
define relative positions as a multiple of screen height and width, using
|
||||||
|
a unit of "h" and "w", respectively, appended to the number.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<div class="step" data-rel-x="1.5w" data-rel-y="1.5h">
|
||||||
|
|
||||||
|
|
||||||
|
IMPORTANT: Incompatible change
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Enabling / adding this plugin has a small incompatible side effect on default values.
|
||||||
|
|
||||||
|
Prior to this plugin, a missing data-x/y/z attribute would be assigned the default value of 0.
|
||||||
|
But when using a version of impress.js with this plugin enabled, a missing data-x/y/z attribute
|
||||||
|
will inherit the value from the previous step. (The first step will inherit the default value of 0.)
|
||||||
|
|
||||||
|
For example, if you have an old presentation with the following 3 steps, they would be positioned
|
||||||
|
differently when using a version of impress.js that includes this plugin:
|
||||||
|
|
||||||
|
<div class="step" data-x="100" data-y="100" data-z="100"></div>
|
||||||
|
<div class="step" data-x="100" data-y="100"></div>
|
||||||
|
<div class="step" data-x="100" data-y="100"></div>
|
||||||
|
|
||||||
|
To get the same rendering now, you need to add an explicit `data-z="0"` to the second step:
|
||||||
|
|
||||||
|
<div class="step" data-x="100" data-y="100" data-z="100"></div>
|
||||||
|
<div class="step" data-x="100" data-y="100" data-z="0"></div>
|
||||||
|
<div class="step" data-x="100" data-y="100"></div>
|
||||||
|
|
||||||
|
Note that the latter code will render correctly also in old versions of impress.js.
|
||||||
|
|
||||||
|
If you have an old presentation that doesn't use relative positioning, and for some reason you
|
||||||
|
cannot or don't want to add the explicit 0 values where needed, your last resort is to simply
|
||||||
|
remove the `rel.js` plugin completely. You can either:
|
||||||
|
|
||||||
|
* Remove `rel.js` from [/build.js](../../../build.js) and recompile `impress.js` with: `npm build`
|
||||||
|
* Just open [/js/impress.js] in an editor and delete the `rel.js` code.
|
||||||
|
* Or, just uncomment the following single line, which is the last line of the plugin:
|
||||||
|
|
||||||
|
impress.addPreInitPlugin( rel );
|
||||||
|
|
||||||
|
|
||||||
|
About Pre-Init Plugins
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
This plugin is a *pre-init plugin*. It is called synchronously from impress.js
|
||||||
|
core at the beginning of `impress().init()`. This allows it to process its own
|
||||||
|
data attributes first, and possibly alter the data-x, data-y and data-z attributes
|
||||||
|
that will then be processed by `impress().init()`.
|
||||||
|
|
||||||
|
(Another name for this kind of plugin might be called a *filter plugin*, but
|
||||||
|
*pre-init plugin* is more generic, as a plugin might do whatever it wants in
|
||||||
|
the pre-init stage.)
|
||||||
|
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
Henrik Ingo (@henrikingo), 2016
|
||||||
167
src/plugins/rel/rel.js
Normal file
167
src/plugins/rel/rel.js
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/**
|
||||||
|
* Relative Positioning Plugin
|
||||||
|
*
|
||||||
|
* This plugin provides support for defining the coordinates of a step relative
|
||||||
|
* to the previous step. This is often more convenient when creating presentations,
|
||||||
|
* since as you add, remove or move steps, you may not need to edit the positions
|
||||||
|
* as much as is the case with the absolute coordinates supported by impress.js
|
||||||
|
* core.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <!-- Position step 1000 px to the right and 500 px up from the previous step. -->
|
||||||
|
* <div class="step" data-rel-x="1000" data-rel-y="500">
|
||||||
|
*
|
||||||
|
* Following html attributes are supported for step elements:
|
||||||
|
*
|
||||||
|
* data-rel-x
|
||||||
|
* data-rel-y
|
||||||
|
* data-rel-z
|
||||||
|
*
|
||||||
|
* These values are also inherited from the previous step. This makes it easy to
|
||||||
|
* create a boring presentation where each slide shifts for example 1000px down
|
||||||
|
* from the previous.
|
||||||
|
*
|
||||||
|
* In addition to plain numbers, which are pixel values, it is also possible to
|
||||||
|
* define relative positions as a multiple of screen height and width, using
|
||||||
|
* a unit of "h" and "w", respectively, appended to the number.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <div class="step" data-rel-x="1.5w" data-rel-y="1.5h">
|
||||||
|
*
|
||||||
|
* This plugin is a *pre-init plugin*. It is called synchronously from impress.js
|
||||||
|
* core at the beginning of `impress().init()`. This allows it to process its own
|
||||||
|
* data attributes first, and possibly alter the data-x, data-y and data-z attributes
|
||||||
|
* that will then be processed by `impress().init()`.
|
||||||
|
*
|
||||||
|
* (Another name for this kind of plugin might be called a *filter plugin*, but
|
||||||
|
* *pre-init plugin* is more generic, as a plugin might do whatever it wants in
|
||||||
|
* the pre-init stage.)
|
||||||
|
*
|
||||||
|
* Copyright 2016 Henrik Ingo (@henrikingo)
|
||||||
|
* Released under the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global document, window */
|
||||||
|
|
||||||
|
( function( document, window ) {
|
||||||
|
"use strict";
|
||||||
|
var lib;
|
||||||
|
|
||||||
|
var startingState = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends toNumber() to correctly compute also relative-to-screen-size values 5w and 5h.
|
||||||
|
*
|
||||||
|
* Returns the computed value in pixels with w/h postfix removed.
|
||||||
|
*/
|
||||||
|
var toNumberAdvanced = function( numeric, fallback ) {
|
||||||
|
if ( typeof numeric !== "string" ) {
|
||||||
|
return lib.util.toNumber( numeric, fallback );
|
||||||
|
}
|
||||||
|
var ratio = numeric.match( /^([+-]*[\d\.]+)([wh])$/ );
|
||||||
|
if ( ratio == null ) {
|
||||||
|
return lib.util.toNumber( numeric, fallback );
|
||||||
|
} else {
|
||||||
|
var value = parseFloat( ratio[ 1 ] );
|
||||||
|
var multiplier = ratio[ 2 ] === "w" ? window.innerWidth : window.innerHeight;
|
||||||
|
return value * multiplier;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var computeRelativePositions = function( el, prev ) {
|
||||||
|
var data = el.dataset;
|
||||||
|
|
||||||
|
if ( !prev ) {
|
||||||
|
|
||||||
|
// For the first step, inherit these defaults
|
||||||
|
prev = { x:0, y:0, z:0, relative: { x:0, y:0, z:0 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
var step = {
|
||||||
|
x: lib.util.toNumber( data.x, prev.x ),
|
||||||
|
y: lib.util.toNumber( data.y, prev.y ),
|
||||||
|
z: lib.util.toNumber( data.z, prev.z ),
|
||||||
|
relative: {
|
||||||
|
x: toNumberAdvanced( data.relX, prev.relative.x ),
|
||||||
|
y: toNumberAdvanced( data.relY, prev.relative.y ),
|
||||||
|
z: toNumberAdvanced( data.relZ, prev.relative.z )
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Relative position is ignored/zero if absolute is given.
|
||||||
|
// Note that this also has the effect of resetting any inherited relative values.
|
||||||
|
if ( data.x !== undefined ) {
|
||||||
|
step.relative.x = 0;
|
||||||
|
}
|
||||||
|
if ( data.y !== undefined ) {
|
||||||
|
step.relative.y = 0;
|
||||||
|
}
|
||||||
|
if ( data.z !== undefined ) {
|
||||||
|
step.relative.z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply relative position to absolute position, if non-zero
|
||||||
|
// Note that at this point, the relative values contain a number value of pixels.
|
||||||
|
step.x = step.x + step.relative.x;
|
||||||
|
step.y = step.y + step.relative.y;
|
||||||
|
step.z = step.z + step.relative.z;
|
||||||
|
|
||||||
|
return step;
|
||||||
|
};
|
||||||
|
|
||||||
|
var rel = function( root ) {
|
||||||
|
var steps = root.querySelectorAll( ".step" );
|
||||||
|
var prev;
|
||||||
|
startingState[ root.id ] = [];
|
||||||
|
for ( var i = 0; i < steps.length; i++ ) {
|
||||||
|
var el = steps[ i ];
|
||||||
|
startingState[ root.id ].push( {
|
||||||
|
el: el,
|
||||||
|
x: el.getAttribute( "data-x" ),
|
||||||
|
y: el.getAttribute( "data-y" ),
|
||||||
|
z: el.getAttribute( "data-z" )
|
||||||
|
} );
|
||||||
|
var step = computeRelativePositions( el, prev );
|
||||||
|
|
||||||
|
// Apply relative position (if non-zero)
|
||||||
|
el.setAttribute( "data-x", step.x );
|
||||||
|
el.setAttribute( "data-y", step.y );
|
||||||
|
el.setAttribute( "data-z", step.z );
|
||||||
|
prev = step;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the plugin to be called in pre-init phase
|
||||||
|
window.impress.addPreInitPlugin( rel );
|
||||||
|
|
||||||
|
// Register teardown callback to reset the data.x, .y, .z values.
|
||||||
|
document.addEventListener( "impress:init", function( event ) {
|
||||||
|
var root = event.target;
|
||||||
|
lib = event.detail.api.lib;
|
||||||
|
lib.gc.addCallback( function() {
|
||||||
|
var steps = startingState[ root.id ];
|
||||||
|
var step;
|
||||||
|
while ( step = steps.pop() ) {
|
||||||
|
if ( step.x === null ) {
|
||||||
|
step.el.removeAttribute( "data-x" );
|
||||||
|
} else {
|
||||||
|
step.el.setAttribute( "data-x", step.x );
|
||||||
|
}
|
||||||
|
if ( step.y === null ) {
|
||||||
|
step.el.removeAttribute( "data-y" );
|
||||||
|
} else {
|
||||||
|
step.el.setAttribute( "data-y", step.y );
|
||||||
|
}
|
||||||
|
if ( step.z === null ) {
|
||||||
|
step.el.removeAttribute( "data-z" );
|
||||||
|
} else {
|
||||||
|
step.el.setAttribute( "data-z", step.z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete startingState[ root.id ];
|
||||||
|
} );
|
||||||
|
}, false );
|
||||||
|
} )( document, window );
|
||||||
|
|
||||||
21
src/plugins/stop/README.md
Normal file
21
src/plugins/stop/README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Stop Plugin
|
||||||
|
===========
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<!-- Stop at this slide.
|
||||||
|
(For example, when used on the last slide, this prevents the
|
||||||
|
presentation from wrapping back to the beginning.) -->
|
||||||
|
<div class="step stop">
|
||||||
|
|
||||||
|
The stop plugin is a pre-stepleave plugin. It is executed before
|
||||||
|
`impress:stepleave` event. If the current slide has `class="stop"`
|
||||||
|
set, it will disable the next() command by setting the next slide to the current
|
||||||
|
slide.
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
Copyright 2016 Henrik Ingo (@henrikingo)
|
||||||
|
Released under the MIT license.
|
||||||
|
|
||||||
35
src/plugins/stop/stop.js
Normal file
35
src/plugins/stop/stop.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Stop Plugin
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <!-- Stop at this slide.
|
||||||
|
* (For example, when used on the last slide, this prevents the
|
||||||
|
* presentation from wrapping back to the beginning.) -->
|
||||||
|
* <div class="step stop">
|
||||||
|
*
|
||||||
|
* Copyright 2016 Henrik Ingo (@henrikingo)
|
||||||
|
* Released under the MIT license.
|
||||||
|
*/
|
||||||
|
/* global document, window */
|
||||||
|
( function( document, window ) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var stop = function( event ) {
|
||||||
|
if ( ( !event ) || ( !event.target ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event.target.classList.contains( "stop" ) ) {
|
||||||
|
if ( event.detail.reason === "next" ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the plugin to be called in pre-stepleave phase
|
||||||
|
// The weight makes this plugin run fairly early.
|
||||||
|
window.impress.addPreStepLeavePlugin( stop, 2 );
|
||||||
|
|
||||||
|
} )( document, window );
|
||||||
|
|
||||||
Reference in New Issue
Block a user