diff --git a/build.js b/build.js index aad050a..b359316 100644 --- a/build.js +++ b/build.js @@ -4,6 +4,7 @@ buildify() .load('src/impress.js') // Libraries from src/lib .concat(['src/lib/gc.js']) + .concat(['src/lib/util.js']) // Plugins from src/plugins .concat(['src/plugins/navigation/navigation.js', 'src/plugins/resize/resize.js']) diff --git a/js/impress.js b/js/impress.js index cae1809..6a90cad 100644 --- a/js/impress.js +++ b/js/impress.js @@ -20,6 +20,7 @@ // Let me show you the cogs that make impress.js run... ( function( document, window ) { "use strict"; + var lib; // HELPER FUNCTIONS @@ -53,12 +54,6 @@ } )(); - // `arrayify` takes an array-like object and turns it into real Array - // to make all the Array.prototype goodness available. - var arrayify = function( a ) { - return [].slice.call( a ); - }; - // `css` function applies the styles given in `props` object to the element // given as `el`. It runs all property names through `pfx` function to make // sure proper prefixed version of the property is used. @@ -75,40 +70,6 @@ return el; }; - // `toNumber` takes a value given as `numeric` parameter and tries to turn - // it into a number. If it is not possible it returns 0 (or other value - // given as `fallback`). - var toNumber = function( numeric, fallback ) { - return isNaN( numeric ) ? ( fallback || 0 ) : Number( numeric ); - }; - - // `byId` returns element with given `id` - you probably have guessed that ;) - var byId = function( id ) { - return document.getElementById( id ); - }; - - // `$` returns first element for given CSS `selector` in the `context` of - // the given element or whole document. - var $ = function( selector, context ) { - context = context || document; - return context.querySelector( selector ); - }; - - // `$$` return an array of elements for given CSS `selector` in the `context` of - // the given element or whole document. - var $$ = function( selector, context ) { - context = context || document; - return arrayify( context.querySelectorAll( selector ) ); - }; - - // `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data - // and triggers it on element given as `el`. - var triggerEvent = function( el, eventName, detail ) { - var event = document.createEvent( "CustomEvent" ); - event.initCustomEvent( eventName, true, true, detail ); - el.dispatchEvent( event ); - }; - // `translate` builds a translate transform string for given data. var translate = function( t ) { return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) "; @@ -130,15 +91,6 @@ return " scale(" + s + ") "; }; - // `getElementFromHash` returns an element located by id from hash part of - // window location. - var getElementFromHash = function() { - - // Get id from url # by removing `#` or `#/` from the beginning, - // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work - return byId( window.location.hash.replace( /^#\/?/, "" ) ); - }; - // `computeWindowScale` counts the scale factor between window size and size // defined for the presentation in the config. var computeWindowScale = function( config ) { @@ -236,7 +188,7 @@ } // The gc library depends on being initialized before we do any changes to DOM. - var lib = initLibraries( rootId ); + lib = initLibraries( rootId ); body.classList.remove( "impress-not-supported" ); body.classList.add( "impress-supported" ); @@ -260,7 +212,7 @@ var windowScale = null; // Root presentation elements - var root = byId( rootId ); + var root = lib.util.byId( rootId ); var canvas = document.createElement( "div" ); var initialized = false; @@ -281,7 +233,7 @@ // last entered step. var onStepEnter = function( step ) { if ( lastEntered !== step ) { - triggerEvent( step, "impress:stepenter" ); + lib.util.triggerEvent( step, "impress:stepenter" ); lastEntered = step; } }; @@ -291,7 +243,7 @@ // last entered step. var onStepLeave = function( step ) { if ( lastEntered === step ) { - triggerEvent( step, "impress:stepleave" ); + lib.util.triggerEvent( step, "impress:stepleave" ); lastEntered = null; } }; @@ -302,16 +254,16 @@ var data = el.dataset, step = { translate: { - x: toNumber( data.x ), - y: toNumber( data.y ), - z: toNumber( data.z ) + x: lib.util.toNumber( data.x ), + y: lib.util.toNumber( data.y ), + z: lib.util.toNumber( data.z ) }, rotate: { - x: toNumber( data.rotateX ), - y: toNumber( data.rotateY ), - z: toNumber( data.rotateZ || data.rotate ) + x: lib.util.toNumber( data.rotateX ), + y: lib.util.toNumber( data.rotateY ), + z: lib.util.toNumber( data.rotateZ || data.rotate ) }, - scale: toNumber( data.scale, 1 ), + scale: lib.util.toNumber( data.scale, 1 ), el: el }; @@ -337,7 +289,7 @@ // First we set up the viewport for mobile devices. // For some reason iPad goes nuts when it is not done properly. - var meta = $( "meta[name='viewport']" ) || document.createElement( "meta" ); + var meta = lib.util.$( "meta[name='viewport']" ) || document.createElement( "meta" ); meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no"; if ( meta.parentNode !== document.head ) { meta.name = "viewport"; @@ -347,12 +299,12 @@ // Initialize configuration object var rootData = root.dataset; config = { - width: toNumber( rootData.width, defaults.width ), - height: toNumber( rootData.height, defaults.height ), - maxScale: toNumber( rootData.maxScale, defaults.maxScale ), - minScale: toNumber( rootData.minScale, defaults.minScale ), - perspective: toNumber( rootData.perspective, defaults.perspective ), - transitionDuration: toNumber( + width: lib.util.toNumber( rootData.width, defaults.width ), + height: lib.util.toNumber( rootData.height, defaults.height ), + maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), + minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), + perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), + transitionDuration: lib.util.toNumber( rootData.transitionDuration, defaults.transitionDuration ) }; @@ -360,7 +312,7 @@ windowScale = computeWindowScale( config ); // Wrap steps with "canvas" element - arrayify( root.childNodes ).forEach( function( el ) { + lib.util.arrayify( root.childNodes ).forEach( function( el ) { canvas.appendChild( el ); } ); root.appendChild( canvas ); @@ -393,7 +345,7 @@ body.classList.add( "impress-enabled" ); // Get and init steps - steps = $$( ".step", root ); + steps = lib.util.$$( ".step", root ); steps.forEach( initStep ); // Set a default initial state of the canvas @@ -405,7 +357,8 @@ initialized = true; - triggerEvent( root, "impress:init", { api: roots[ "impress-root-" + rootId ] } ); + lib.util.triggerEvent( root, "impress:init", + { api: roots[ "impress-root-" + rootId ] } ); }; // `getStep` is a helper function that returns a step element defined by parameter. @@ -416,7 +369,7 @@ if ( typeof step === "number" ) { step = step < 0 ? steps[ steps.length + step ] : steps[ step ]; } else if ( typeof step === "string" ) { - step = byId( step ); + step = lib.util.byId( step ); } return ( step && step.id && stepsData[ "impress-" + step.id ] ) ? step : null; }; @@ -478,7 +431,7 @@ // with scaling down and move and rotation are delayed. var zoomin = target.scale >= currentState.scale; - duration = toNumber( duration, config.transitionDuration ); + duration = lib.util.toNumber( duration, config.transitionDuration ); var delay = ( duration / 2 ); // If the same step is re-selected, force computing window scaling, @@ -650,13 +603,13 @@ // // To avoid this we store last entered hash and compare. if ( window.location.hash !== lastHash ) { - goto( getElementFromHash() ); + goto( lib.util.getElementFromHash() ); } }, false ); // START // by selecting step defined in url or first step of the presentation - goto( getElementFromHash() || steps[ 0 ], 0 ); + goto( lib.util.getElementFromHash() || steps[ 0 ], 0 ); }, false ); body.classList.add( "impress-disabled" ); @@ -946,6 +899,104 @@ } )( document, window ); +/** + * Common utility functions + * + * Copyright 2011-2012 Bartek Szopka (@bartaz) + * Henrik Ingo (c) 2016 + * MIT License + */ + +( function( document, window ) { + "use strict"; + var roots = []; + + var libraryFactory = function( rootId ) { + if ( roots[ rootId ] ) { + return roots[ rootId ]; + } + + // `$` returns first element for given CSS `selector` in the `context` of + // the given element or whole document. + var $ = function( selector, context ) { + context = context || document; + return context.querySelector( selector ); + }; + + // `$$` return an array of elements for given CSS `selector` in the `context` of + // the given element or whole document. + var $$ = function( selector, context ) { + context = context || document; + return arrayify( context.querySelectorAll( selector ) ); + }; + + // `arrayify` takes an array-like object and turns it into real Array + // to make all the Array.prototype goodness available. + var arrayify = function( a ) { + return [].slice.call( a ); + }; + + // `byId` returns element with given `id` - you probably have guessed that ;) + var byId = function( id ) { + return document.getElementById( id ); + }; + + // `getElementFromHash` returns an element located by id from hash part of + // window location. + var getElementFromHash = function() { + + // Get id from url # by removing `#` or `#/` from the beginning, + // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work + return byId( window.location.hash.replace( /^#\/?/, "" ) ); + }; + + // Throttling function calls, by Remy Sharp + // http://remysharp.com/2010/07/21/throttling-function-calls/ + var throttle = function( fn, delay ) { + var timer = null; + return function() { + var context = this, args = arguments; + window.clearTimeout( timer ); + timer = window.setTimeout( function() { + fn.apply( context, args ); + }, delay ); + }; + }; + + // `toNumber` takes a value given as `numeric` parameter and tries to turn + // it into a number. If it is not possible it returns 0 (or other value + // given as `fallback`). + var toNumber = function( numeric, fallback ) { + return isNaN( numeric ) ? ( fallback || 0 ) : Number( numeric ); + }; + + // `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data + // and triggers it on element given as `el`. + var triggerEvent = function( el, eventName, detail ) { + var event = document.createEvent( "CustomEvent" ); + event.initCustomEvent( eventName, true, true, detail ); + el.dispatchEvent( event ); + }; + + var lib = { + $: $, + $$: $$, + arrayify: arrayify, + byId: byId, + getElementFromHash: getElementFromHash, + throttle: throttle, + toNumber: toNumber, + triggerEvent: triggerEvent + }; + roots[ rootId ] = lib; + return lib; + }; + + // Let impress core know about the existence of this library + window.impress.addLibraryFactory( { util: libraryFactory } ); + +} )( document, window ); + /** * Navigation events plugin * @@ -973,12 +1024,6 @@ ( function( document ) { "use strict"; - var triggerEvent = function( el, eventName, detail ) { - var event = document.createEvent( "CustomEvent" ); - event.initCustomEvent( eventName, true, true, detail ); - el.dispatchEvent( event ); - }; - // Wait for impress.js to be initialized document.addEventListener( "impress:init", function( event ) { @@ -988,6 +1033,7 @@ // need to control the presentation that was just initialized. var api = event.detail.api; var gc = api.lib.gc; + var util = api.lib.util; // Supported keys are: // [space] - quite common in presentation software to move forward @@ -1114,8 +1160,9 @@ }, false ); // Add a line to the help popup - triggerEvent( document, "impress:help:add", - { command: "Left & Right", text: "Previous & Next step", row: 1 } ); + util.triggerEvent( document, "impress:help:add", { command: "Left & Right", + text: "Previous & Next step", + row: 1 } ); }, false ); @@ -1142,25 +1189,12 @@ ( function( document, window ) { "use strict"; - // Throttling function calls, by Remy Sharp - // http://remysharp.com/2010/07/21/throttling-function-calls/ - var throttle = function( fn, delay ) { - var timer = null; - return function() { - var context = this, args = arguments; - window.clearTimeout( timer ); - timer = window.setTimeout( function() { - fn.apply( context, args ); - }, delay ); - }; - }; - // Wait for impress.js to be initialized document.addEventListener( "impress:init", function( event ) { var api = event.detail.api; // Rescale presentation when window is resized - api.lib.gc.addEventListener( window, "resize", throttle( function() { + api.lib.gc.addEventListener( window, "resize", api.lib.util.throttle( function() { // Force going to active step again, to trigger rescaling api.goto( document.querySelector( ".step.active" ), 500 ); diff --git a/src/impress.js b/src/impress.js index cfc3642..4788673 100644 --- a/src/impress.js +++ b/src/impress.js @@ -20,6 +20,7 @@ // Let me show you the cogs that make impress.js run... ( function( document, window ) { "use strict"; + var lib; // HELPER FUNCTIONS @@ -53,12 +54,6 @@ } )(); - // `arrayify` takes an array-like object and turns it into real Array - // to make all the Array.prototype goodness available. - var arrayify = function( a ) { - return [].slice.call( a ); - }; - // `css` function applies the styles given in `props` object to the element // given as `el`. It runs all property names through `pfx` function to make // sure proper prefixed version of the property is used. @@ -75,40 +70,6 @@ return el; }; - // `toNumber` takes a value given as `numeric` parameter and tries to turn - // it into a number. If it is not possible it returns 0 (or other value - // given as `fallback`). - var toNumber = function( numeric, fallback ) { - return isNaN( numeric ) ? ( fallback || 0 ) : Number( numeric ); - }; - - // `byId` returns element with given `id` - you probably have guessed that ;) - var byId = function( id ) { - return document.getElementById( id ); - }; - - // `$` returns first element for given CSS `selector` in the `context` of - // the given element or whole document. - var $ = function( selector, context ) { - context = context || document; - return context.querySelector( selector ); - }; - - // `$$` return an array of elements for given CSS `selector` in the `context` of - // the given element or whole document. - var $$ = function( selector, context ) { - context = context || document; - return arrayify( context.querySelectorAll( selector ) ); - }; - - // `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data - // and triggers it on element given as `el`. - var triggerEvent = function( el, eventName, detail ) { - var event = document.createEvent( "CustomEvent" ); - event.initCustomEvent( eventName, true, true, detail ); - el.dispatchEvent( event ); - }; - // `translate` builds a translate transform string for given data. var translate = function( t ) { return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) "; @@ -130,15 +91,6 @@ return " scale(" + s + ") "; }; - // `getElementFromHash` returns an element located by id from hash part of - // window location. - var getElementFromHash = function() { - - // Get id from url # by removing `#` or `#/` from the beginning, - // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work - return byId( window.location.hash.replace( /^#\/?/, "" ) ); - }; - // `computeWindowScale` counts the scale factor between window size and size // defined for the presentation in the config. var computeWindowScale = function( config ) { @@ -236,7 +188,7 @@ } // The gc library depends on being initialized before we do any changes to DOM. - var lib = initLibraries( rootId ); + lib = initLibraries( rootId ); body.classList.remove( "impress-not-supported" ); body.classList.add( "impress-supported" ); @@ -260,7 +212,7 @@ var windowScale = null; // Root presentation elements - var root = byId( rootId ); + var root = lib.util.byId( rootId ); var canvas = document.createElement( "div" ); var initialized = false; @@ -281,7 +233,7 @@ // last entered step. var onStepEnter = function( step ) { if ( lastEntered !== step ) { - triggerEvent( step, "impress:stepenter" ); + lib.util.triggerEvent( step, "impress:stepenter" ); lastEntered = step; } }; @@ -291,7 +243,7 @@ // last entered step. var onStepLeave = function( step ) { if ( lastEntered === step ) { - triggerEvent( step, "impress:stepleave" ); + lib.util.triggerEvent( step, "impress:stepleave" ); lastEntered = null; } }; @@ -302,16 +254,16 @@ var data = el.dataset, step = { translate: { - x: toNumber( data.x ), - y: toNumber( data.y ), - z: toNumber( data.z ) + x: lib.util.toNumber( data.x ), + y: lib.util.toNumber( data.y ), + z: lib.util.toNumber( data.z ) }, rotate: { - x: toNumber( data.rotateX ), - y: toNumber( data.rotateY ), - z: toNumber( data.rotateZ || data.rotate ) + x: lib.util.toNumber( data.rotateX ), + y: lib.util.toNumber( data.rotateY ), + z: lib.util.toNumber( data.rotateZ || data.rotate ) }, - scale: toNumber( data.scale, 1 ), + scale: lib.util.toNumber( data.scale, 1 ), el: el }; @@ -337,7 +289,7 @@ // First we set up the viewport for mobile devices. // For some reason iPad goes nuts when it is not done properly. - var meta = $( "meta[name='viewport']" ) || document.createElement( "meta" ); + var meta = lib.util.$( "meta[name='viewport']" ) || document.createElement( "meta" ); meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no"; if ( meta.parentNode !== document.head ) { meta.name = "viewport"; @@ -347,12 +299,12 @@ // Initialize configuration object var rootData = root.dataset; config = { - width: toNumber( rootData.width, defaults.width ), - height: toNumber( rootData.height, defaults.height ), - maxScale: toNumber( rootData.maxScale, defaults.maxScale ), - minScale: toNumber( rootData.minScale, defaults.minScale ), - perspective: toNumber( rootData.perspective, defaults.perspective ), - transitionDuration: toNumber( + width: lib.util.toNumber( rootData.width, defaults.width ), + height: lib.util.toNumber( rootData.height, defaults.height ), + maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), + minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), + perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), + transitionDuration: lib.util.toNumber( rootData.transitionDuration, defaults.transitionDuration ) }; @@ -360,7 +312,7 @@ windowScale = computeWindowScale( config ); // Wrap steps with "canvas" element - arrayify( root.childNodes ).forEach( function( el ) { + lib.util.arrayify( root.childNodes ).forEach( function( el ) { canvas.appendChild( el ); } ); root.appendChild( canvas ); @@ -393,7 +345,7 @@ body.classList.add( "impress-enabled" ); // Get and init steps - steps = $$( ".step", root ); + steps = lib.util.$$( ".step", root ); steps.forEach( initStep ); // Set a default initial state of the canvas @@ -405,7 +357,8 @@ initialized = true; - triggerEvent( root, "impress:init", { api: roots[ "impress-root-" + rootId ] } ); + lib.util.triggerEvent( root, "impress:init", + { api: roots[ "impress-root-" + rootId ] } ); }; // `getStep` is a helper function that returns a step element defined by parameter. @@ -416,7 +369,7 @@ if ( typeof step === "number" ) { step = step < 0 ? steps[ steps.length + step ] : steps[ step ]; } else if ( typeof step === "string" ) { - step = byId( step ); + step = lib.util.byId( step ); } return ( step && step.id && stepsData[ "impress-" + step.id ] ) ? step : null; }; @@ -478,7 +431,7 @@ // with scaling down and move and rotation are delayed. var zoomin = target.scale >= currentState.scale; - duration = toNumber( duration, config.transitionDuration ); + duration = lib.util.toNumber( duration, config.transitionDuration ); var delay = ( duration / 2 ); // If the same step is re-selected, force computing window scaling, @@ -650,13 +603,13 @@ // // To avoid this we store last entered hash and compare. if ( window.location.hash !== lastHash ) { - goto( getElementFromHash() ); + goto( lib.util.getElementFromHash() ); } }, false ); // START // by selecting step defined in url or first step of the presentation - goto( getElementFromHash() || steps[ 0 ], 0 ); + goto( lib.util.getElementFromHash() || steps[ 0 ], 0 ); }, false ); body.classList.add( "impress-disabled" ); diff --git a/src/lib/util.js b/src/lib/util.js new file mode 100644 index 0000000..bd7dcbb --- /dev/null +++ b/src/lib/util.js @@ -0,0 +1,97 @@ +/** + * Common utility functions + * + * Copyright 2011-2012 Bartek Szopka (@bartaz) + * Henrik Ingo (c) 2016 + * MIT License + */ + +( function( document, window ) { + "use strict"; + var roots = []; + + var libraryFactory = function( rootId ) { + if ( roots[ rootId ] ) { + return roots[ rootId ]; + } + + // `$` returns first element for given CSS `selector` in the `context` of + // the given element or whole document. + var $ = function( selector, context ) { + context = context || document; + return context.querySelector( selector ); + }; + + // `$$` return an array of elements for given CSS `selector` in the `context` of + // the given element or whole document. + var $$ = function( selector, context ) { + context = context || document; + return arrayify( context.querySelectorAll( selector ) ); + }; + + // `arrayify` takes an array-like object and turns it into real Array + // to make all the Array.prototype goodness available. + var arrayify = function( a ) { + return [].slice.call( a ); + }; + + // `byId` returns element with given `id` - you probably have guessed that ;) + var byId = function( id ) { + return document.getElementById( id ); + }; + + // `getElementFromHash` returns an element located by id from hash part of + // window location. + var getElementFromHash = function() { + + // Get id from url # by removing `#` or `#/` from the beginning, + // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work + return byId( window.location.hash.replace( /^#\/?/, "" ) ); + }; + + // Throttling function calls, by Remy Sharp + // http://remysharp.com/2010/07/21/throttling-function-calls/ + var throttle = function( fn, delay ) { + var timer = null; + return function() { + var context = this, args = arguments; + window.clearTimeout( timer ); + timer = window.setTimeout( function() { + fn.apply( context, args ); + }, delay ); + }; + }; + + // `toNumber` takes a value given as `numeric` parameter and tries to turn + // it into a number. If it is not possible it returns 0 (or other value + // given as `fallback`). + var toNumber = function( numeric, fallback ) { + return isNaN( numeric ) ? ( fallback || 0 ) : Number( numeric ); + }; + + // `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data + // and triggers it on element given as `el`. + var triggerEvent = function( el, eventName, detail ) { + var event = document.createEvent( "CustomEvent" ); + event.initCustomEvent( eventName, true, true, detail ); + el.dispatchEvent( event ); + }; + + var lib = { + $: $, + $$: $$, + arrayify: arrayify, + byId: byId, + getElementFromHash: getElementFromHash, + throttle: throttle, + toNumber: toNumber, + triggerEvent: triggerEvent + }; + roots[ rootId ] = lib; + return lib; + }; + + // Let impress core know about the existence of this library + window.impress.addLibraryFactory( { util: libraryFactory } ); + +} )( document, window ); diff --git a/src/plugins/navigation/navigation.js b/src/plugins/navigation/navigation.js index 0db7b00..60f75ad 100644 --- a/src/plugins/navigation/navigation.js +++ b/src/plugins/navigation/navigation.js @@ -25,12 +25,6 @@ ( function( document ) { "use strict"; - var triggerEvent = function( el, eventName, detail ) { - var event = document.createEvent( "CustomEvent" ); - event.initCustomEvent( eventName, true, true, detail ); - el.dispatchEvent( event ); - }; - // Wait for impress.js to be initialized document.addEventListener( "impress:init", function( event ) { @@ -40,6 +34,7 @@ // need to control the presentation that was just initialized. var api = event.detail.api; var gc = api.lib.gc; + var util = api.lib.util; // Supported keys are: // [space] - quite common in presentation software to move forward @@ -166,8 +161,9 @@ }, false ); // Add a line to the help popup - triggerEvent( document, "impress:help:add", - { command: "Left & Right", text: "Previous & Next step", row: 1 } ); + util.triggerEvent( document, "impress:help:add", { command: "Left & Right", + text: "Previous & Next step", + row: 1 } ); }, false ); diff --git a/src/plugins/resize/resize.js b/src/plugins/resize/resize.js index 636d5da..ca8efb4 100644 --- a/src/plugins/resize/resize.js +++ b/src/plugins/resize/resize.js @@ -18,25 +18,12 @@ ( function( document, window ) { "use strict"; - // Throttling function calls, by Remy Sharp - // http://remysharp.com/2010/07/21/throttling-function-calls/ - var throttle = function( fn, delay ) { - var timer = null; - return function() { - var context = this, args = arguments; - window.clearTimeout( timer ); - timer = window.setTimeout( function() { - fn.apply( context, args ); - }, delay ); - }; - }; - // Wait for impress.js to be initialized document.addEventListener( "impress:init", function( event ) { var api = event.detail.api; // Rescale presentation when window is resized - api.lib.gc.addEventListener( window, "resize", throttle( function() { + api.lib.gc.addEventListener( window, "resize", api.lib.util.throttle( function() { // Force going to active step again, to trigger rescaling api.goto( document.querySelector( ".step.active" ), 500 );