add support for menu plugin
diff --git a/inst/reveal.js-3.3.0/plugin/menu/menu.js b/inst/reveal.js-3.3.0/plugin/menu/menu.js
new file mode 100755
index 0000000..65f05ee
--- /dev/null
+++ b/inst/reveal.js-3.3.0/plugin/menu/menu.js
@@ -0,0 +1,715 @@
+/*
+ * Reveal.js menu plugin
+ * MIT licensed
+ * (c) Greg Denehy 2015
+ */
+
+var RevealMenu = window.RevealMenu || (function(){
+ var config = Reveal.getConfig();
+ var options = config.menu || {};
+ options.path = options.path || scriptPath() || 'plugin/menu';
+
+ var module = {};
+
+ loadResource(options.path + '/lib/jeesh.min.js', 'script', function() {
+ loadResource(options.path + '/lib/bowser.min.js', 'script', function() {
+ loadResource(options.path + '/menu.css', 'stylesheet', function() {
+ // does not support IE8 or below
+ if (!bowser.msie || bowser.version >= 9) {
+ //
+ // Set option defaults
+ //
+ var side = options.side || 'left'; // 'left' or 'right'
+ var numbers = options.numbers || false;
+ var titleSelector = 'h1, h2, h3, h4, h5';
+ if (typeof options.titleSelector === 'string') titleSelector = options.titleSelector;
+ var hideMissingTitles = options.hideMissingTitles || false;
+ var markers = options.markers || false;
+ var custom = options.custom;
+ var themes = options.themes;
+ if (typeof themes === "undefined") {
+ themes = [
+ { name: 'Black', theme: 'css/theme/black.css' },
+ { name: 'White', theme: 'css/theme/white.css' },
+ { name: 'League', theme: 'css/theme/league.css' },
+ { name: 'Sky', theme: 'css/theme/sky.css' },
+ { name: 'Beige', theme: 'css/theme/beige.css' },
+ { name: 'Simple', theme: 'css/theme/simple.css' },
+ { name: 'Serif', theme: 'css/theme/serif.css' },
+ { name: 'Blood', theme: 'css/theme/blood.css' },
+ { name: 'Night', theme: 'css/theme/night.css' },
+ { name: 'Moon', theme: 'css/theme/moon.css' },
+ { name: 'Solarized', theme: 'css/theme/solarized.css' }
+ ];
+ }
+ var transitions = options.transitions;
+ if (typeof transitions === "undefined") transitions = true;
+ if (bowser.msie && bowser.version <= 9) {
+ // transitions aren't support in IE9 anyway, so no point in showing them
+ transitions = false;
+ }
+ var openButton = options.openButton;
+ if (typeof openButton === "undefined") openButton = true;
+ var openSlideNumber = options.openSlideNumber;
+ if (typeof openSlideNumber === "undefined") openSlideNumber = false;
+ var keyboard = options.keyboard;
+ if (typeof keyboard === "undefined") keyboard = true;
+
+ function disableMouseSelection() {
+ mouseSelectionEnabled = false;
+ }
+
+ function reenableMouseSelection() {
+ // wait until the mouse has moved before re-enabling mouse selection
+ // to avoid selections on scroll
+ $('nav.slide-menu').one('mousemove', function(event) {
+ //XXX this should select the item under the mouse
+ mouseSelectionEnabled = true;
+ });
+ }
+
+ //
+ // Keyboard handling
+ //
+ function getOffset(el) {
+ var _x = 0;
+ var _y = 0;
+ while(el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
+ _x += el.offsetLeft - el.scrollLeft;
+ _y += el.offsetTop - el.scrollTop;
+ el = el.offsetParent;
+ }
+ return { top: _y, left: _x };
+ }
+
+ function visibleOffset(el) {
+ var offsetFromTop = getOffset(el).top - el.offsetParent.offsetTop;
+ if (offsetFromTop < 0) return -offsetFromTop
+ var offsetFromBottom = el.offsetParent.offsetHeight - (el.offsetTop - el.offsetParent.scrollTop + el.offsetHeight);
+ if (offsetFromBottom < 0) return offsetFromBottom;
+ return 0;
+ }
+
+ function keepVisible(el) {
+ var offset = visibleOffset(el);
+ if (offset) {
+ disableMouseSelection();
+ el.scrollIntoView(offset > 0);
+ reenableMouseSelection();
+ }
+ }
+
+ function scrollItemToTop(el) {
+ disableMouseSelection();
+ el.offsetParent.scrollTop = el.offsetTop;
+ reenableMouseSelection();
+ }
+
+ function scrollItemToBottom(el) {
+ disableMouseSelection();
+ el.offsetParent.scrollTop = el.offsetTop - el.offsetParent.offsetHeight + el.offsetHeight
+ reenableMouseSelection();
+ }
+
+ function selectItem(el) {
+ $(el).addClass('selected');
+ keepVisible(el);
+ }
+
+ function onDocumentKeyDown(event) {
+ if (event.keyCode === 77) {
+ toggleMenu();
+ } else if (isOpen()) {
+ event.stopImmediatePropagation();
+ switch( event.keyCode ) {
+ // h, left - change panel
+ case 72: case 37:
+ prevPanel();
+ break;
+ // l, right - change panel
+ case 76: case 39:
+ nextPanel();
+ break;
+ // k, up
+ case 75: case 38:
+ var currItem = $('.active-menu-panel .slide-menu-items li.selected').get(0) || $('.active-menu-panel .slide-menu-items li.active').get(0);
+ if (currItem) {
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ var nextItem = $('.active-menu-panel .slide-menu-items li[data-item="' + ($(currItem).data('item') - 1) + '"]').get(0) || currItem;
+ selectItem(nextItem);
+ } else {
+ var items = $('.active-menu-panel .slide-menu-items li.slide-menu-item');
+ if (items.length > 0) {
+ selectItem(items.get(0));
+ }
+ }
+ break;
+ // j, down
+ case 74: case 40:
+ var currItem = $('.active-menu-panel .slide-menu-items li.selected').get(0) || $('.active-menu-panel .slide-menu-items li.active').get(0);
+ if (currItem) {
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ var nextItem = $('.active-menu-panel .slide-menu-items li[data-item="' + ($(currItem).data('item') + 1) + '"]').get(0) || currItem;
+ selectItem(nextItem);
+ } else {
+ var items = $('.active-menu-panel .slide-menu-items li.slide-menu-item');
+ if (items.length > 0) {
+ selectItem(items.get(0));
+ }
+ }
+ break;
+ // pageup, u
+ case 33: case 85:
+ var itemsAbove = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) > 0; });
+ var visibleItems = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
+
+ var firstVisible = (itemsAbove.length > 0 && Math.abs(visibleOffset(itemsAbove[itemsAbove.length-1])) < itemsAbove[itemsAbove.length-1].clientHeight ? itemsAbove[itemsAbove.length-1] : visibleItems[0]);
+ if (firstVisible) {
+ if ($(firstVisible).hasClass('selected') && itemsAbove.length > 0) {
+ // at top of viewport already, page scroll (if not at start)
+ // ...move selected item to bottom, and change selection to last fully visible item at top
+ scrollItemToBottom(firstVisible);
+ visibleItems = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
+ if (visibleItems[0] == firstVisible) {
+ // prev item is still beyond the viewport (for custom panels)
+ firstVisible = itemsAbove[itemsAbove.length-1];
+ } else {
+ firstVisible = visibleItems[0];
+ }
+ }
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ selectItem(firstVisible);
+ // ensure selected item is positioned at the top of the viewport
+ scrollItemToTop(firstVisible);
+ }
+ break;
+ // pagedown, d
+ case 34: case 68:
+ var visibleItems = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
+ var itemsBelow = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) < 0; });
+
+ var lastVisible = (itemsBelow.length > 0 && Math.abs(visibleOffset(itemsBelow[0])) < itemsBelow[0].clientHeight ? itemsBelow[0] : visibleItems[visibleItems.length-1]);
+ if (lastVisible) {
+ if ($(lastVisible).hasClass('selected') && itemsBelow.length > 0) {
+ // at bottom of viewport already, page scroll (if not at end)
+ // ...move selected item to top, and change selection to last fully visible item at bottom
+ scrollItemToTop(lastVisible);
+ visibleItems = $('.active-menu-panel .slide-menu-items li').filter(function(item) { return visibleOffset(item) == 0; });
+ if (visibleItems[visibleItems.length-1] == lastVisible) {
+ // next item is still beyond the viewport (for custom panels)
+ lastVisible = itemsBelow[0];
+ } else {
+ lastVisible = visibleItems[visibleItems.length-1];
+ }
+ }
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ selectItem(lastVisible);
+ // ensure selected item is positioned at the bottom of the viewport
+ scrollItemToBottom(lastVisible);
+ }
+ break;
+ // home
+ case 36:
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ var sel = $('.active-menu-panel .slide-menu-items li:first-of-type');
+ if (sel.length > 0) {
+ keepVisible(sel.addClass('selected').get(0));
+ }
+ break;
+ // end
+ case 35:
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ var sel = $('.active-menu-panel .slide-menu-items li:last-of-type');
+ if (sel.length > 0) {
+ keepVisible(sel.addClass('selected').get(0));
+ }
+ break;
+ // space, return
+ case 32: case 13:
+ var currItem = $('.active-menu-panel .slide-menu-items li.selected').get(0);
+ if (currItem) {
+ openItem(currItem);
+ }
+ break;
+ // esc
+ case 27: closeMenu(); break;
+ }
+ }
+ }
+
+ if (keyboard) {
+ //XXX add keyboard option for custom key codes, etc.
+
+ document.addEventListener('keydown', onDocumentKeyDown, false);
+
+ // handle key presses within speaker notes
+ window.addEventListener( 'message', function( event ) {
+ var data = JSON.parse( event.data );
+ if (data.method === 'triggerKey') {
+ onDocumentKeyDown( { keyCode: data.args[0], stopImmediatePropagation: function() {} } );
+ }
+ });
+
+ // Prevent reveal from processing keyboard events when the menu is open
+ if (config.keyboardCondition && typeof config.keyboardCondition === 'function') {
+ // combine user defined keyboard condition with the menu's own condition
+ var userCondition = config.keyboardCondition;
+ config.keyboardCondition = function() {
+ return userCondition() && !isOpen();
+ };
+ } else {
+ config.keyboardCondition = function() { return !isOpen(); }
+ }
+ }
+
+
+ //
+ // Utilty functions
+ //
+
+ function openMenu(event) {
+ if (event) event.preventDefault();
+ if (!isOpen()) {
+ $('body').addClass('slide-menu-active');
+ $('.reveal').addClass('has-' + options.effect + '-' + side);
+ $('.slide-menu').addClass('active');
+ $('.slide-menu-overlay').addClass('active');
+
+ // identify active theme
+ $('div[data-panel="Themes"] li').removeClass('active');
+ $('li[data-theme="' + $('#theme').attr('href') + '"]').addClass('active');
+
+ // identify active transition
+ $('div[data-panel="Transitions"] li').removeClass('active');
+ $('li[data-transition="' + Reveal.getConfig().transition + '"]').addClass('active');
+
+ // set item selections to match active items
+ $('.slide-menu-panel li.active')
+ .addClass('selected')
+ .each(function(item) { keepVisible(item) });
+ }
+ }
+
+ function closeMenu(event) {
+ if (event) event.preventDefault();
+ $('body').removeClass('slide-menu-active');
+ $('.reveal').removeClass('has-' + options.effect + '-' + side);
+ $('.slide-menu').removeClass('active');
+ $('.slide-menu-overlay').removeClass('active');
+ $('.slide-menu-panel li.selected').removeClass('selected');
+ }
+
+ function toggleMenu(event) {
+ if (isOpen()) {
+ closeMenu(event);
+ } else {
+ openMenu(event);
+ }
+ }
+
+ function isOpen() {
+ return $('body').hasClass('slide-menu-active');
+ }
+
+ function openPanel(e) {
+ openMenu();
+ var panel = e;
+ if (typeof e !== "string") {
+ panel = $(e.currentTarget).data('panel');
+ }
+ $('.slide-menu-toolbar > li').removeClass('active-toolbar-button');
+ $('li[data-panel="' + panel + '"]').addClass('active-toolbar-button');
+ $('.slide-menu-panel').removeClass('active-menu-panel');
+ $('div[data-panel="' + panel + '"]').addClass('active-menu-panel');
+ }
+
+ function nextPanel() {
+ var next = ($('.active-toolbar-button').data('button') + 1) % buttons;
+ openPanel($('.toolbar-panel-button[data-button="' + next + '"]').data('panel'));
+ }
+
+ function prevPanel() {
+ var next = $('.active-toolbar-button').data('button') - 1;
+ if (next < 0) {
+ next = buttons - 1;
+ }
+ openPanel($('.toolbar-panel-button[data-button="' + next + '"]').data('panel'));
+ }
+
+ $('<nav class="slide-menu slide-menu--' + side + '"></nav>')
+ .appendTo($('.reveal'));
+ $('<div class="slide-menu-overlay"></div>')
+ .appendTo($('.reveal'))
+ .click(closeMenu);
+
+ var toolbar = $('<ol class="slide-menu-toolbar"></ol>').prependTo($('.slide-menu'));
+ var buttons = 0;
+ $('<li data-panel="Slides" data-button="' + (buttons++) + '" class="toolbar-panel-button"><span class="slide-menu-toolbar-label">Slides</span><br/><i class="fa fa-list"></i></li>')
+ .appendTo(toolbar)
+ .addClass('active-toolbar-button')
+ .click(openPanel);
+
+ if (custom) {
+ custom.forEach(function(element, index, array) {
+ $('<li data-panel="Custom' + index + '" data-button="' + (buttons++) + '" class="toolbar-panel-button"><span class="slide-menu-toolbar-label">' + element.title + '</span><br/>' + element.icon + '</i></li>')
+ .appendTo(toolbar)
+ .click(openPanel);
+ })
+ }
+
+ if (themes) {
+ $('<li data-panel="Themes" data-button="' + (buttons++) + '" class="toolbar-panel-button"><span class="slide-menu-toolbar-label">Themes</span><br/><i class="fa fa-desktop"></i></li>')
+ .appendTo(toolbar)
+ .click(openPanel);
+ }
+ if (transitions) {
+ $('<li data-panel="Transitions" data-button="' + (buttons++) + '" class="toolbar-panel-button"><span class="slide-menu-toolbar-label">Transitions</span><br/><i class="fa fa-arrows-h"></i></li>')
+ .appendTo(toolbar)
+ .click(openPanel);
+ }
+ $('<li id="close"><span class="slide-menu-toolbar-label">Close</span><br/><i class="fa fa-times"></i></li>')
+ .appendTo(toolbar)
+ .click(closeMenu);
+
+ var panels = $('.slide-menu');
+
+ //
+ // Slide links
+ //
+ function generateItem(type, section, i, h, v) {
+ var link = '/#/' + h;
+ if (typeof v === 'number' && !isNaN( v )) link += '/' + v;
+
+ var title = $(section).data('menu-title') ||
+ $('.menu-title', section).text() ||
+ $(titleSelector, section).text();
+ if (!title) {
+ if (hideMissingTitles) return '';
+ title = "Slide " + i;
+ type += ' no-title';
+ }
+
+ title = '<span class="slide-menu-item-title">' + title + '</span>';
+ if (numbers) {
+ // Number formatting taken from reveal.js
+ var value = [];
+ var format = 'h.v';
+
+ // Check if a custom number format is available
+ if( typeof numbers === 'string' ) {
+ format = numbers;
+ }
+ else if (typeof config.slideNumber === 'string') {
+ // Take user defined number format for slides
+ format = config.slideNumber;
+ }
+
+ switch( format ) {
+ case 'c':
+ value.push( i );
+ break;
+ case 'c/t':
+ value.push( i, '/', Reveal.getTotalSlides() );
+ break;
+ case 'h/v':
+ value.push( h + 1 );
+ if( typeof v === 'number' && !isNaN( v ) ) value.push( '/', v + 1 );
+ break;
+ default:
+ value.push( h + 1 );
+ if( typeof v === 'number' && !isNaN( v ) ) value.push( '.', v + 1 );
+ }
+
+ title = '<span class="slide-menu-item-number">' + value.join('') + '. </span>' + title;
+ }
+
+ var m = '';
+ if (markers) {
+ m = '<i class="fa fa-check-circle past"></i>' +
+ '<i class="fa fa-dot-circle-o active"></i>' +
+ '<i class="fa fa-circle-thin future"></i>';
+ }
+
+ return '<li class="' + type + '" data-item="' + i + '" data-slide-h="' + h + '" data-slide-v="' + (v === undefined ? 0 : v) + '">' + m + title + '</li>';
+ }
+
+ function openItem(item) {
+ var h = $(item).data('slide-h');
+ var v = $(item).data('slide-v');
+ var theme = $(item).data('theme');
+ var transition = $(item).data('transition');
+ if (typeof h !== "undefined" && typeof v !== "undefined") {
+ Reveal.slide(h, v);
+ closeMenu();
+ } else if (theme) {
+ $('#theme').attr('href', theme);
+ closeMenu();
+ } else if (transition) {
+ Reveal.configure({ transition: transition });
+ closeMenu();
+ } else {
+ var links = $(item).find('a');
+ if (links.length > 0) {
+ links.get(0).click();
+ }
+ closeMenu();
+ }
+ }
+
+ function clicked(event) {
+ if (event.target.nodeName !== "A") {
+ event.preventDefault();
+ }
+ openItem(event.currentTarget);
+ }
+
+ function highlightCurrentSlide() {
+ var state = Reveal.getState();
+ $('li.slide-menu-item, li.slide-menu-item-vertical')
+ .removeClass('past')
+ .removeClass('active')
+ .removeClass('future');
+
+ $('li.slide-menu-item, li.slide-menu-item-vertical').each(function(e) {
+ var h = $(e).data('slide-h');
+ var v = $(e).data('slide-v');
+ if (h < state.indexh || (h === state.indexh && v < state.indexv)) {
+ $(e).addClass('past');
+ }
+ else if (h === state.indexh && v === state.indexv) {
+ $(e).addClass('active');
+ }
+ else {
+ $(e).addClass('future');
+ }
+ });
+ }
+
+ function createSlideMenu() {
+ if ( !document.querySelector('section[data-markdown]:not([data-markdown-parsed])') ) {
+ $('<div data-panel="Slides" class="slide-menu-panel"><ul class="slide-menu-items"></ul></div>')
+ .appendTo(panels)
+ .addClass('active-menu-panel');
+ var items = $('.slide-menu-panel[data-panel="Slides"] > .slide-menu-items');
+ var slideCount = 0;
+ $('.slides > section').each(function(section, h) {
+ var subsections = $('section', section);
+ if (subsections.length > 0) {
+ subsections.each(function(subsection, v) {
+ var type = (v === 0 ? 'slide-menu-item' : 'slide-menu-item-vertical');
+ var item = generateItem(type, subsection, slideCount, h, v);
+ if (item) {
+ slideCount++;
+ items.append(item);
+ }
+ });
+ } else {
+ var item = generateItem('slide-menu-item', section, slideCount, h);
+ if (item) {
+ slideCount++;
+ items.append(item);
+ }
+ }
+ });
+ $('.slide-menu-item, .slide-menu-item-vertical').click(clicked);
+ highlightCurrentSlide();
+ }
+ else {
+ // wait for markdown to be loaded and parsed
+ setTimeout( createSlideMenu, 100 );
+ }
+ }
+
+ createSlideMenu();
+ Reveal.addEventListener('slidechanged', highlightCurrentSlide);
+
+ //
+ // Custom menu panels
+ //
+ if (custom) {
+ function xhrSuccess () {
+ if (this.status >= 200 && this.status < 300) {
+ $(this.responseText).appendTo(this.panel);
+ enableCustomLinks(this.panel);
+ }
+ else {
+ showErrorMsg(this)
+ }
+ }
+ function xhrError () {
+ showErrorMsg(this)
+ }
+ function loadCustomPanelContent (panel, sURL) {
+ var oReq = new XMLHttpRequest();
+ oReq.panel = panel;
+ oReq.arguments = Array.prototype.slice.call(arguments, 2);
+ oReq.onload = xhrSuccess;
+ oReq.onerror = xhrError;
+ oReq.open("get", sURL, true);
+ oReq.send(null);
+ }
+ function enableCustomLinks(panel) {
+ $(panel).find('ul.slide-menu-items li.slide-menu-item').each(function(item, i) {
+ $(item).attr('data-item', i+1);
+ $(item).click(clicked);
+ });
+ }
+ function showErrorMsg(response) {
+ var msg = '<p>ERROR: The attempt to fetch ' + response.responseURL + ' failed with HTTP status ' +
+ response.status + ' (' + response.statusText + ').</p>' +
+ '<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>';
+ $(msg).appendTo(response.panel)
+ }
+
+ custom.forEach(function(element, index, array) {
+ var panel = $('<div data-panel="Custom' + index + '" class="slide-menu-panel slide-menu-custom-panel"></div>');
+ if (element.content) {
+ $(element.content).appendTo(panel);
+ enableCustomLinks(panel);
+ }
+ else if (element.src) {
+ loadCustomPanelContent(panel, element.src);
+ }
+ panel.appendTo(panels);
+ })
+ }
+
+ //
+ // Themes
+ //
+ if (themes) {
+ var panel = $('<div data-panel="Themes" class="slide-menu-panel"></div>').appendTo(panels);
+ var menu = $('<ul class="slide-menu-items"></ul>').appendTo(panel);
+ themes.forEach(function(t, i) {
+ $('<li class="slide-menu-item" data-theme="' + t.theme + '" data-item="' + (i+1) + '">' + t.name + '</li>').appendTo(menu).click(clicked);
+ })
+ }
+
+ //
+ // Transitions
+ //
+ if (transitions) {
+ var panel = $('<div data-panel="Transitions" class="slide-menu-panel"></div>').appendTo(panels);
+ var menu = $('<ul class="slide-menu-items"></ul>').appendTo(panel);
+ ['None', 'Fade', 'Slide', 'Convex', 'Concave', 'Zoom', 'Cube', 'Page'].forEach(function(name, i) {
+ $('<li class="slide-menu-item" data-transition="' + name.toLowerCase() + '" data-item="' + (i+1) + '">' + name + '</li>').appendTo(menu).click(clicked);
+ })
+ }
+
+ //
+ // Open menu options
+ //
+ if (openButton) {
+ // add menu button
+ $('<div class="slide-menu-button"><a href="#"><i class="fa fa-bars"></i></a></div>')
+ .appendTo($('.reveal'))
+ .click(openMenu);
+ }
+
+ if (openSlideNumber) {
+ // wrap slide number in link
+ $('<div class="slide-number-wrapper"><a href="#"></a></div>').insertAfter($('div.slide-number'));
+ $('.slide-number').appendTo($('.slide-number-wrapper a'));
+ $('.slide-number-wrapper a').click(openMenu);
+ }
+
+ //
+ // Handle mouse overs
+ //
+ var mouseSelectionEnabled = true;
+ $('.slide-menu-panel .slide-menu-items li').mouseenter(function(event) {
+ if (mouseSelectionEnabled) {
+ $('.active-menu-panel .slide-menu-items li').removeClass('selected');
+ $(event.currentTarget).addClass('selected');
+ }
+ });
+
+ module.toggle = toggleMenu;
+ module.isOpen = isOpen;
+
+ /**
+ * Extend object a with the properties of object b.
+ * If there's a conflict, object b takes precedence.
+ */
+ function extend( a, b ) {
+ for( var i in b ) {
+ a[ i ] = b[ i ];
+ }
+ }
+
+ /**
+ * Dispatches an event of the specified type from the
+ * reveal DOM element.
+ */
+ function dispatchEvent( type, args ) {
+ var event = document.createEvent( 'HTMLEvents', 1, 2 );
+ event.initEvent( type, true, true );
+ extend( event, args );
+ document.querySelector('.reveal').dispatchEvent( event );
+
+ // If we're in an iframe, post each reveal.js event to the
+ // parent window. Used by the notes plugin
+ if( config.postMessageEvents && window.parent !== window.self ) {
+ window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: getState() }), '*' );
+ }
+ }
+
+ dispatchEvent('menu-ready');
+ }
+ })
+ })
+ });
+
+ // modified from math plugin
+ function loadResource( url, type, callback ) {
+ var head = document.querySelector( 'head' );
+ var resource;
+
+ if ( type === 'script' ) {
+ resource = document.createElement( 'script' );
+ resource.type = 'text/javascript';
+ resource.src = url;
+ }
+ else if ( type === 'stylesheet' ) {
+ resource = document.createElement( 'link' );
+ resource.rel = 'stylesheet';
+ resource.href = url;
+ }
+
+ // Wrapper for callback to make sure it only fires once
+ var finish = function() {
+ if( typeof callback === 'function' ) {
+ callback.call();
+ callback = null;
+ }
+ }
+
+ resource.onload = finish;
+
+ // IE
+ resource.onreadystatechange = function() {
+ if ( this.readyState === 'loaded' ) {
+ finish();
+ }
+ }
+
+ // Normal browsers
+ head.appendChild( resource );
+ }
+
+ function scriptPath() {
+ // obtain plugin path from the script element
+ var path;
+ if (document.currentScript) {
+ path = document.currentScript.src.slice(0, -7);
+ } else {
+ var sel = document.querySelector('script[src$="/menu.js"]')
+ if (sel) {
+ path = sel.src.slice(0, -7);
+ }
+ }
+ return path;
+ }
+
+ return module;
+})();