0){let a=.9;t+=b.querySelectorAll(".fragment.visible").length/e.length*a}}return Math.min(t/(e-1),1)}function ct(){return!!window.location.search.match(/receiver/gi)}function ut(){let e=window.location.hash,t=e.slice(2).split("/"),r=e.replace(/#|\//gi,"");if(!/^[0-9]*$/.test(t[0])&&r.length){let e;try{e=document.getElementById(decodeURIComponent(r))}catch(e){}let t=!!b&&b.getAttribute("id")===r;if(e){if(!t){let t=a.getIndices(e);Re(t.h,t.v)}}else Re(m||0,v||0)}else{let e,a=f.hashOneBasedIndex?1:0,r=parseInt(t[0],10)-a||0,n=parseInt(t[1],10)-a||0;f.fragmentInURL&&(e=parseInt(t[2],10),isNaN(e)&&(e=void 0)),r===m&&n===v&&void 0===e||Re(r,n,e)}}function pt(e){clearTimeout(B),"number"==typeof e?B=setTimeout(pt,e):b&&(f.history||!window.history?window.location.hash=Le():f.hash?window.history.replaceState(null,null,"#"+Le()):window.history.replaceState(null,null,window.location.pathname+window.location.search))}function ht(e){let t,a=m,r=v;if(e){let t=xe(e),n=t?e.parentNode:e,i=d(R.wrapper.querySelectorAll(".slides>section"));a=Math.max(i.indexOf(n),0),r=void 0,t&&(r=Math.max(d(e.parentNode.querySelectorAll("section")).indexOf(e),0))}if(!e&&b){if(b.querySelectorAll(".fragment").length>0){let e=b.querySelector(".current-fragment");t=e&&e.hasAttribute("data-fragment-index")?parseInt(e.getAttribute("data-fragment-index"),10):b.querySelectorAll(".fragment.visible").length-1}}return{h:a,v:r,f:t}}function gt(){return d(R.wrapper.querySelectorAll('.slides section:not(.stack):not([data-visibility="uncounted"])'))}function ft(){return d(R.wrapper.querySelectorAll(".slides>section"))}function mt(){return d(R.wrapper.querySelectorAll(".slides>section>section"))}function vt(){return ft().length>1}function yt(){return mt().length>1}function bt(){return gt().length}function wt(e,t){let a=ft()[e],r=a&&a.querySelectorAll("section");return r&&r.length&&"number"==typeof t?r?r[t]:void 0:a}function At(e,t){let a="number"==typeof e?wt(e,t):e;if(a)return a.slideBackgroundElement}function kt(e=b){if(e.hasAttribute("data-notes"))return e.getAttribute("data-notes");let t=e.querySelector("aside.notes");return t?t.innerHTML:null}function Et(){let e=ht();return{indexh:e.h,indexv:e.v,indexf:e.f,paused:Te(),overview:Se()}}function St(e,t=!1){e=d(e);let a=[],r=[],n=[];e.forEach(e=>{if(e.hasAttribute("data-fragment-index")){let t=parseInt(e.getAttribute("data-fragment-index"),10);a[t]||(a[t]=[]),a[t].push(e)}else r.push([e])}),a=a.concat(r);let i=0;return a.forEach(e=>{e.forEach(e=>{n.push(e),e.setAttribute("data-fragment-index",i)}),i++}),!0===t?a:n}function Lt(e,t){let a={shown:[],hidden:[]};if(b&&f.fragments&&(t=t||St(b.querySelectorAll(".fragment"))).length){let r=0;if("number"!=typeof e){let t=St(b.querySelectorAll(".fragment.visible")).pop();t&&(e=parseInt(t.getAttribute("data-fragment-index")||0,10))}d(t).forEach((t,n)=>{t.hasAttribute("data-fragment-index")&&(n=parseInt(t.getAttribute("data-fragment-index"),10)),r=Math.max(r,n),n<=e?(t.classList.contains("visible")||a.shown.push(t),t.classList.add("visible"),t.classList.remove("current-fragment"),R.statusDiv.textContent=Q(t),n===e&&(t.classList.add("current-fragment"),nt(t))):(t.classList.contains("visible")&&a.hidden.push(t),t.classList.remove("visible"),t.classList.remove("current-fragment"))}),e="number"==typeof e?e:-1,e=Math.max(Math.min(e,r),-1),b.setAttribute("data-fragment",e)}return a}function xt(e,t=0){if(b&&f.fragments){let a=St(b.querySelectorAll(".fragment"));if(a.length){if("number"!=typeof e){let t=St(b.querySelectorAll(".fragment.visible")).pop();e=t?parseInt(t.getAttribute("data-fragment-index")||0,10):-1}let r=Lt(e+=t,a);return r.hidden.length&&se("fragmenthidden",{fragment:r.hidden[0],fragments:r.hidden}),r.shown.length&&se("fragmentshown",{fragment:r.shown[0],fragments:r.shown}),Ue(),$e(),f.fragmentInURL&&pt(),!(!r.shown.length&&!r.hidden.length)}}return!1}function Mt(){return xt(null,1)}function Nt(){return xt(null,-1)}function qt(){if(Pt(),b&&!1!==f.autoSlide){let e=b.querySelector(".current-fragment");e||(e=b.querySelector(".fragment"));let t=e?e.getAttribute("data-autoslide"):null,r=b.parentNode?b.parentNode.getAttribute("data-autoslide"):null,n=b.getAttribute("data-autoslide");F=t?parseInt(t,10):n?parseInt(n,10):r?parseInt(r,10):f.autoSlide,0===b.querySelectorAll(".fragment").length&&d(b.querySelectorAll("video, audio")).forEach(e=>{e.hasAttribute("data-autoplay")&&F&&1e3*e.duration/e.playbackRate>F&&(F=1e3*e.duration/e.playbackRate+1e3)}),!F||X||Te()||Se()||a.isLastSlide()&&!rt().next&&!0!==f.loop||(U=setTimeout(()=>{"function"==typeof f.autoSlideMethod?f.autoSlideMethod():Bt(),qt()},F),V=Date.now()),S&&S.setPlaying(-1!==U)}}function Pt(){clearTimeout(U),U=-1}function It(){F&&!X&&(X=!0,se("autoslidepaused"),clearTimeout(U),S&&S.setPlaying(!1))}function Tt(){F&&X&&(X=!1,se("autoslideresumed"),qt())}function Ct(){q=!0,f.rtl?(Se()||!1===Mt())&&at().left&&Re(m+1,"grid"===f.navigationMode?v:void 0):(Se()||!1===Nt())&&at().left&&Re(m-1,"grid"===f.navigationMode?v:void 0)}function Rt(){q=!0,f.rtl?(Se()||!1===Nt())&&at().right&&Re(m-1,"grid"===f.navigationMode?v:void 0):(Se()||!1===Mt())&&at().right&&Re(m+1,"grid"===f.navigationMode?v:void 0)}function Dt(){(Se()||!1===Nt())&&at().up&&Re(m,v-1)}function Ot(){P=!0,(Se()||!1===Mt())&&at().down&&Re(m,v+1)}function zt(){if(!1===Nt())if(at().up)Dt();else{let e;if(e=f.rtl?d(R.wrapper.querySelectorAll(".slides>section.future")).pop():d(R.wrapper.querySelectorAll(".slides>section.past")).pop(),e){let t=e.querySelectorAll("section").length-1||void 0;Re(m-1,t)}}}function Bt(){if(q=!0,P=!0,!1===Mt()){let e=at();e.down&&e.right&&f.loop&&a.isLastVerticalSlide(b)&&(e.down=!1),e.down?Ot():f.rtl?Ct():Rt()}}function Ht(e){for(;e&&"function"==typeof e.hasAttribute;){if(e.hasAttribute("data-prevent-swipe"))return!0;e=e.parentNode}return!1}function jt(e){f.autoSlideStoppable&&It()}function $t(e){Me(),clearTimeout(j),j=setTimeout(Ne,f.hideCursorTime)}function Wt(e){e.shiftKey&&63===e.charCode&&ue()}function Ft(e){if("function"==typeof f.keyboardCondition&&!1===f.keyboardCondition(e))return!0;let t=e.keyCode,r=X;jt();let n=document.activeElement&&"inherit"!==document.activeElement.contentEditable,i=document.activeElement&&document.activeElement.tagName&&/input|textarea/i.test(document.activeElement.tagName),o=document.activeElement&&document.activeElement.className&&/speaker-notes/i.test(document.activeElement.className),s=e.shiftKey&&32===e.keyCode,l=e.shiftKey&&37===t,d=e.shiftKey&&39===t,c=!s&&!l&&!d&&(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey);if(n||i||o||c)return;let u,p=[66,86,190,191];if("object"==typeof f.keyboard)for(u in f.keyboard)"togglePause"===f.keyboard[u]&&p.push(parseInt(u,10));if(Te()&&-1===p.indexOf(t))return!1;let h="linear"===f.navigationMode||!vt()||!yt(),g=!1;if("object"==typeof f.keyboard)for(u in f.keyboard)if(parseInt(u,10)===t){let t=f.keyboard[u];"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),g=!0}if(!1===g)for(u in _)if(parseInt(u,10)===t){let t=_[u].callback;"function"==typeof t?t.apply(null,[e]):"string"==typeof t&&"function"==typeof a[t]&&a[t].call(),g=!0}!1===g&&(g=!0,80===t||33===t?zt():78===t||34===t?Bt():72===t||37===t?l?Re(0):!Se()&&h?zt():Ct():76===t||39===t?d?Re(Number.MAX_VALUE):!Se()&&h?Bt():Rt():75===t||38===t?!Se()&&h?zt():Dt():74===t||40===t?!Se()&&h?Bt():Ot():36===t?Re(0):35===t?Re(Number.MAX_VALUE):32===t?(Se()&&ke(),e.shiftKey?zt():Bt()):58===t||59===t||66===t||86===t||190===t||191===t?Ie():70===t?(()=>{let e=document.documentElement,t=e.requestFullscreen||e.webkitRequestFullscreen||e.webkitRequestFullScreen||e.mozRequestFullScreen||e.msRequestFullscreen;t&&t.apply(e)})():65===t?f.autoSlideStoppable&&Ce(r):g=!1),g?e.preventDefault&&e.preventDefault():27!==t&&79!==t||(R.overlay?he():Ee(),e.preventDefault&&e.preventDefault()),qt()}function Ut(e){if(Ht(e.target))return!0;Y.startX=e.touches[0].clientX,Y.startY=e.touches[0].clientY,Y.startCount=e.touches.length}function Vt(e){if(Ht(e.target))return!0;if(Y.captured)r.match(/android/gi)&&e.preventDefault();else{jt();let t=e.touches[0].clientX,a=e.touches[0].clientY;if(1===e.touches.length&&2!==Y.startCount){let r=t-Y.startX,n=a-Y.startY;r>Y.threshold&&Math.abs(r)>Math.abs(n)?(Y.captured=!0,"linear"===f.navigationMode?f.rtl?Bt():zt():Ct()):r<-Y.threshold&&Math.abs(r)>Math.abs(n)?(Y.captured=!0,"linear"===f.navigationMode?f.rtl?zt():Bt():Rt()):n>Y.threshold?(Y.captured=!0,"linear"===f.navigationMode?zt():Dt()):n<-Y.threshold&&(Y.captured=!0,"linear"===f.navigationMode?Bt():Ot()),f.embedded?(Y.captured||xe(b))&&e.preventDefault():e.preventDefault()}}}function Xt(e){Y.captured=!1}function Yt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Ut(e))}function Kt(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Vt(e))}function _t(e){e.pointerType!==e.MSPOINTER_TYPE_TOUCH&&"touch"!==e.pointerType||(e.touches=[{clientX:e.clientX,clientY:e.clientY}],Xt())}function Jt(e){if(Date.now()-z>600){z=Date.now();let t=e.detail||-e.wheelDelta;t>0?Bt():t<0&&zt()}}function Qt(e){jt(),e.preventDefault();let t=ft().length,a=Math.floor(e.clientX/R.wrapper.offsetWidth*t);f.rtl&&(a=t-a),Re(a)}function Zt(e){e.preventDefault(),jt(),"linear"===f.navigationMode?zt():Ct()}function Gt(e){e.preventDefault(),jt(),"linear"===f.navigationMode?Bt():Rt()}function ea(e){e.preventDefault(),jt(),Dt()}function ta(e){e.preventDefault(),jt(),Ot()}function aa(e){e.preventDefault(),jt(),zt()}function ra(e){e.preventDefault(),jt(),Bt()}function na(e){ut()}function ia(e){ge()}function oa(e){!1===document.hidden&&document.activeElement!==document.body&&("function"==typeof document.activeElement.blur&&document.activeElement.blur(),document.body.focus())}function sa(e){if($&&Se()){e.preventDefault();let t=e.target;for(;t&&!t.nodeName.match(/section/gi);)t=t.parentNode;if(t&&!t.classList.contains("disabled")&&(ke(),t.nodeName.match(/section/gi))){Re(parseInt(t.getAttribute("data-index-h"),10),parseInt(t.getAttribute("data-index-v"),10))}}}function la(e){if(e.currentTarget&&e.currentTarget.hasAttribute("href")){let t=e.currentTarget.getAttribute("href");t&&(!function(e){he(),R.overlay=document.createElement("div"),R.overlay.classList.add("overlay"),R.overlay.classList.add("overlay-preview"),R.wrapper.appendChild(R.overlay),R.overlay.innerHTML=`\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options).\n\t\t\t\t\n\t\t\t
`,R.overlay.querySelector("iframe").addEventListener("load",e=>{R.overlay.classList.add("loaded")},!1),R.overlay.querySelector(".close").addEventListener("click",e=>{he(),e.preventDefault()},!1),R.overlay.querySelector(".external").addEventListener("click",e=>{he()},!1)}(t),e.preventDefault())}}function da(e){a.isLastSlide()&&!1===f.loop?(Re(0,0),Tt()):X?Tt():It()}return a={VERSION:"4.0.0-dev",initialize:function(){if(e)return function(){A=/(iphone|ipod|ipad|android)/gi.test(r)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,k=/chrome/i.test(r)&&!/edge/i.test(r);let e=document.createElement("div");O.zoom="zoom"in e.style&&!A&&(k||/Version\/[\d\.]+.*Safari/.test(r))}(),R.wrapper=e,R.slides=e.querySelector(".slides"),window.addEventListener("load",ge,!1),f={...o,...t,...a.getQueryHash()},D.load(f.dependencies).then(J),a;console.warn("reveal.js can not initialize without a valid .reveal element.")},configure:ae,sync:De,syncSlide:function(e=b){te(e),Oe(e),et(e),Ve(),je()},syncFragments:Oe,slide:Re,left:Ct,right:Rt,up:Dt,down:Ot,prev:zt,next:Bt,navigateTo:Re,navigateLeft:Ct,navigateRight:Rt,navigateUp:Dt,navigateDown:Ot,navigatePrev:zt,navigateNext:Bt,navigateFragment:xt,prevFragment:Nt,nextFragment:Mt,layout:ge,shuffle:ze,availableRoutes:at,availableFragments:rt,toggleHelp:ue,toggleOverview:Ee,togglePause:Ie,toggleAutoSlide:Ce,isOverview:Se,isPaused:Te,isAutoSliding:function(){return!(!F||X)},isSpeakerNotes:ct,loadSlide:et,unloadSlide:tt,addEventListeners:re,removeEventListeners:ne,getState:Et,setState:function(e){if("object"==typeof e){Re(c(e.indexh),c(e.indexv),c(e.indexf));let t=c(e.paused),a=c(e.overview);"boolean"==typeof t&&t!==Te()&&Ie(t),"boolean"==typeof a&&a!==Se()&&Ee(a)}},getSlidePastCount:lt,getProgress:dt,getIndices:ht,getSlides:gt,getSlidesAttributes:function(){return gt().map(e=>{let t={};for(let a=0;aD.registerPlugin(...e),hasPlugin:(...e)=>D.hasPlugin(...e),getPlugin:(...e)=>D.getPlugin(...e),getPlugins:()=>D.getRegisteredPlugins(),getComputedSlideSize:me,getPreviousSlide:()=>y,getCurrentSlide:()=>b,getScale:()=>T,getConfig:()=>f,getQueryHash:()=>{let e={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,t=>{e[t.split("=").shift()]=t.split("=").pop()});for(let t in e){let a=e[t];e[t]=c(unescape(a))}return void 0!==e.dependencies&&delete e.dependencies,e},getRevealElement:()=>R.wrapper||document.querySelector(".reveal"),isFirstSlide:()=>0===m&&0===v,isLastSlide:()=>!!b&&(!b.nextElementSibling&&(!xe(b)||!b.parentNode.nextElementSibling)),isLastVerticalSlide:()=>!(!b||!xe(b))&&!b.nextElementSibling,isReady:()=>L,addEventListener:(e,t,r)=>{a.getRevealElement().addEventListener(e,t,r)},removeEventListener:(e,t,r)=>{a.getRevealElement().removeEventListener(e,t,r)},triggerKey:e=>Ft({keyCode:e}),registerKeyboardShortcut:(e,t)=>K[e]=t},a};window.Reveal=f,window.Reveal.initialize=e=>(window.Reveal=new f(document.querySelector(".reveal"),e),window.Reveal.initialize(),new Promise(e=>window.Reveal.addEventListener("ready",e)))}]);
\ No newline at end of file
diff --git a/js/controllers/plugins.js b/js/controllers/plugins.js
index 9e52866..300b0ba 100644
--- a/js/controllers/plugins.js
+++ b/js/controllers/plugins.js
@@ -1,4 +1,4 @@
-import { loadScript } from './../utils/util.js'
+import { loadScript } from '../utils/loader.js'
/**
* Manages loading and registering of reveal.js plugins.
diff --git a/js/reveal.js b/js/reveal.js
index c4508c0..feb94fa 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -1,6 +1,12 @@
import Plugins from './controllers/plugins.js'
import Playback from './components/playback.js'
import defaultConfig from './config.js'
+import {
+ SLIDES_SELECTOR,
+ HORIZONTAL_SLIDES_SELECTOR,
+ VERTICAL_SLIDES_SELECTOR,
+ POST_MESSAGE_METHOD_BLACKLIST
+} from './utils/constants.js'
import {
extend,
toArray,
@@ -9,10 +15,9 @@ import {
transformElement,
injectStyleSheet,
closestParent,
- colorToRgb,
- colorBrightness,
enterFullscreen
} from './utils/util.js'
+import { colorToRgb, colorBrightness } from './utils/color.js'
/**
* reveal.js
@@ -28,16 +33,8 @@ export default function( revealElement, options ) {
// The reveal.js version
const VERSION = '4.0.0-dev';
- const SLIDES_SELECTOR = '.slides section';
- const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
- const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
- const HOME_SLIDE_SELECTOR = '.slides>section:first-of-type';
-
const UA = navigator.userAgent;
- // Methods that may not be invoked via the postMessage API
- const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
-
// Configuration defaults, can be overridden at initialization time
let config,
@@ -147,7 +144,7 @@ export default function( revealElement, options ) {
function initialize() {
if( !revealElement ) {
- console.warn( 'reveal.js must be instantiated with a valid .reveal element' );
+ console.warn( 'reveal.js can not initialize without a valid .reveal element.' );
return;
}
@@ -160,16 +157,10 @@ export default function( revealElement, options ) {
// Force a layout when the whole page, incl fonts, has loaded
window.addEventListener( 'load', layout, false );
- let query = Reveal.getQueryHash();
-
- // Do not accept new dependencies via query config to avoid
- // the potential of malicious script injection
- if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
-
// Copy options over to our config object
- config = { ...defaultConfig, ...options, ...query };
+ config = { ...defaultConfig, ...options, ...Reveal.getQueryHash() };
- // Load plugins and move on to #start() once done
+ // Load plugins then move on to #start()
plugins.load( config.dependencies ).then( start )
return Reveal;
@@ -5471,7 +5462,7 @@ export default function( revealElement, options ) {
Reveal = {
- VERSION: VERSION,
+ VERSION,
initialize,
configure,
@@ -5623,6 +5614,10 @@ export default function( revealElement, options ) {
query[ i ] = deserialize( unescape( value ) );
}
+ // Do not accept new dependencies via query config to avoid
+ // the potential of malicious script injection
+ if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
return query;
},
diff --git a/js/utils/color.js b/js/utils/color.js
new file mode 100644
index 0000000..1043f83
--- /dev/null
+++ b/js/utils/color.js
@@ -0,0 +1,77 @@
+/**
+ * Converts various color input formats to an {r:0,g:0,b:0} object.
+ *
+ * @param {string} color The string representation of a color
+ * @example
+ * colorToRgb('#000');
+ * @example
+ * colorToRgb('#000000');
+ * @example
+ * colorToRgb('rgb(0,0,0)');
+ * @example
+ * colorToRgb('rgba(0,0,0)');
+ *
+ * @return {{r: number, g: number, b: number, [a]: number}|null}
+ */
+export const colorToRgb = ( color ) => {
+
+ let hex3 = color.match( /^#([0-9a-f]{3})$/i );
+ if( hex3 && hex3[1] ) {
+ hex3 = hex3[1];
+ return {
+ r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,
+ g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,
+ b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11
+ };
+ }
+
+ let hex6 = color.match( /^#([0-9a-f]{6})$/i );
+ if( hex6 && hex6[1] ) {
+ hex6 = hex6[1];
+ return {
+ r: parseInt( hex6.substr( 0, 2 ), 16 ),
+ g: parseInt( hex6.substr( 2, 2 ), 16 ),
+ b: parseInt( hex6.substr( 4, 2 ), 16 )
+ };
+ }
+
+ let rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i );
+ if( rgb ) {
+ return {
+ r: parseInt( rgb[1], 10 ),
+ g: parseInt( rgb[2], 10 ),
+ b: parseInt( rgb[3], 10 )
+ };
+ }
+
+ let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
+ if( rgba ) {
+ return {
+ r: parseInt( rgba[1], 10 ),
+ g: parseInt( rgba[2], 10 ),
+ b: parseInt( rgba[3], 10 ),
+ a: parseFloat( rgba[4] )
+ };
+ }
+
+ return null;
+
+}
+
+/**
+ * Calculates brightness on a scale of 0-255.
+ *
+ * @param {string} color See colorToRgb for supported formats.
+ * @see {@link colorToRgb}
+ */
+export const colorBrightness = ( color ) => {
+
+ if( typeof color === 'string' ) color = colorToRgb( color );
+
+ if( color ) {
+ return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;
+ }
+
+ return null;
+
+}
\ No newline at end of file
diff --git a/js/utils/constants.js b/js/utils/constants.js
new file mode 100644
index 0000000..46faf27
--- /dev/null
+++ b/js/utils/constants.js
@@ -0,0 +1,7 @@
+
+export const SLIDES_SELECTOR = '.slides section';
+export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
+export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
+
+// Methods that may not be invoked via the postMessage API
+export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
\ No newline at end of file
diff --git a/js/utils/loader.js b/js/utils/loader.js
new file mode 100644
index 0000000..58d39ac
--- /dev/null
+++ b/js/utils/loader.js
@@ -0,0 +1,46 @@
+/**
+ * Loads a JavaScript file from the given URL and executes it.
+ *
+ * @param {string} url Address of the .js file to load
+ * @param {function} callback Method to invoke when the script
+ * has loaded and executed
+ */
+export const loadScript = ( url, callback ) => {
+
+ const script = document.createElement( 'script' );
+ script.type = 'text/javascript';
+ script.async = false;
+ script.defer = false;
+ script.src = url;
+
+ if( typeof callback === 'function' ) {
+
+ // Success callback
+ script.onload = script.onreadystatechange = event => {
+ if( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {
+
+ // Kill event listeners
+ script.onload = script.onreadystatechange = script.onerror = null;
+
+ callback();
+
+ }
+ };
+
+ // Error callback
+ script.onerror = err => {
+
+ // Kill event listeners
+ script.onload = script.onreadystatechange = script.onerror = null;
+
+ callback( new Error( 'Failed loading script: ' + script.src + '\n' + err ) );
+
+ };
+
+ }
+
+ // Append the script at the end of
+ const head = document.querySelector( 'head' );
+ head.insertBefore( script, head.lastChild );
+
+}
\ No newline at end of file
diff --git a/js/utils/util.js b/js/utils/util.js
index b96fe29..a7aae7b 100644
--- a/js/utils/util.js
+++ b/js/utils/util.js
@@ -112,84 +112,6 @@ export const closestParent = ( target, selector ) => {
}
-/**
- * Converts various color input formats to an {r:0,g:0,b:0} object.
- *
- * @param {string} color The string representation of a color
- * @example
- * colorToRgb('#000');
- * @example
- * colorToRgb('#000000');
- * @example
- * colorToRgb('rgb(0,0,0)');
- * @example
- * colorToRgb('rgba(0,0,0)');
- *
- * @return {{r: number, g: number, b: number, [a]: number}|null}
- */
-export const colorToRgb = ( color ) => {
-
- let hex3 = color.match( /^#([0-9a-f]{3})$/i );
- if( hex3 && hex3[1] ) {
- hex3 = hex3[1];
- return {
- r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,
- g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,
- b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11
- };
- }
-
- let hex6 = color.match( /^#([0-9a-f]{6})$/i );
- if( hex6 && hex6[1] ) {
- hex6 = hex6[1];
- return {
- r: parseInt( hex6.substr( 0, 2 ), 16 ),
- g: parseInt( hex6.substr( 2, 2 ), 16 ),
- b: parseInt( hex6.substr( 4, 2 ), 16 )
- };
- }
-
- let rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i );
- if( rgb ) {
- return {
- r: parseInt( rgb[1], 10 ),
- g: parseInt( rgb[2], 10 ),
- b: parseInt( rgb[3], 10 )
- };
- }
-
- let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
- if( rgba ) {
- return {
- r: parseInt( rgba[1], 10 ),
- g: parseInt( rgba[2], 10 ),
- b: parseInt( rgba[3], 10 ),
- a: parseFloat( rgba[4] )
- };
- }
-
- return null;
-
-}
-
-/**
- * Calculates brightness on a scale of 0-255.
- *
- * @param {string} color See colorToRgb for supported formats.
- * @see {@link colorToRgb}
- */
-export const colorBrightness = ( color ) => {
-
- if( typeof color === 'string' ) color = colorToRgb( color );
-
- if( color ) {
- return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;
- }
-
- return null;
-
-}
-
/**
* Handling the fullscreen functionality via the fullscreen API
*
@@ -230,51 +152,4 @@ export const injectStyleSheet = ( value ) => {
}
document.getElementsByTagName( 'head' )[0].appendChild( tag );
-}
-
-/**
- * Loads a JavaScript file from the given URL and executes it.
- *
- * @param {string} url Address of the .js file to load
- * @param {function} callback Method to invoke when the script
- * has loaded and executed
- */
-export const loadScript = ( url, callback ) => {
-
- const script = document.createElement( 'script' );
- script.type = 'text/javascript';
- script.async = false;
- script.defer = false;
- script.src = url;
-
- if( typeof callback === 'function' ) {
-
- // Success callback
- script.onload = script.onreadystatechange = event => {
- if( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {
-
- // Kill event listeners
- script.onload = script.onreadystatechange = script.onerror = null;
-
- callback();
-
- }
- };
-
- // Error callback
- script.onerror = err => {
-
- // Kill event listeners
- script.onload = script.onreadystatechange = script.onerror = null;
-
- callback( new Error( 'Failed loading script: ' + script.src + '\n' + err ) );
-
- };
-
- }
-
- // Append the script at the end of
- const head = document.querySelector( 'head' );
- head.insertBefore( script, head.lastChild );
-
}
\ No newline at end of file