Kaynağa Gözat

make plugins work with multiple presentations on same page

Hakim El Hattab 5 yıl önce
ebeveyn
işleme
b92d16f48d

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/plugin/highlight.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/plugin/markdown.js


+ 1 - 1
dist/plugin/math.js

@@ -1 +1 @@
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RevealMath=t()}(this,(function(){"use strict";var e=function(){var e=Reveal.getConfig().math||{},t=(e.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(e.config||"TeX-AMS_HTML-full"),n={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};function a(e,t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}return{id:"math",init:function(o){a(e,n),a(e.tex2jax,n.tex2jax),e.mathjax=e.config=null,function(e,t){var n=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===this.readyState&&o()},n.appendChild(a)}(t,(function(){MathJax.Hub.Config(e),MathJax.Hub.Queue(["Typeset",MathJax.Hub]),MathJax.Hub.Queue(o.layout),o.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}();return function(){return e}}));
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RevealMath=t()}(this,(function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(n){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?t(Object(a),!0).forEach((function(t){e(n,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach((function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(a,e))}))}return n}return function(){var e,t={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=n({},t,{},a),c=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=n({},t.tex2jax,{},a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(c,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}}));

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 1
dist/plugin/search.js


+ 34 - 2
examples/multiple-presentations.html

@@ -10,6 +10,7 @@
 
 		<link rel="stylesheet" href="../dist/reveal.css">
 		<link rel="stylesheet" href="../dist/theme/white.css" id="theme">
+		<link rel="stylesheet" href="../lib/css/monokai.css">
 	</head>
 
 	<body style="background: #ddd;">
@@ -19,6 +20,14 @@
 				<div class="slides">
 					<section>Deck 1, Slide 1</section>
 					<section>Deck 1, Slide 2</section>
+					<section>
+						<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
+							import React, { useState } from 'react';
+							function Example() {
+							  const [count, setCount] = useState(0);
+							}
+						</code></pre>
+					</section>
 				</div>
 			</div>
 
@@ -26,16 +35,38 @@
 				<div class="slides">
 					<section>Deck 2, Slide 1</section>
 					<section>Deck 2, Slide 2</section>
+					<section data-markdown>
+						<script type="text/template">
+							## Markdown plugin
+
+							- 1
+							- 2
+							- 3
+						</script>
+					</section>
+					<section>
+						<h3>The Lorenz Equations</h3>
+
+						\[\begin{aligned}
+						\dot{x} &amp; = \sigma(y-x) \\
+						\dot{y} &amp; = \rho x - y - xz \\
+						\dot{z} &amp; = -\beta z + xy
+						\end{aligned} \]
+					</section>
 				</div>
 			</div>
 		</div>
 
 		<script src="../dist/reveal.es5.js"></script>
+		<script src="../dist/plugin/highlight.js"></script>
+		<script src="../dist/plugin/markdown.js"></script>
+		<script src="../dist/plugin/math.js"></script>
 		<script>
 
 			let deck1 = new Reveal( document.querySelector( '.deck1' ), {
 				embedded: true,
-				keyboard: false
+				keyboard: false,
+				plugins: [ RevealHighlight ]
 			} );
 			deck1.on( 'slidechanged', () => {
 				console.log( 'Deck 1 slide changed' );
@@ -44,7 +75,8 @@
 
 			let deck2 = new Reveal( document.querySelector( '.deck2' ), {
 				embedded: true,
-				keyboard: false
+				keyboard: true,
+				plugins: [ RevealMarkdown, RevealMath ]
 			} );
 			deck2.initialize().then( () => {
 				deck2.slide(1);

+ 13 - 5
plugin/highlight/highlight.js

@@ -13,14 +13,22 @@ let Plugin = {
 	HIGHLIGHT_LINE_DELIMITER: ',',
 	HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
 
-	init: function( deck ) {
+	/**
+	 * Highlights code blocks withing the given deck.
+	 *
+	 * Note that this can be called multiple times if
+	 * there are multiple presentations on one page.
+	 *
+	 * @param {Reveal} reveal the reveal.js instance
+	 */
+	init: function( reveal ) {
 
 		// Read the plugin config options and provide fallbacks
-		var config = deck.getConfig().highlight || {};
+		var config = reveal.getConfig().highlight || {};
 		config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
 		config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
 
-		[].slice.call( document.querySelectorAll( '.reveal pre code' ) ).forEach( function( block ) {
+		[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( function( block ) {
 
 			// Trim whitespace if the "data-trim" attribute is present
 			if( block.hasAttribute( 'data-trim' ) && typeof block.innerHTML.trim === 'function' ) {
@@ -45,8 +53,8 @@ let Plugin = {
 
 		// If we're printing to PDF, scroll the code highlights of
 		// all blocks in the deck into view at once
-		deck.on( 'pdf-ready', function() {
-			[].slice.call( document.querySelectorAll( '.reveal pre code[data-line-numbers].current-fragment' ) ).forEach( function( block ) {
+		reveal.on( 'pdf-ready', function() {
+			[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code[data-line-numbers].current-fragment' ) ).forEach( function( block ) {
 				Plugin.scrollHighlightedLineIntoView( block, {}, true );
 			} );
 		} );

+ 327 - 321
plugin/markdown/markdown.js

@@ -6,429 +6,435 @@
 
 import marked from './marked.js'
 
-let Plugin = {
+const DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
+	  DEFAULT_NOTES_SEPARATOR = 'notes?:',
+	  DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
+	  DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
 
-	id: 'markdown',
+const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
+
+const Plugin = () => {
+
+	// The reveal.js instance this plugin is attached to
+	let deck;
 
 	/**
-	 * Starts processing and converting Markdown within the
-	 * current reveal.js deck.
+	 * Retrieves the markdown contents of a slide section
+	 * element. Normalizes leading tabs/whitespace.
 	 */
-	init: function( deck ) {
-
-		// This should no longer be needed, as long as the highlight.js
-		// plugin is included after the markdown plugin
-		// if( typeof window.hljs !== 'undefined' ) {
-		// 	marked.setOptions({
-		// 		highlight: function( code, lang ) {
-		// 			return window.hljs.highlightAuto( code, lang ? [lang] : null ).value;
-		// 		}
-		// 	});
-		// }
-
-		// marked can be configured via reveal.js config options
-		var options = deck.getConfig().markdown;
-		if( options ) {
-			marked.setOptions( options );
-		}
+	function getMarkdownFromSlide( section ) {
 
-		return processSlides( deck.getRevealElement() ).then( convertSlides );
+		// look for a <script> or <textarea data-template> wrapper
+		var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
 
-	},
+		// strip leading whitespace so it isn't evaluated as code
+		var text = ( template || section ).textContent;
 
-	// TODO: Do these belong in the API?
-	processSlides: processSlides,
-	convertSlides: convertSlides,
-	slidify: slidify,
-	marked: marked
+		// restore script end tags
+		text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
 
-};
+		var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
+			leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
 
-export default () => Plugin;
+		if( leadingTabs > 0 ) {
+			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+		}
+		else if( leadingWs > 1 ) {
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
+		}
 
-var DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
-	DEFAULT_NOTES_SEPARATOR = 'notes?:',
-	DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
-	DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
+		return text;
 
-var SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
+	}
 
+	/**
+	 * Given a markdown slide section element, this will
+	 * return all arguments that aren't related to markdown
+	 * parsing. Used to forward any other user-defined arguments
+	 * to the output markdown slide.
+	 */
+	function getForwardedAttributes( section ) {
 
-/**
- * Retrieves the markdown contents of a slide section
- * element. Normalizes leading tabs/whitespace.
- */
-function getMarkdownFromSlide( section ) {
+		var attributes = section.attributes;
+		var result = [];
 
-	// look for a <script> or <textarea data-template> wrapper
-	var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
+		for( var i = 0, len = attributes.length; i < len; i++ ) {
+			var name = attributes[i].name,
+				value = attributes[i].value;
 
-	// strip leading whitespace so it isn't evaluated as code
-	var text = ( template || section ).textContent;
+			// disregard attributes that are used for markdown loading/parsing
+			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
 
-	// restore script end tags
-	text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
+			if( value ) {
+				result.push( name + '="' + value + '"' );
+			}
+			else {
+				result.push( name );
+			}
+		}
 
-	var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
-		leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
+		return result.join( ' ' );
 
-	if( leadingTabs > 0 ) {
-		text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
-	}
-	else if( leadingWs > 1 ) {
-		text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
 	}
 
-	return text;
-
-}
-
-/**
- * Given a markdown slide section element, this will
- * return all arguments that aren't related to markdown
- * parsing. Used to forward any other user-defined arguments
- * to the output markdown slide.
- */
-function getForwardedAttributes( section ) {
-
-	var attributes = section.attributes;
-	var result = [];
+	/**
+	 * Inspects the given options and fills out default
+	 * values for what's not defined.
+	 */
+	function getSlidifyOptions( options ) {
 
-	for( var i = 0, len = attributes.length; i < len; i++ ) {
-		var name = attributes[i].name,
-			value = attributes[i].value;
+		options = options || {};
+		options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
+		options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
+		options.attributes = options.attributes || '';
 
-		// disregard attributes that are used for markdown loading/parsing
-		if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
+		return options;
 
-		if( value ) {
-			result.push( name + '="' + value + '"' );
-		}
-		else {
-			result.push( name );
-		}
 	}
 
-	return result.join( ' ' );
-
-}
-
-/**
- * Inspects the given options and fills out default
- * values for what's not defined.
- */
-function getSlidifyOptions( options ) {
-
-	options = options || {};
-	options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
-	options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
-	options.attributes = options.attributes || '';
+	/**
+	 * Helper function for constructing a markdown slide.
+	 */
+	function createMarkdownSlide( content, options ) {
 
-	return options;
+		options = getSlidifyOptions( options );
 
-}
+		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
 
-/**
- * Helper function for constructing a markdown slide.
- */
-function createMarkdownSlide( content, options ) {
+		if( notesMatch.length === 2 ) {
+			content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
+		}
 
-	options = getSlidifyOptions( options );
+		// prevent script end tags in the content from interfering
+		// with parsing
+		content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
 
-	var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
+		return '<script type="text/template">' + content + '</script>';
 
-	if( notesMatch.length === 2 ) {
-		content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
 	}
 
-	// prevent script end tags in the content from interfering
-	// with parsing
-	content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
+	/**
+	 * Parses a data string into multiple slides based
+	 * on the passed in separator arguments.
+	 */
+	function slidify( markdown, options ) {
 
-	return '<script type="text/template">' + content + '</script>';
+		options = getSlidifyOptions( options );
 
-}
+		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
+			horizontalSeparatorRegex = new RegExp( options.separator );
 
-/**
- * Parses a data string into multiple slides based
- * on the passed in separator arguments.
- */
-function slidify( markdown, options ) {
+		var matches,
+			lastIndex = 0,
+			isHorizontal,
+			wasHorizontal = true,
+			content,
+			sectionStack = [];
 
-	options = getSlidifyOptions( options );
+		// iterate until all blocks between separators are stacked up
+		while( matches = separatorRegex.exec( markdown ) ) {
+			var notes = null;
 
-	var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
-		horizontalSeparatorRegex = new RegExp( options.separator );
+			// determine direction (horizontal by default)
+			isHorizontal = horizontalSeparatorRegex.test( matches[0] );
 
-	var matches,
-		lastIndex = 0,
-		isHorizontal,
-		wasHorizontal = true,
-		content,
-		sectionStack = [];
+			if( !isHorizontal && wasHorizontal ) {
+				// create vertical stack
+				sectionStack.push( [] );
+			}
 
-	// iterate until all blocks between separators are stacked up
-	while( matches = separatorRegex.exec( markdown ) ) {
-		var notes = null;
+			// pluck slide content from markdown input
+			content = markdown.substring( lastIndex, matches.index );
 
-		// determine direction (horizontal by default)
-		isHorizontal = horizontalSeparatorRegex.test( matches[0] );
+			if( isHorizontal && wasHorizontal ) {
+				// add to horizontal stack
+				sectionStack.push( content );
+			}
+			else {
+				// add to vertical stack
+				sectionStack[sectionStack.length-1].push( content );
+			}
 
-		if( !isHorizontal && wasHorizontal ) {
-			// create vertical stack
-			sectionStack.push( [] );
+			lastIndex = separatorRegex.lastIndex;
+			wasHorizontal = isHorizontal;
 		}
 
-		// pluck slide content from markdown input
-		content = markdown.substring( lastIndex, matches.index );
+		// add the remaining slide
+		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
 
-		if( isHorizontal && wasHorizontal ) {
-			// add to horizontal stack
-			sectionStack.push( content );
-		}
-		else {
-			// add to vertical stack
-			sectionStack[sectionStack.length-1].push( content );
-		}
-
-		lastIndex = separatorRegex.lastIndex;
-		wasHorizontal = isHorizontal;
-	}
+		var markdownSections = '';
 
-	// add the remaining slide
-	( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
+		// flatten the hierarchical stack, and insert <section data-markdown> tags
+		for( var i = 0, len = sectionStack.length; i < len; i++ ) {
+			// vertical
+			if( sectionStack[i] instanceof Array ) {
+				markdownSections += '<section '+ options.attributes +'>';
 
-	var markdownSections = '';
+				sectionStack[i].forEach( function( child ) {
+					markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
+				} );
 
-	// flatten the hierarchical stack, and insert <section data-markdown> tags
-	for( var i = 0, len = sectionStack.length; i < len; i++ ) {
-		// vertical
-		if( sectionStack[i] instanceof Array ) {
-			markdownSections += '<section '+ options.attributes +'>';
+				markdownSections += '</section>';
+			}
+			else {
+				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
+			}
+		}
 
-			sectionStack[i].forEach( function( child ) {
-				markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
-			} );
+		return markdownSections;
 
-			markdownSections += '</section>';
-		}
-		else {
-			markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
-		}
 	}
 
-	return markdownSections;
+	/**
+	 * Parses any current data-markdown slides, splits
+	 * multi-slide markdown into separate sections and
+	 * handles loading of external markdown.
+	 */
+	function processSlides( scope ) {
 
-}
+		return new Promise( function( resolve ) {
 
-/**
- * Parses any current data-markdown slides, splits
- * multi-slide markdown into separate sections and
- * handles loading of external markdown.
- */
-function processSlides( scope ) {
+			var externalPromises = [];
 
-	return new Promise( function( resolve ) {
+			[].slice.call( scope.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
 
-		var externalPromises = [];
+				if( section.getAttribute( 'data-markdown' ).length ) {
 
-		[].slice.call( scope.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
+					externalPromises.push( loadExternalMarkdown( section ).then(
 
-			if( section.getAttribute( 'data-markdown' ).length ) {
+						// Finished loading external file
+						function( xhr, url ) {
+							section.outerHTML = slidify( xhr.responseText, {
+								separator: section.getAttribute( 'data-separator' ),
+								verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+								notesSeparator: section.getAttribute( 'data-separator-notes' ),
+								attributes: getForwardedAttributes( section )
+							});
+						},
 
-				externalPromises.push( loadExternalMarkdown( section ).then(
+						// Failed to load markdown
+						function( xhr, url ) {
+							section.outerHTML = '<section data-state="alert">' +
+								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
+								'Check your browser\'s JavaScript console for more details.' +
+								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
+								'</section>';
+						}
 
-					// Finished loading external file
-					function( xhr, url ) {
-						section.outerHTML = slidify( xhr.responseText, {
-							separator: section.getAttribute( 'data-separator' ),
-							verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
-							notesSeparator: section.getAttribute( 'data-separator-notes' ),
-							attributes: getForwardedAttributes( section )
-						});
-					},
+					) );
 
-					// Failed to load markdown
-					function( xhr, url ) {
-						section.outerHTML = '<section data-state="alert">' +
-							'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
-							'Check your browser\'s JavaScript console for more details.' +
-							'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
-							'</section>';
-					}
+				}
+				else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
 
-				) );
+					section.outerHTML = slidify( getMarkdownFromSlide( section ), {
+						separator: section.getAttribute( 'data-separator' ),
+						verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+						notesSeparator: section.getAttribute( 'data-separator-notes' ),
+						attributes: getForwardedAttributes( section )
+					});
 
-			}
-			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
+				}
+				else {
+					section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
+				}
 
-				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
-					separator: section.getAttribute( 'data-separator' ),
-					verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
-					notesSeparator: section.getAttribute( 'data-separator-notes' ),
-					attributes: getForwardedAttributes( section )
-				});
+			});
 
-			}
-			else {
-				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
-			}
+			Promise.all( externalPromises ).then( resolve );
 
-		});
+		} );
 
-		Promise.all( externalPromises ).then( resolve );
+	}
 
-	} );
+	function loadExternalMarkdown( section ) {
 
-}
+		return new Promise( function( resolve, reject ) {
 
-function loadExternalMarkdown( section ) {
+			var xhr = new XMLHttpRequest(),
+				url = section.getAttribute( 'data-markdown' );
 
-	return new Promise( function( resolve, reject ) {
+			var datacharset = section.getAttribute( 'data-charset' );
 
-		var xhr = new XMLHttpRequest(),
-			url = section.getAttribute( 'data-markdown' );
+			// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
+			if( datacharset != null && datacharset != '' ) {
+				xhr.overrideMimeType( 'text/html; charset=' + datacharset );
+			}
 
-		var datacharset = section.getAttribute( 'data-charset' );
+			xhr.onreadystatechange = function( section, xhr ) {
+				if( xhr.readyState === 4 ) {
+					// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
+					if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
 
-		// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
-		if( datacharset != null && datacharset != '' ) {
-			xhr.overrideMimeType( 'text/html; charset=' + datacharset );
-		}
+						resolve( xhr, url );
 
-		xhr.onreadystatechange = function( section, xhr ) {
-			if( xhr.readyState === 4 ) {
-				// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
-				if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
+					}
+					else {
 
-					resolve( xhr, url );
+						reject( xhr, url );
 
+					}
 				}
-				else {
+			}.bind( this, section, xhr );
 
-					reject( xhr, url );
+			xhr.open( 'GET', url, true );
 
-				}
+			try {
+				xhr.send();
+			}
+			catch ( e ) {
+				console.warn( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
+				resolve( xhr, url );
 			}
-		}.bind( this, section, xhr );
-
-		xhr.open( 'GET', url, true );
-
-		try {
-			xhr.send();
-		}
-		catch ( e ) {
-			console.warn( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
-			resolve( xhr, url );
-		}
 
-	} );
+		} );
 
-}
+	}
 
-/**
- * Check if a node value has the attributes pattern.
- * If yes, extract it and add that value as one or several attributes
- * to the target element.
- *
- * You need Cache Killer on Chrome to see the effect on any FOM transformation
- * directly on refresh (F5)
- * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
- */
-function addAttributeInElement( node, elementTarget, separator ) {
-
-	var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
-	var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
-	var nodeValue = node.nodeValue;
-	var matches,
-		matchesClass;
-	if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
-
-		var classes = matches[1];
-		nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
-		node.nodeValue = nodeValue;
-		while( matchesClass = mardownClassRegex.exec( classes ) ) {
-			if( matchesClass[2] ) {
-				elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
-			} else {
-				elementTarget.setAttribute( matchesClass[3], "" );
+	/**
+	 * Check if a node value has the attributes pattern.
+	 * If yes, extract it and add that value as one or several attributes
+	 * to the target element.
+	 *
+	 * You need Cache Killer on Chrome to see the effect on any FOM transformation
+	 * directly on refresh (F5)
+	 * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
+	 */
+	function addAttributeInElement( node, elementTarget, separator ) {
+
+		var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
+		var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
+		var nodeValue = node.nodeValue;
+		var matches,
+			matchesClass;
+		if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
+
+			var classes = matches[1];
+			nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
+			node.nodeValue = nodeValue;
+			while( matchesClass = mardownClassRegex.exec( classes ) ) {
+				if( matchesClass[2] ) {
+					elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
+				} else {
+					elementTarget.setAttribute( matchesClass[3], "" );
+				}
 			}
+			return true;
 		}
-		return true;
+		return false;
 	}
-	return false;
-}
 
-/**
- * Add attributes to the parent element of a text node,
- * or the element of an attribute node.
- */
-function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
-
-	if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
-		var previousParentElement = element;
-		for( var i = 0; i < element.childNodes.length; i++ ) {
-			var childElement = element.childNodes[i];
-			if ( i > 0 ) {
-				var j = i - 1;
-				while ( j >= 0 ) {
-					var aPreviousChildElement = element.childNodes[j];
-					if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
-						previousParentElement = aPreviousChildElement;
-						break;
+	/**
+	 * Add attributes to the parent element of a text node,
+	 * or the element of an attribute node.
+	 */
+	function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
+
+		if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
+			var previousParentElement = element;
+			for( var i = 0; i < element.childNodes.length; i++ ) {
+				var childElement = element.childNodes[i];
+				if ( i > 0 ) {
+					var j = i - 1;
+					while ( j >= 0 ) {
+						var aPreviousChildElement = element.childNodes[j];
+						if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
+							previousParentElement = aPreviousChildElement;
+							break;
+						}
+						j = j - 1;
 					}
-					j = j - 1;
 				}
-			}
-			var parentSection = section;
-			if( childElement.nodeName ==  "section" ) {
-				parentSection = childElement ;
-				previousParentElement = childElement ;
-			}
-			if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
-				addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				var parentSection = section;
+				if( childElement.nodeName ==  "section" ) {
+					parentSection = childElement ;
+					previousParentElement = childElement ;
+				}
+				if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
+					addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
+				}
 			}
 		}
-	}
 
-	if ( element.nodeType == Node.COMMENT_NODE ) {
-		if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
-			addAttributeInElement( element, section, separatorSectionAttributes );
+		if ( element.nodeType == Node.COMMENT_NODE ) {
+			if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
+				addAttributeInElement( element, section, separatorSectionAttributes );
+			}
 		}
 	}
-}
 
-/**
- * Converts any current data-markdown slides in the
- * DOM to HTML.
- */
-function convertSlides() {
+	/**
+	 * Converts any current data-markdown slides in the
+	 * DOM to HTML.
+	 */
+	function convertSlides() {
 
-	var sections = document.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
+		var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
 
-	[].slice.call( sections ).forEach( function( section ) {
+		[].slice.call( sections ).forEach( function( section ) {
 
-		section.setAttribute( 'data-markdown-parsed', true )
+			section.setAttribute( 'data-markdown-parsed', true )
 
-		var notes = section.querySelector( 'aside.notes' );
-		var markdown = getMarkdownFromSlide( section );
+			var notes = section.querySelector( 'aside.notes' );
+			var markdown = getMarkdownFromSlide( section );
 
-		section.innerHTML = marked( markdown );
-		addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
-						section.parentNode.getAttribute( 'data-element-attributes' ) ||
-						DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
-						section.getAttribute( 'data-attributes' ) ||
-						section.parentNode.getAttribute( 'data-attributes' ) ||
-						DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
+			section.innerHTML = marked( markdown );
+			addAttributes( 	section, section, null, section.getAttribute( 'data-element-attributes' ) ||
+							section.parentNode.getAttribute( 'data-element-attributes' ) ||
+							DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
+							section.getAttribute( 'data-attributes' ) ||
+							section.parentNode.getAttribute( 'data-attributes' ) ||
+							DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
 
-		// If there were notes, we need to re-add them after
-		// having overwritten the section's HTML
-		if( notes ) {
-			section.appendChild( notes );
-		}
+			// If there were notes, we need to re-add them after
+			// having overwritten the section's HTML
+			if( notes ) {
+				section.appendChild( notes );
+			}
+
+		} );
+
+		return Promise.resolve();
+
+	}
 
-	} );
+	return {
+		id: 'markdown',
+
+		/**
+		 * Starts processing and converting Markdown within the
+		 * current reveal.js deck.
+		 */
+		init: function( reveal ) {
+
+			deck = reveal;
+
+			// This should no longer be needed, as long as the highlight.js
+			// plugin is included after the markdown plugin
+			// if( typeof window.hljs !== 'undefined' ) {
+			// 	marked.setOptions({
+			// 		highlight: function( code, lang ) {
+			// 			return window.hljs.highlightAuto( code, lang ? [lang] : null ).value;
+			// 		}
+			// 	});
+			// }
+
+			// marked can be configured via reveal.js config options
+			var options = deck.getConfig().markdown;
+			if( options ) {
+				marked.setOptions( options );
+			}
+
+			return processSlides( deck.getRevealElement() ).then( convertSlides );
+
+		},
 
-	return Promise.resolve();
+		// TODO: Do these belong in the API?
+		processSlides: processSlides,
+		convertSlides: convertSlides,
+		slidify: slidify,
+		marked: marked
+	}
+
+};
 
-}
+export default Plugin;

+ 23 - 26
plugin/math/math.js

@@ -4,14 +4,12 @@
  *
  * @author Hakim El Hattab
  */
-let Plugin = (function(){
+const Plugin = () => {
 
-	var options = Reveal.getConfig().math || {};
-	var mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
-	var config = options.config || 'TeX-AMS_HTML-full';
-	var url = mathjax + '?config=' + config;
+	// The reveal.js instance this plugin is attached to
+	let deck;
 
-	var defaultOptions = {
+	let defaultOptions = {
 		messageStyle: 'none',
 		tex2jax: {
 			inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
@@ -20,25 +18,15 @@ let Plugin = (function(){
 		skipStartupTypeset: true
 	};
 
-	function defaults( options, defaultOptions ) {
-
-		for ( var i in defaultOptions ) {
-			if ( !options.hasOwnProperty( i ) ) {
-				options[i] = defaultOptions[i];
-			}
-		}
-
-	}
-
 	function loadScript( url, callback ) {
 
-		var head = document.querySelector( 'head' );
-		var script = document.createElement( 'script' );
+		let head = document.querySelector( 'head' );
+		let script = document.createElement( 'script' );
 		script.type = 'text/javascript';
 		script.src = url;
 
 		// Wrapper for callback to make sure it only fires once
-		var finish = function() {
+		let finish = () => {
 			if( typeof callback === 'function' ) {
 				callback.call();
 				callback = null;
@@ -48,7 +36,7 @@ let Plugin = (function(){
 		script.onload = finish;
 
 		// IE
-		script.onreadystatechange = function() {
+		script.onreadystatechange = () => {
 			if ( this.readyState === 'loaded' ) {
 				finish();
 			}
@@ -62,10 +50,19 @@ let Plugin = (function(){
 	return {
 		id: 'math',
 
-		init: function( deck ) {
+		init: function( reveal ) {
+
+			deck = reveal;
+
+			let revealOptions = deck.getConfig().math || {};
+
+			let options = { ...defaultOptions, ...revealOptions };
+			let mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
+			let config = options.config || 'TeX-AMS_HTML-full';
+			let url = mathjax + '?config=' + config;
+
+			options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
 
-			defaults( options, defaultOptions );
-			defaults( options.tex2jax, defaultOptions.tex2jax );
 			options.mathjax = options.config = null;
 
 			loadScript( url, function() {
@@ -74,7 +71,7 @@ let Plugin = (function(){
 
 				// Typeset followed by an immediate reveal.js layout since
 				// the typesetting process could affect slide height
-				MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
+				MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
 				MathJax.Hub.Queue( deck.layout );
 
 				// Reprocess equations in slides when they turn visible
@@ -89,6 +86,6 @@ let Plugin = (function(){
 		}
 	}
 
-})();
+};
 
-export default () => Plugin;
+export default Plugin;

+ 177 - 155
plugin/search/search.js

@@ -2,130 +2,89 @@
  * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
  * by navigatating to that slide and highlighting it.
  *
- * By Jon Snyder <snyder.jon@gmail.com>, February 2013
+ * @author Jon Snyder <snyder.jon@gmail.com>, February 2013
  */
 
-var Plugin = (function() {
-
-	var matchedSlides;
-	var currentMatchedIndex;
-	var searchboxDirty;
-	var myHilitor;
-
-// Original JavaScript code by Chirp Internet: www.chirp.com.au
-// Please acknowledge use of this code by including this header.
-// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
-
-function Hilitor(id, tag)
-{
-
-	var targetNode = document.getElementById(id) || document.body;
-	var hiliteTag = tag || "EM";
-	var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
-	var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
-	var wordColor = [];
-	var colorIdx = 0;
-	var matchRegex = "";
-	var matchingSlides = [];
-
-	this.setRegex = function(input)
-	{
-		input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
-		matchRegex = new RegExp("(" + input + ")","i");
-	}
-
-	this.getRegex = function()
-	{
-		return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
-	}
-
-	// recursively apply word highlighting
-	this.hiliteWords = function(node)
-	{
-		if(node == undefined || !node) return;
-		if(!matchRegex) return;
-		if(skipTags.test(node.nodeName)) return;
-
-		if(node.hasChildNodes()) {
-			for(var i=0; i < node.childNodes.length; i++)
-				this.hiliteWords(node.childNodes[i]);
-		}
-		if(node.nodeType == 3) { // NODE_TEXT
-			if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
-				//find the slide's section element and save it in our list of matching slides
-				var secnode = node;
-				while (secnode != null && secnode.nodeName != 'SECTION') {
-					secnode = secnode.parentNode;
-				}
-
-				var slideIndex = Reveal.getIndices(secnode);
-				var slidelen = matchingSlides.length;
-				var alreadyAdded = false;
-				for (var i=0; i < slidelen; i++) {
-					if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
-						alreadyAdded = true;
-					}
-				}
-				if (! alreadyAdded) {
-					matchingSlides.push(slideIndex);
-				}
-
-				if(!wordColor[regs[0].toLowerCase()]) {
-					wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
-				}
-
-				var match = document.createElement(hiliteTag);
-				match.appendChild(document.createTextNode(regs[0]));
-				match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
-				match.style.fontStyle = "inherit";
-				match.style.color = "#000";
-
-				var after = node.splitText(regs.index);
-				after.nodeValue = after.nodeValue.substring(regs[0].length);
-				node.parentNode.insertBefore(match, after);
+const Plugin = () => {
+
+	// The reveal.js instance this plugin is attached to
+	let deck;
+
+	let searchElement;
+	let searchButton;
+	let searchInput;
+
+	let matchedSlides;
+	let currentMatchedIndex;
+	let searchboxDirty;
+	let hilitor;
+
+	function render() {
+
+		searchElement = document.createElement( 'div' );
+		searchElement.classList.add( 'searchbox' );
+		searchElement.style.position = 'absolute';
+		searchElement.style.top = '10px';
+		searchElement.style.right = '10px';
+		searchElement.style.zIndex = 10;
+
+		//embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
+		searchElement.innerHTML = `<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>
+		</span>`;
+
+		searchInput = searchElement.querySelector( '.searchinput' );
+		searchInput.style.width = '240px';
+		searchInput.style.fontSize = '14px';
+		searchInput.style.padding = '4px 6px';
+		searchInput.style.color = '#000';
+		searchInput.style.background = '#fff';
+		searchInput.style.borderRadius = '2px';
+		searchInput.style.border = '0';
+		searchInput.style.outline = '0';
+		searchInput.style.boxShadow = '0 2px 18px rgba(0, 0, 0, 0.2)';
+		searchInput.style['-webkit-appearance']  = 'none';
+
+		deck.getRevealElement().appendChild( searchElement );
+
+		// searchButton.addEventListener( 'click', function(event) {
+		// 	doSearch();
+		// }, false );
+
+		searchInput.addEventListener( 'keyup', function( event ) {
+			switch (event.keyCode) {
+				case 13:
+					event.preventDefault();
+					doSearch();
+					searchboxDirty = false;
+					break;
+				default:
+					searchboxDirty = true;
 			}
-		}
-	};
-
-	// remove highlighting
-	this.remove = function()
-	{
-		var arr = document.getElementsByTagName(hiliteTag);
-		while(arr.length && (el = arr[0])) {
-			el.parentNode.replaceChild(el.firstChild, el);
-		}
-	};
+		}, false );
 
-	// start highlighting at target node
-	this.apply = function(input)
-	{
-		if(input == undefined || !input) return;
-		this.remove();
-		this.setRegex(input);
-		this.hiliteWords(targetNode);
-		return matchingSlides;
-	};
+		closeSearch();
 
-}
+	}
 
 	function openSearch() {
-		//ensure the search term input dialog is visible and has focus:
-		var inputboxdiv = document.getElementById("searchinputdiv");
-		var inputbox = document.getElementById("searchinput");
-		inputboxdiv.style.display = "inline";
-		inputbox.focus();
-		inputbox.select();
+		if( !searchElement ) render();
+
+		searchElement.style.display = 'inline';
+		searchInput.focus();
+		searchInput.select();
 	}
 
 	function closeSearch() {
-		var inputboxdiv = document.getElementById("searchinputdiv");
-		inputboxdiv.style.display = "none";
-		if(myHilitor) myHilitor.remove();
+		if( !searchElement ) render();
+
+		searchElement.style.display = 'none';
+		if(hilitor) hilitor.remove();
 	}
 
 	function toggleSearch() {
-		var inputboxdiv = document.getElementById("searchinputdiv");
-		if (inputboxdiv.style.display !== "inline") {
+		if( !searchElement ) render();
+
+		if (searchElement.style.display !== 'inline') {
 			openSearch();
 		}
 		else {
@@ -136,16 +95,16 @@ function Hilitor(id, tag)
 	function doSearch() {
 		//if there's been a change in the search term, perform a new search:
 		if (searchboxDirty) {
-			var searchstring = document.getElementById("searchinput").value;
+			var searchstring = searchInput.value;
 
 			if (searchstring === '') {
-				if(myHilitor) myHilitor.remove();
+				if(hilitor) hilitor.remove();
 				matchedSlides = null;
 			}
 			else {
 				//find the keyword amongst the slides
-				myHilitor = new Hilitor("slidecontent");
-				matchedSlides = myHilitor.apply(searchstring);
+				hilitor = new Hilitor("slidecontent");
+				matchedSlides = hilitor.apply(searchstring);
 				currentMatchedIndex = 0;
 			}
 		}
@@ -156,52 +115,107 @@ function Hilitor(id, tag)
 				currentMatchedIndex = 0;
 			}
 			if (matchedSlides.length > currentMatchedIndex) {
-				Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
+				deck.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
 				currentMatchedIndex++;
 			}
 		}
 	}
 
-	var dom = {};
-	dom.wrapper = document.querySelector( '.reveal' );
-
-	if( !dom.wrapper.querySelector( '.searchbox' ) ) {
-			var searchElement = document.createElement( 'div' );
-			searchElement.id = "searchinputdiv";
-			searchElement.classList.add( 'searchdiv' );
-			searchElement.style.position = 'absolute';
-			searchElement.style.top = '10px';
-			searchElement.style.right = '10px';
-			searchElement.style.zIndex = 10;
-			//embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
-			searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
-			dom.wrapper.appendChild( searchElement );
-	}
-
-	document.getElementById( 'searchbutton' ).addEventListener( 'click', function(event) {
-		doSearch();
-	}, false );
-
-	document.getElementById( 'searchinput' ).addEventListener( 'keyup', function( event ) {
-		switch (event.keyCode) {
-			case 13:
-				event.preventDefault();
-				doSearch();
-				searchboxDirty = false;
-				break;
-			default:
-				searchboxDirty = true;
+	// Original JavaScript code by Chirp Internet: www.chirp.com.au
+	// Please acknowledge use of this code by including this header.
+	// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
+	function Hilitor(id, tag) {
+
+		var targetNode = document.getElementById(id) || document.body;
+		var hiliteTag = tag || "EM";
+		var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
+		var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
+		var wordColor = [];
+		var colorIdx = 0;
+		var matchRegex = "";
+		var matchingSlides = [];
+
+		this.setRegex = function(input)
+		{
+			input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
+			matchRegex = new RegExp("(" + input + ")","i");
 		}
-	}, false );
 
-	document.addEventListener( 'keydown', function( event ) {
-		if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
-			event.preventDefault();
-			toggleSearch();
+		this.getRegex = function()
+		{
+			return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
 		}
-	}, false );
 
-	closeSearch();
+		// recursively apply word highlighting
+		this.hiliteWords = function(node)
+		{
+			if(node == undefined || !node) return;
+			if(!matchRegex) return;
+			if(skipTags.test(node.nodeName)) return;
+
+			if(node.hasChildNodes()) {
+				for(var i=0; i < node.childNodes.length; i++)
+					this.hiliteWords(node.childNodes[i]);
+			}
+			if(node.nodeType == 3) { // NODE_TEXT
+				var nv, regs;
+				if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
+					//find the slide's section element and save it in our list of matching slides
+					var secnode = node;
+					while (secnode != null && secnode.nodeName != 'SECTION') {
+						secnode = secnode.parentNode;
+					}
+
+					var slideIndex = deck.getIndices(secnode);
+					var slidelen = matchingSlides.length;
+					var alreadyAdded = false;
+					for (var i=0; i < slidelen; i++) {
+						if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
+							alreadyAdded = true;
+						}
+					}
+					if (! alreadyAdded) {
+						matchingSlides.push(slideIndex);
+					}
+
+					if(!wordColor[regs[0].toLowerCase()]) {
+						wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
+					}
+
+					var match = document.createElement(hiliteTag);
+					match.appendChild(document.createTextNode(regs[0]));
+					match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
+					match.style.fontStyle = "inherit";
+					match.style.color = "#000";
+
+					var after = node.splitText(regs.index);
+					after.nodeValue = after.nodeValue.substring(regs[0].length);
+					node.parentNode.insertBefore(match, after);
+				}
+			}
+		};
+
+		// remove highlighting
+		this.remove = function()
+		{
+			var arr = document.getElementsByTagName(hiliteTag);
+			var el;
+			while(arr.length && (el = arr[0])) {
+				el.parentNode.replaceChild(el.firstChild, el);
+			}
+		};
+
+		// start highlighting at target node
+		this.apply = function(input)
+		{
+			if(input == undefined || !input) return;
+			this.remove();
+			this.setRegex(input);
+			this.hiliteWords(targetNode);
+			return matchingSlides;
+		};
+
+	}
 
 	return {
 
@@ -209,13 +223,21 @@ function Hilitor(id, tag)
 
 		init: reveal => {
 
-			reveal.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
+			deck = reveal;
+			deck.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
+
+			document.addEventListener( 'keydown', function( event ) {
+				if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
+					event.preventDefault();
+					toggleSearch();
+				}
+			}, false );
 
 		},
 
 		open: openSearch
 
 	}
-})();
+};
 
-export default () => Plugin;
+export default Plugin;

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor