Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		| @@ -17,7 +17,7 @@ module.exports = function(grunt) { | |||||||
|  |  | ||||||
| 		// Tests will be added soon | 		// Tests will be added soon | ||||||
| 		qunit: { | 		qunit: { | ||||||
| 			files: [ 'test/**/*.html' ] | 			files: [ 'test/*.html' ] | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		uglify: { | 		uglify: { | ||||||
| @@ -109,6 +109,7 @@ module.exports = function(grunt) { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	// Dependencies | 	// Dependencies | ||||||
|  | 	grunt.loadNpmTasks( 'grunt-contrib-qunit' ); | ||||||
| 	grunt.loadNpmTasks( 'grunt-contrib-jshint' ); | 	grunt.loadNpmTasks( 'grunt-contrib-jshint' ); | ||||||
| 	grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); | 	grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); | ||||||
| 	grunt.loadNpmTasks( 'grunt-contrib-uglify' ); | 	grunt.loadNpmTasks( 'grunt-contrib-uglify' ); | ||||||
| @@ -118,7 +119,7 @@ module.exports = function(grunt) { | |||||||
| 	grunt.loadNpmTasks( 'grunt-zip' ); | 	grunt.loadNpmTasks( 'grunt-zip' ); | ||||||
|  |  | ||||||
| 	// Default task | 	// Default task | ||||||
| 	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify' ] ); | 	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] ); | ||||||
|  |  | ||||||
| 	// Theme task | 	// Theme task | ||||||
| 	grunt.registerTask( 'themes', [ 'sass' ] ); | 	grunt.registerTask( 'themes', [ 'sass' ] ); | ||||||
| @@ -129,4 +130,7 @@ module.exports = function(grunt) { | |||||||
| 	// Serve presentation locally | 	// Serve presentation locally | ||||||
| 	grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); | 	grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); | ||||||
|  |  | ||||||
|  | 	// Run tests | ||||||
|  | 	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] ); | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										158
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								README.md
									
									
									
									
									
								
							| @@ -52,10 +52,10 @@ This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Iri | |||||||
|  |  | ||||||
| #### External Markdown | #### External Markdown | ||||||
|  |  | ||||||
| You can write your content as a separate file and have reveal.js load it at runtime. Note the separator arguments which determine how slides are delimited in the external file. | You can write your content as a separate file and have reveal.js load it at runtime. Note the separator arguments which determine how slides are delimited in the external file. The ```data-charset``` attribute is optional and specifies which charset to use when loading the external file. | ||||||
|  |  | ||||||
| ```html | ```html | ||||||
| <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> | <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n" data-notes="^Note:" data-charset="iso-8859-15"></section> | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Configuration | ### Configuration | ||||||
| @@ -100,9 +100,6 @@ Reveal.initialize({ | |||||||
| 	// Enable slide navigation via mouse wheel | 	// Enable slide navigation via mouse wheel | ||||||
| 	mouseWheel: false, | 	mouseWheel: false, | ||||||
|  |  | ||||||
| 	// Apply a 3D roll to links on hover |  | ||||||
| 	rollingLinks: true, |  | ||||||
|  |  | ||||||
| 	// Transition style | 	// Transition style | ||||||
| 	transition: 'default', // default/cube/page/concave/zoom/linear/fade/none | 	transition: 'default', // default/cube/page/concave/zoom/linear/fade/none | ||||||
|  |  | ||||||
| @@ -110,7 +107,7 @@ Reveal.initialize({ | |||||||
| 	transitionSpeed: 'default', // default/fast/slow | 	transitionSpeed: 'default', // default/fast/slow | ||||||
|  |  | ||||||
| 	// Transition style for full page backgrounds | 	// Transition style for full page backgrounds | ||||||
| 	backgroundTransition: 'default' // default/linear | 	backgroundTransition: 'default' // default/linear/none | ||||||
|  |  | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @@ -153,7 +150,10 @@ Reveal.initialize({ | |||||||
| 		{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }, | 		{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }, | ||||||
|  |  | ||||||
| 		// Remote control your reveal.js presentation using a touch device | 		// Remote control your reveal.js presentation using a touch device | ||||||
| 		{ src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } } | 		{ src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }, | ||||||
|  |  | ||||||
|  | 		// MathJax | ||||||
|  | 		{ src: 'plugin/math/math.js', async: true } | ||||||
| 	] | 	] | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @@ -370,6 +370,8 @@ The display order of fragments can be controlled using the ```data-fragment-inde | |||||||
|  |  | ||||||
| When a slide fragment is either shown or hidden reveal.js will dispatch an event. | When a slide fragment is either shown or hidden reveal.js will dispatch an event. | ||||||
|  |  | ||||||
|  | Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback. | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.addEventListener( 'fragmentshown', function( event ) { | Reveal.addEventListener( 'fragmentshown', function( event ) { | ||||||
| 	// event.fragment = the fragment DOM element | 	// event.fragment = the fragment DOM element | ||||||
| @@ -398,7 +400,7 @@ By default, Reveal is configured with [highlight.js](http://softwaremaniacs.org/ | |||||||
|  |  | ||||||
| ### Overview mode | ### Overview mode | ||||||
|  |  | ||||||
| Press "Esc" key to toggle the overview mode on and off. While you're in this mode, you can still navigate between slides, | Press "Esc" or "o" keys to toggle the overview mode on and off. While you're in this mode, you can still navigate between slides, | ||||||
| as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks: | as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks: | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| @@ -414,7 +416,7 @@ Just press »F« on your keyboard to show your presentation in fullscreen mode. | |||||||
|  |  | ||||||
|  |  | ||||||
| ### Embedded media | ### Embedded media | ||||||
| Embedded HTML5 `<video>`/`<audio>` and YouTube iframes are automatically paused when your navigate away from a slide. This can be disabled by decorating your element with a `data-ignore` attribute. | Embedded HTML5 `<video>`/`<audio>` and YouTube iframes are automatically paused when you navigate away from a slide. This can be disabled by decorating your element with a `data-ignore` attribute. | ||||||
|  |  | ||||||
| Add `data-autoplay` to your media element if you want it to automatically start playing when the slide is shown: | Add `data-autoplay` to your media element if you want it to automatically start playing when the slide is shown: | ||||||
|  |  | ||||||
| @@ -423,6 +425,21 @@ Add `data-autoplay` to your media element if you want it to automatically start | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ### Stretching elements | ||||||
|  | Sometimes it's desirable to have an element, like an image or video, stretch to consume as much space as possible within a given slide. This can be done by adding the ```.stretch``` class to an element as seen below: | ||||||
|  |  | ||||||
|  | ```html | ||||||
|  | <section> | ||||||
|  | 	<h2>This video will use up the remaining space on the slide</h2> | ||||||
|  |     <video class="stretch" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video> | ||||||
|  | </section> | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Limitations: | ||||||
|  | - Only direct descendants of a slide section can be stretched | ||||||
|  | - Only one descendant per slide section can be stretched | ||||||
|  |  | ||||||
|  |  | ||||||
| ## PDF Export | ## PDF Export | ||||||
|  |  | ||||||
| Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). | Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). | ||||||
| @@ -461,7 +478,7 @@ If you want to add a theme of your own see the instructions here: [/css/theme/RE | |||||||
|  |  | ||||||
| reveal.js comes with a speaker notes plugin which can be used to present per-slide notes in a separate browser window. The notes window also gives you a preview of the next upcoming slide so it may be helpful even if you haven't written any notes. Press the 's' key on your keyboard to open the notes window. | reveal.js comes with a speaker notes plugin which can be used to present per-slide notes in a separate browser window. The notes window also gives you a preview of the next upcoming slide so it may be helpful even if you haven't written any notes. Press the 's' key on your keyboard to open the notes window. | ||||||
|  |  | ||||||
| By default notes are written using standard HTML, see below, but you can add a ```data-markdown``` attribute to the ```<aside>``` to write them using Markdown. | Notes are defined by appending an ```<aside>``` element to a slide as seen below. You can add the ```data-markdown``` attribute to the aside element if you prefer writing notes using Markdown. | ||||||
|  |  | ||||||
| ```html | ```html | ||||||
| <section> | <section> | ||||||
| @@ -473,6 +490,20 @@ By default notes are written using standard HTML, see below, but you can add a ` | |||||||
| </section> | </section> | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | If you're using the external Markdown plugin, you can add notes with the help of a special delimiter: | ||||||
|  |  | ||||||
|  | ```html | ||||||
|  | <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n" data-notes="^Note:"></section> | ||||||
|  |  | ||||||
|  | # Title | ||||||
|  | ## Sub-title | ||||||
|  |  | ||||||
|  | Here is some content... | ||||||
|  |  | ||||||
|  | Note: | ||||||
|  | This will only display in the notes window. | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ## Server Side Speaker Notes | ## Server Side Speaker Notes | ||||||
|  |  | ||||||
| In some cases it can be desirable to run notes on a separate device from the one you're presenting on. The Node.js-based notes plugin lets you do this using the same note definitions as its client side counterpart. Include the required scripts by adding the following dependencies: | In some cases it can be desirable to run notes on a separate device from the one you're presenting on. The Node.js-based notes plugin lets you do this using the same note definitions as its client side counterpart. Include the required scripts by adding the following dependencies: | ||||||
| @@ -520,23 +551,24 @@ You can then access your master presentation at ```http://localhost:1947``` | |||||||
| Example configuration: | Example configuration: | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
| 	// other options | 	// other options... | ||||||
|  |  | ||||||
| 	multiplex: { | 	multiplex: { | ||||||
| 		// Example values. Generate your own. | 		// Example values. To generate your own, see the socket.io server instructions. | ||||||
| 		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation | 		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation | ||||||
| 		id: '1ea875674b17ca76', // Obtained from socket.io server | 		id: '1ea875674b17ca76', // Obtained from socket.io server | ||||||
| 		url: 'revealjs.jit.su:80' // Location of socket.io server | 		url: 'revealjs.jit.su:80' // Location of socket.io server | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	// Optional libraries used to extend on reveal.js | 	// Don't forget to add the dependencies | ||||||
| 	dependencies: [ | 	dependencies: [ | ||||||
| 		// other deps |  | ||||||
| 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | ||||||
| 		{ src: 'plugin/multiplex/master.js', async: true }, | 		{ src: 'plugin/multiplex/master.js', async: true }, | ||||||
|  |  | ||||||
| 		// and if you want speaker notes | 		// and if you want speaker notes | ||||||
| 		{ src: 'plugin/notes-server/client.js', async: true } | 		{ src: 'plugin/notes-server/client.js', async: true } | ||||||
|  |  | ||||||
|  | 		// other dependencies... | ||||||
| 	] | 	] | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @@ -547,20 +579,21 @@ Served from a publicly accessible static file server. Examples include: GitHub P | |||||||
| Example configuration: | Example configuration: | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
| 	// other options | 	// other options... | ||||||
|  |  | ||||||
| 	multiplex: { | 	multiplex: { | ||||||
| 		// Example values. Generate your own. | 		// Example values. To generate your own, see the socket.io server instructions. | ||||||
| 		secret: null, // null so the clients do not have control of the master presentation | 		secret: null, // null so the clients do not have control of the master presentation | ||||||
| 		id: '1ea875674b17ca76', // id, obtained from socket.io server | 		id: '1ea875674b17ca76', // id, obtained from socket.io server | ||||||
| 		url: 'revealjs.jit.su:80' // Location of socket.io server | 		url: 'revealjs.jit.su:80' // Location of socket.io server | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	// Optional libraries used to extend on reveal.js | 	// Don't forget to add the dependencies | ||||||
| 	dependencies: [ | 	dependencies: [ | ||||||
| 		// other deps |  | ||||||
| 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | ||||||
| 		{ src: 'plugin/multiplex/client.js', async: true } | 		{ src: 'plugin/multiplex/client.js', async: true } | ||||||
|  |  | ||||||
|  | 		// other dependencies... | ||||||
| 	] | 	] | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @@ -584,20 +617,21 @@ The socket.io server can play the role of static file server for your client pre | |||||||
| Example configuration: | Example configuration: | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
| 	// other options | 	// other options... | ||||||
|  |  | ||||||
| 	multiplex: { | 	multiplex: { | ||||||
| 		// Example values. Generate your own. | 		// Example values. To generate your own, see the socket.io server instructions. | ||||||
| 		secret: null, // null so the clients do not have control of the master presentation | 		secret: null, // null so the clients do not have control of the master presentation | ||||||
| 		id: '1ea875674b17ca76', // id, obtained from socket.io server | 		id: '1ea875674b17ca76', // id, obtained from socket.io server | ||||||
| 		url: 'example.com:80' // Location of your socket.io server | 		url: 'example.com:80' // Location of your socket.io server | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	// Optional libraries used to extend on reveal.js | 	// Don't forget to add the dependencies | ||||||
| 	dependencies: [ | 	dependencies: [ | ||||||
| 		// other deps |  | ||||||
| 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | ||||||
| 		{ src: 'plugin/multiplex/client.js', async: true } | 		{ src: 'plugin/multiplex/client.js', async: true } | ||||||
|  |  | ||||||
|  | 		// other dependencies... | ||||||
| 	] | 	] | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| @@ -606,21 +640,22 @@ It can also play the role of static file server for your master presentation and | |||||||
| Example configuration: | Example configuration: | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
| 	// other options | 	// other options... | ||||||
|  |  | ||||||
| 	multiplex: { | 	multiplex: { | ||||||
| 		// Example values. Generate your own. | 		// Example values. To generate your own, see the socket.io server instructions. | ||||||
| 		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation | 		secret: '13652805320794272084', // Obtained from the socket.io server. Gives this (the master) control of the presentation | ||||||
| 		id: '1ea875674b17ca76', // Obtained from socket.io server | 		id: '1ea875674b17ca76', // Obtained from socket.io server | ||||||
| 		url: 'example.com:80' // Location of your socket.io server | 		url: 'example.com:80' // Location of your socket.io server | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	// Optional libraries used to extend on reveal.js | 	// Don't forget to add the dependencies | ||||||
| 	dependencies: [ | 	dependencies: [ | ||||||
| 		// other deps |  | ||||||
| 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | 		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true }, | ||||||
| 		{ src: 'plugin/multiplex/master.js', async: true }, | 		{ src: 'plugin/multiplex/master.js', async: true }, | ||||||
| 		{ src: 'plugin/multiplex/client.js', async: true } | 		{ src: 'plugin/multiplex/client.js', async: true } | ||||||
|  |  | ||||||
|  | 		// other dependencies... | ||||||
| 	] | 	] | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
| @@ -629,46 +664,75 @@ Reveal.initialize({ | |||||||
| The Leap Motion plugin lets you utilize your [Leap Motion](https://www.leapmotion.com/) device to control basic navigation of your presentation. The gestures currently supported are: | The Leap Motion plugin lets you utilize your [Leap Motion](https://www.leapmotion.com/) device to control basic navigation of your presentation. The gestures currently supported are: | ||||||
|  |  | ||||||
| ##### 1 to 2 fingers | ##### 1 to 2 fingers | ||||||
| * Pointer — Point to anything on screen. Move your finger past the device to expand the pointer. | Pointer — Point to anything on screen. Move your finger past the device to expand the pointer. | ||||||
|  |  | ||||||
| ##### 1 hand + 3 or more fingers |  | ||||||
|  |  | ||||||
| * Left |  | ||||||
| * Right |  | ||||||
| * Up |  | ||||||
| * down |  | ||||||
|  |  | ||||||
|  | ##### 1 hand + 3 or more fingers (left/right/up/down) | ||||||
| Navigate through your slides. See config options to invert movements. | Navigate through your slides. See config options to invert movements. | ||||||
|  |  | ||||||
| ##### 2 hands | ##### 2 hands upwards | ||||||
| * Up |  | ||||||
|  |  | ||||||
| Toggle the overview mode. Do it a second time to exit the overview. | Toggle the overview mode. Do it a second time to exit the overview. | ||||||
|  |  | ||||||
| #### Config Options | #### Config Options | ||||||
| You can edit the following options: | You can edit the following options: | ||||||
| * autoCenter: Defaults to true. Center the pointer based on where you put your finger into the leap motions detection field. |  | ||||||
| * gestureDelay: Defaults to 500. How long to delay between gestures in milliseconds. | | Property          | Default           | Description | ||||||
| * naturalSwipe: Defaults to true. Swipe as though you were touching a touch screen. Set to false to invert. | | ----------------- |:-----------------:| :------------- | ||||||
| * pointerColor: Defaults to #00aaff. The color of the pointer. | | autoCenter        | true              | Center the pointer based on where you put your finger into the leap motions detection field. | ||||||
| * pointerOpacity: Defaults to 0.7. The opacity of the pointer. | | gestureDelay      | 500               | How long to delay between gestures in milliseconds. | ||||||
| * pointerSize: Defaults to 15. The minimum height and width of the pointer. | | naturalSwipe      | true              | Swipe as though you were touching a touch screen. Set to false to invert. | ||||||
| * pointerTolerance: Defaults to 120. Bigger = slower pointer. | | pointerColor      | #00aaff           | The color of the pointer. | ||||||
|  | | pointerOpacity    | 0.7               | The opacity of the pointer. | ||||||
|  | | pointerSize       | 15                | The minimum height and width of the pointer. | ||||||
|  | | pointerTolerance  | 120               | Bigger = slower pointer. | ||||||
|  |  | ||||||
|  |  | ||||||
| Example configuration: | Example configuration: | ||||||
| ```js | ```js | ||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
| 	// other options |  | ||||||
|  | 	// other options... | ||||||
|  |  | ||||||
| 	leap: { | 	leap: { | ||||||
| 		naturalSwipe   : false,    // Invert swipe gestures | 		naturalSwipe   : false,    // Invert swipe gestures | ||||||
| 		pointerOpacity : 0.5,      // Set pointer opacity to 0.5 | 		pointerOpacity : 0.5,      // Set pointer opacity to 0.5 | ||||||
| 		pointerColor   : '#d80000' // Red pointer | 		pointerColor   : '#d80000' // Red pointer | ||||||
| 	} | 	}, | ||||||
|  |  | ||||||
| 	// Optional libraries used to extend on reveal.js | 	dependencies: [ | ||||||
| 		{ src: 'plugin/leap/leap.js', async: true } | 		{ src: 'plugin/leap/leap.js', async: true } | ||||||
|  | 	] | ||||||
|  |  | ||||||
|  | }); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ## MathJax | ||||||
|  |  | ||||||
|  | If you want to display math equations in your presentation you can easily do so by including this plugin. The plugin is a very thin wrapper around the [MathJax](http://www.mathjax.org/) library. To use it you'll need to include it as a reveal.js dependency, [find our more about dependencies here](#dependencies). | ||||||
|  |  | ||||||
|  | The plugin defaults to using [LaTeX](http://en.wikipedia.org/wiki/LaTeX) but that can be adjusted through the ```math``` configuration object. Note that MathJax is loaded from a remote server. If you want to use it offline you'll need to download a copy of the library and adjust the ```mathjax``` configuration value.  | ||||||
|  |  | ||||||
|  | Below is an example of how the plugin can be configured. If you don't intend to change these values you do not need to include the ```math``` config object at all. | ||||||
|  |  | ||||||
|  | ```js | ||||||
|  | Reveal.initialize({ | ||||||
|  |  | ||||||
|  | 	// other options ... | ||||||
|  |  | ||||||
|  | 	math: { | ||||||
|  | 		mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js', | ||||||
|  | 		config: 'TeX-AMS_HTML-full'  // See http://docs.mathjax.org/en/latest/config-files.html | ||||||
|  | 	}, | ||||||
|  | 	 | ||||||
|  | 	dependencies: [ | ||||||
|  | 		{ src: 'plugin/math/math.js', async: true } | ||||||
|  | 	] | ||||||
|  |  | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Read MathJax's documentation if you need [HTTPS delivery](http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn) or serving of [specific versions](http://docs.mathjax.org/en/latest/configuration.html#loading-mathjax-from-the-cdn) for stability. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Installation | ## Installation | ||||||
|  |  | ||||||
| The **basic setup** is for authoring presentations only. The **full setup** gives you access to all reveal.js features and plugins such as speaker notes as well as the development tasks needed to make changes to the source. | The **basic setup** is for authoring presentations only. The **full setup** gives you access to all reveal.js features and plugins such as speaker notes as well as the development tasks needed to make changes to the source. | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ body, p, td, li, div, a { | |||||||
| } | } | ||||||
|  |  | ||||||
| /* SECTION 4: Set heading font face, sizes, and color. | /* SECTION 4: Set heading font face, sizes, and color. | ||||||
|    Diffrentiate your headings from your body text. |    Differentiate your headings from your body text. | ||||||
|    Perhaps use a large sans-serif for distinction. */ |    Perhaps use a large sans-serif for distinction. */ | ||||||
| h1,h2,h3,h4,h5,h6 { | h1,h2,h3,h4,h5,h6 { | ||||||
| 	color: #000!important; | 	color: #000!important; | ||||||
|   | |||||||
| @@ -56,7 +56,7 @@ body, p, td, li, div { | |||||||
| } | } | ||||||
|  |  | ||||||
| /* SECTION 4: Set heading font face, sizes, and color. | /* SECTION 4: Set heading font face, sizes, and color. | ||||||
|    Diffrentiate your headings from your body text. |    Differentiate your headings from your body text. | ||||||
|    Perhaps use a large sans-serif for distinction. */ |    Perhaps use a large sans-serif for distinction. */ | ||||||
| h1,h2,h3,h4,h5,h6 { | h1,h2,h3,h4,h5,h6 { | ||||||
| 	text-shadow: 0 0 0 #000 !important; | 	text-shadow: 0 0 0 #000 !important; | ||||||
|   | |||||||
							
								
								
									
										219
									
								
								css/reveal.css
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								css/reveal.css
									
									
									
									
									
								
							| @@ -205,6 +205,10 @@ body { | |||||||
|   font-style: italic; |   font-style: italic; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .reveal iframe { | ||||||
|  | 	z-index: 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Ensure certain elements are never larger than the slide itself */ | /* Ensure certain elements are never larger than the slide itself */ | ||||||
| .reveal img, | .reveal img, | ||||||
| .reveal video, | .reveal video, | ||||||
| @@ -314,6 +318,14 @@ body { | |||||||
| 	max-height: 400px; | 	max-height: 400px; | ||||||
| 	word-wrap: normal; | 	word-wrap: normal; | ||||||
| } | } | ||||||
|  | .reveal pre.stretch code { | ||||||
|  | 	height: 100%; | ||||||
|  | 	max-height: 100%; | ||||||
|  |  | ||||||
|  | 	-webkit-box-sizing: border-box; | ||||||
|  | 	   -moz-box-sizing: border-box; | ||||||
|  | 	        box-sizing: border-box; | ||||||
|  | } | ||||||
|  |  | ||||||
| .reveal table th, | .reveal table th, | ||||||
| .reveal table td { | .reveal table td { | ||||||
| @@ -343,6 +355,11 @@ body { | |||||||
| 	vertical-align: top; | 	vertical-align: top; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .reveal .stretch { | ||||||
|  | 	max-width: none; | ||||||
|  | 	max-height: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* | /********************************************* | ||||||
|  * CONTROLS |  * CONTROLS | ||||||
| @@ -460,90 +477,6 @@ body { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* |  | ||||||
|  * ROLLING LINKS |  | ||||||
|  *********************************************/ |  | ||||||
|  |  | ||||||
| .reveal .roll { |  | ||||||
| 	display: inline-block; |  | ||||||
| 	line-height: 1.2; |  | ||||||
| 	overflow: hidden; |  | ||||||
|  |  | ||||||
| 	vertical-align: top; |  | ||||||
|  |  | ||||||
| 	-webkit-perspective: 400px; |  | ||||||
| 	   -moz-perspective: 400px; |  | ||||||
| 	    -ms-perspective: 400px; |  | ||||||
| 	        perspective: 400px; |  | ||||||
|  |  | ||||||
| 	-webkit-perspective-origin: 50% 50%; |  | ||||||
| 	   -moz-perspective-origin: 50% 50%; |  | ||||||
| 	    -ms-perspective-origin: 50% 50%; |  | ||||||
| 	        perspective-origin: 50% 50%; |  | ||||||
| } |  | ||||||
| 	.reveal .roll:hover { |  | ||||||
| 		background: none; |  | ||||||
| 		text-shadow: none; |  | ||||||
| 	} |  | ||||||
| .reveal .roll span { |  | ||||||
| 	display: block; |  | ||||||
| 	position: relative; |  | ||||||
| 	padding: 0 2px; |  | ||||||
|  |  | ||||||
| 	pointer-events: none; |  | ||||||
|  |  | ||||||
| 	-webkit-transition: all 400ms ease; |  | ||||||
| 	   -moz-transition: all 400ms ease; |  | ||||||
| 	    -ms-transition: all 400ms ease; |  | ||||||
| 	        transition: all 400ms ease; |  | ||||||
|  |  | ||||||
| 	-webkit-transform-origin: 50% 0%; |  | ||||||
| 	   -moz-transform-origin: 50% 0%; |  | ||||||
| 	    -ms-transform-origin: 50% 0%; |  | ||||||
| 	        transform-origin: 50% 0%; |  | ||||||
|  |  | ||||||
| 	-webkit-transform-style: preserve-3d; |  | ||||||
| 	   -moz-transform-style: preserve-3d; |  | ||||||
| 	    -ms-transform-style: preserve-3d; |  | ||||||
| 	        transform-style: preserve-3d; |  | ||||||
|  |  | ||||||
| 	-webkit-backface-visibility: hidden; |  | ||||||
| 	   -moz-backface-visibility: hidden; |  | ||||||
| 	        backface-visibility: hidden; |  | ||||||
| } |  | ||||||
| 	.reveal .roll:hover span { |  | ||||||
| 	    background: rgba(0,0,0,0.5); |  | ||||||
|  |  | ||||||
| 	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); |  | ||||||
| 	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); |  | ||||||
| 	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); |  | ||||||
| 	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); |  | ||||||
| 	} |  | ||||||
| .reveal .roll span:after { |  | ||||||
| 	content: attr(data-title); |  | ||||||
|  |  | ||||||
| 	display: block; |  | ||||||
| 	position: absolute; |  | ||||||
| 	left: 0; |  | ||||||
| 	top: 0; |  | ||||||
| 	padding: 0 2px; |  | ||||||
|  |  | ||||||
| 	-webkit-backface-visibility: hidden; |  | ||||||
| 	   -moz-backface-visibility: hidden; |  | ||||||
| 	        backface-visibility: hidden; |  | ||||||
|  |  | ||||||
| 	-webkit-transform-origin: 50% 0%; |  | ||||||
| 	   -moz-transform-origin: 50% 0%; |  | ||||||
| 	    -ms-transform-origin: 50% 0%; |  | ||||||
| 	        transform-origin: 50% 0%; |  | ||||||
|  |  | ||||||
| 	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); |  | ||||||
| 	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); |  | ||||||
| 	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); |  | ||||||
| 	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* | /********************************************* | ||||||
|  * SLIDES |  * SLIDES | ||||||
|  *********************************************/ |  *********************************************/ | ||||||
| @@ -673,6 +606,19 @@ body { | |||||||
| 	min-height: auto !important; | 	min-height: auto !important; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Don't allow interaction with invisible slides */ | ||||||
|  | .reveal .slides>section.future, | ||||||
|  | .reveal .slides>section>section.future, | ||||||
|  | .reveal .slides>section.past, | ||||||
|  | .reveal .slides>section>section.past { | ||||||
|  | 	pointer-events: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .reveal.overview .slides>section, | ||||||
|  | .reveal.overview .slides>section>section { | ||||||
|  | 	pointer-events: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* | /********************************************* | ||||||
| @@ -1152,6 +1098,7 @@ body { | |||||||
|  |  | ||||||
| .reveal.overview .slides section { | .reveal.overview .slides section { | ||||||
| 	height: 600px; | 	height: 600px; | ||||||
|  | 	top: -300px !important; | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
| 	opacity: 1 !important; | 	opacity: 1 !important; | ||||||
| 	visibility: visible !important; | 	visibility: visible !important; | ||||||
| @@ -1177,6 +1124,7 @@ body { | |||||||
| 	} | 	} | ||||||
| .reveal.overview .slides>section.stack { | .reveal.overview .slides>section.stack { | ||||||
| 	padding: 0; | 	padding: 0; | ||||||
|  | 	top: 0 !important; | ||||||
| 	background: none; | 	background: none; | ||||||
| 	overflow: visible; | 	overflow: visible; | ||||||
| } | } | ||||||
| @@ -1345,6 +1293,16 @@ body { | |||||||
| 		visibility: visible !important; | 		visibility: visible !important; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | /* Immediate transition style */ | ||||||
|  | .reveal[data-background-transition=none]>.backgrounds .slide-background, | ||||||
|  | .reveal>.backgrounds .slide-background[data-background-transition=none] { | ||||||
|  | 	-webkit-transition: none; | ||||||
|  | 	   -moz-transition: none; | ||||||
|  | 	    -ms-transition: none; | ||||||
|  | 	     -o-transition: none; | ||||||
|  | 	        transition: none; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Linear sliding transition style */ | /* Linear sliding transition style */ | ||||||
| .reveal[data-background-transition=slide]>.backgrounds .slide-background, | .reveal[data-background-transition=slide]>.backgrounds .slide-background, | ||||||
| .reveal>.backgrounds .slide-background[data-background-transition=slide] { | .reveal>.backgrounds .slide-background[data-background-transition=slide] { | ||||||
| @@ -1564,6 +1522,90 @@ body { | |||||||
|  	} |  	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /********************************************* | ||||||
|  |  * ROLLING LINKS | ||||||
|  |  *********************************************/ | ||||||
|  |  | ||||||
|  | .reveal .roll { | ||||||
|  | 	display: inline-block; | ||||||
|  | 	line-height: 1.2; | ||||||
|  | 	overflow: hidden; | ||||||
|  |  | ||||||
|  | 	vertical-align: top; | ||||||
|  |  | ||||||
|  | 	-webkit-perspective: 400px; | ||||||
|  | 	   -moz-perspective: 400px; | ||||||
|  | 	    -ms-perspective: 400px; | ||||||
|  | 	        perspective: 400px; | ||||||
|  |  | ||||||
|  | 	-webkit-perspective-origin: 50% 50%; | ||||||
|  | 	   -moz-perspective-origin: 50% 50%; | ||||||
|  | 	    -ms-perspective-origin: 50% 50%; | ||||||
|  | 	        perspective-origin: 50% 50%; | ||||||
|  | } | ||||||
|  | 	.reveal .roll:hover { | ||||||
|  | 		background: none; | ||||||
|  | 		text-shadow: none; | ||||||
|  | 	} | ||||||
|  | .reveal .roll span { | ||||||
|  | 	display: block; | ||||||
|  | 	position: relative; | ||||||
|  | 	padding: 0 2px; | ||||||
|  |  | ||||||
|  | 	pointer-events: none; | ||||||
|  |  | ||||||
|  | 	-webkit-transition: all 400ms ease; | ||||||
|  | 	   -moz-transition: all 400ms ease; | ||||||
|  | 	    -ms-transition: all 400ms ease; | ||||||
|  | 	        transition: all 400ms ease; | ||||||
|  |  | ||||||
|  | 	-webkit-transform-origin: 50% 0%; | ||||||
|  | 	   -moz-transform-origin: 50% 0%; | ||||||
|  | 	    -ms-transform-origin: 50% 0%; | ||||||
|  | 	        transform-origin: 50% 0%; | ||||||
|  |  | ||||||
|  | 	-webkit-transform-style: preserve-3d; | ||||||
|  | 	   -moz-transform-style: preserve-3d; | ||||||
|  | 	    -ms-transform-style: preserve-3d; | ||||||
|  | 	        transform-style: preserve-3d; | ||||||
|  |  | ||||||
|  | 	-webkit-backface-visibility: hidden; | ||||||
|  | 	   -moz-backface-visibility: hidden; | ||||||
|  | 	        backface-visibility: hidden; | ||||||
|  | } | ||||||
|  | 	.reveal .roll:hover span { | ||||||
|  | 	    background: rgba(0,0,0,0.5); | ||||||
|  |  | ||||||
|  | 	    -webkit-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); | ||||||
|  | 	       -moz-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); | ||||||
|  | 	        -ms-transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); | ||||||
|  | 	            transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); | ||||||
|  | 	} | ||||||
|  | .reveal .roll span:after { | ||||||
|  | 	content: attr(data-title); | ||||||
|  |  | ||||||
|  | 	display: block; | ||||||
|  | 	position: absolute; | ||||||
|  | 	left: 0; | ||||||
|  | 	top: 0; | ||||||
|  | 	padding: 0 2px; | ||||||
|  |  | ||||||
|  | 	-webkit-backface-visibility: hidden; | ||||||
|  | 	   -moz-backface-visibility: hidden; | ||||||
|  | 	        backface-visibility: hidden; | ||||||
|  |  | ||||||
|  | 	-webkit-transform-origin: 50% 0%; | ||||||
|  | 	   -moz-transform-origin: 50% 0%; | ||||||
|  | 	    -ms-transform-origin: 50% 0%; | ||||||
|  | 	        transform-origin: 50% 0%; | ||||||
|  |  | ||||||
|  | 	-webkit-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); | ||||||
|  | 	   -moz-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); | ||||||
|  | 	    -ms-transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); | ||||||
|  | 	        transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* | /********************************************* | ||||||
|  * SPEAKER NOTES |  * SPEAKER NOTES | ||||||
|  *********************************************/ |  *********************************************/ | ||||||
| @@ -1605,12 +1647,3 @@ body { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /********************************************* |  | ||||||
|  * LEAP PLUGIN |  | ||||||
|  *********************************************/ |  | ||||||
|  |  | ||||||
| #leap { |  | ||||||
|   position: absolute;  |  | ||||||
|   z-index: 50; |  | ||||||
|   visibility: hidden; |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								css/reveal.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								css/reveal.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -10,6 +10,7 @@ $mainFontSize: 36px; | |||||||
| $mainColor: #eee; | $mainColor: #eee; | ||||||
|  |  | ||||||
| // Headings | // Headings | ||||||
|  | $headingMargin: 0 0 20px 0; | ||||||
| $headingFont: 'League Gothic', Impact, sans-serif; | $headingFont: 'League Gothic', Impact, sans-serif; | ||||||
| $headingColor: #eee; | $headingColor: #eee; | ||||||
| $headingLineHeight: 0.9em; | $headingLineHeight: 0.9em; | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ body { | |||||||
| .reveal h4, | .reveal h4, | ||||||
| .reveal h5, | .reveal h5, | ||||||
| .reveal h6 { | .reveal h6 { | ||||||
| 	margin: 0 0 20px 0; | 	margin: $headingMargin; | ||||||
| 	color: $headingColor; | 	color: $headingColor; | ||||||
|  |  | ||||||
| 	font-family: $headingFont; | 	font-family: $headingFont; | ||||||
|   | |||||||
| @@ -371,9 +371,6 @@ function linkify( selector ) { | |||||||
| 					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, | 					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, | ||||||
| 					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }, | 					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }, | ||||||
| 					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } } | 					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } } | ||||||
| 					// { src: 'plugin/leap/leap.js', async: true } |  | ||||||
| 					// { src: 'plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } } |  | ||||||
| 					// { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } } |  | ||||||
| 				] | 				] | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										630
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										630
									
								
								js/reveal.js
									
									
									
									
									
								
							| @@ -59,6 +59,10 @@ var Reveal = (function(){ | |||||||
| 			// Turns fragments on and off globally | 			// Turns fragments on and off globally | ||||||
| 			fragments: true, | 			fragments: true, | ||||||
|  |  | ||||||
|  | 			// Flags if the presentation is running in an embedded mode, | ||||||
|  | 			// i.e. contained within a limited portion of the screen | ||||||
|  | 			embedded: false, | ||||||
|  |  | ||||||
| 			// Number of milliseconds between automatically proceeding to the | 			// Number of milliseconds between automatically proceeding to the | ||||||
| 			// next slide, disabled when set to 0, this value can be overwritten | 			// next slide, disabled when set to 0, this value can be overwritten | ||||||
| 			// by using a data-autoslide attribute on your slides | 			// by using a data-autoslide attribute on your slides | ||||||
| @@ -68,7 +72,7 @@ var Reveal = (function(){ | |||||||
| 			mouseWheel: false, | 			mouseWheel: false, | ||||||
|  |  | ||||||
| 			// Apply a 3D roll to links on hover | 			// Apply a 3D roll to links on hover | ||||||
| 			rollingLinks: true, | 			rollingLinks: false, | ||||||
|  |  | ||||||
| 			// Opens links in an iframe preview overlay | 			// Opens links in an iframe preview overlay | ||||||
| 			previewLinks: false, | 			previewLinks: false, | ||||||
| @@ -83,18 +87,24 @@ var Reveal = (function(){ | |||||||
| 			transitionSpeed: 'default', // default/fast/slow | 			transitionSpeed: 'default', // default/fast/slow | ||||||
|  |  | ||||||
| 			// Transition style for full page slide backgrounds | 			// Transition style for full page slide backgrounds | ||||||
| 			backgroundTransition: 'default', // default/linear | 			backgroundTransition: 'default', // default/linear/none | ||||||
|  |  | ||||||
|  | 			// Number of slides away from the current that are visible | ||||||
|  | 			viewDistance: 3, | ||||||
|  |  | ||||||
| 			// Script dependencies to load | 			// Script dependencies to load | ||||||
| 			dependencies: [] | 			dependencies: [] | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | 		// Flags if reveal.js is loaded (has dispatched the 'ready' event) | ||||||
|  | 		loaded = false, | ||||||
|  |  | ||||||
| 		// The current auto-slide duration | 		// The current auto-slide duration | ||||||
| 		autoSlide = 0, | 		autoSlide = 0, | ||||||
|  |  | ||||||
| 		// The horizontal and vertical index of the currently active slide | 		// The horizontal and vertical index of the currently active slide | ||||||
| 		indexh = 0, | 		indexh, | ||||||
| 		indexv = 0, | 		indexv, | ||||||
|  |  | ||||||
| 		// The previous and current slide HTML elements | 		// The previous and current slide HTML elements | ||||||
| 		previousSlide, | 		previousSlide, | ||||||
| @@ -111,19 +121,14 @@ var Reveal = (function(){ | |||||||
| 		// Cached references to DOM elements | 		// Cached references to DOM elements | ||||||
| 		dom = {}, | 		dom = {}, | ||||||
|  |  | ||||||
| 		// Detect support for CSS 3D transforms | 		// Client support for CSS 3D transforms, see #checkCapabilities() | ||||||
| 		supports3DTransforms =  'WebkitPerspective' in document.body.style || | 		supports3DTransforms, | ||||||
| 								'MozPerspective' in document.body.style || |  | ||||||
| 								'msPerspective' in document.body.style || |  | ||||||
| 								'OPerspective' in document.body.style || |  | ||||||
| 								'perspective' in document.body.style, |  | ||||||
|  |  | ||||||
| 		// Detect support for CSS 2D transforms | 		// Client support for CSS 2D transforms, see #checkCapabilities() | ||||||
| 		supports2DTransforms =  'WebkitTransform' in document.body.style || | 		supports2DTransforms, | ||||||
| 								'MozTransform' in document.body.style || |  | ||||||
| 								'msTransform' in document.body.style || | 		// Client is a mobile device, see #checkCapabilities() | ||||||
| 								'OTransform' in document.body.style || | 		isMobileDevice, | ||||||
| 								'transform' in document.body.style, |  | ||||||
|  |  | ||||||
| 		// Throttles mouse wheel navigation | 		// Throttles mouse wheel navigation | ||||||
| 		lastMouseWheelStep = 0, | 		lastMouseWheelStep = 0, | ||||||
| @@ -149,8 +154,8 @@ var Reveal = (function(){ | |||||||
| 			startY: 0, | 			startY: 0, | ||||||
| 			startSpan: 0, | 			startSpan: 0, | ||||||
| 			startCount: 0, | 			startCount: 0, | ||||||
| 			handled: false, | 			captured: false, | ||||||
| 			threshold: 80 | 			threshold: 40 | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -158,6 +163,8 @@ var Reveal = (function(){ | |||||||
| 	 */ | 	 */ | ||||||
| 	function initialize( options ) { | 	function initialize( options ) { | ||||||
|  |  | ||||||
|  | 		checkCapabilities(); | ||||||
|  |  | ||||||
| 		if( !supports2DTransforms && !supports3DTransforms ) { | 		if( !supports2DTransforms && !supports3DTransforms ) { | ||||||
| 			document.body.setAttribute( 'class', 'no-transforms' ); | 			document.body.setAttribute( 'class', 'no-transforms' ); | ||||||
|  |  | ||||||
| @@ -180,6 +187,136 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Inspect the client to see what it's capable of, this | ||||||
|  | 	 * should only happens once per runtime. | ||||||
|  | 	 */ | ||||||
|  | 	function checkCapabilities() { | ||||||
|  |  | ||||||
|  | 		supports3DTransforms =  'WebkitPerspective' in document.body.style || | ||||||
|  | 								'MozPerspective' in document.body.style || | ||||||
|  | 								'msPerspective' in document.body.style || | ||||||
|  | 								'OPerspective' in document.body.style || | ||||||
|  | 								'perspective' in document.body.style; | ||||||
|  |  | ||||||
|  | 		supports2DTransforms =  'WebkitTransform' in document.body.style || | ||||||
|  | 								'MozTransform' in document.body.style || | ||||||
|  | 								'msTransform' in document.body.style || | ||||||
|  | 								'OTransform' in document.body.style || | ||||||
|  | 								'transform' in document.body.style; | ||||||
|  |  | ||||||
|  | 		isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Loads the dependencies of reveal.js. Dependencies are | ||||||
|  | 	 * defined via the configuration option 'dependencies' | ||||||
|  | 	 * and will be loaded prior to starting/binding reveal.js. | ||||||
|  | 	 * Some dependencies may have an 'async' flag, if so they | ||||||
|  | 	 * will load after reveal.js has been started up. | ||||||
|  | 	 */ | ||||||
|  | 	function load() { | ||||||
|  |  | ||||||
|  | 		var scripts = [], | ||||||
|  | 			scriptsAsync = []; | ||||||
|  |  | ||||||
|  | 		for( var i = 0, len = config.dependencies.length; i < len; i++ ) { | ||||||
|  | 			var s = config.dependencies[i]; | ||||||
|  |  | ||||||
|  | 			// Load if there's no condition or the condition is truthy | ||||||
|  | 			if( !s.condition || s.condition() ) { | ||||||
|  | 				if( s.async ) { | ||||||
|  | 					scriptsAsync.push( s.src ); | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					scripts.push( s.src ); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Extension may contain callback functions | ||||||
|  | 				if( typeof s.callback === 'function' ) { | ||||||
|  | 					head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], s.callback ); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Called once synchronous scripts finish loading | ||||||
|  | 		function proceed() { | ||||||
|  | 			if( scriptsAsync.length ) { | ||||||
|  | 				// Load asynchronous scripts | ||||||
|  | 				head.js.apply( null, scriptsAsync ); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			start(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if( scripts.length ) { | ||||||
|  | 			head.ready( proceed ); | ||||||
|  |  | ||||||
|  | 			// Load synchronous scripts | ||||||
|  | 			head.js.apply( null, scripts ); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			proceed(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Starts up reveal.js by binding input events and navigating | ||||||
|  | 	 * to the current URL deeplink if there is one. | ||||||
|  | 	 */ | ||||||
|  | 	function start() { | ||||||
|  |  | ||||||
|  | 		// Make sure we've got all the DOM elements we need | ||||||
|  | 		setupDOM(); | ||||||
|  |  | ||||||
|  | 		// Decorate the slide DOM elements with state classes (past/future) | ||||||
|  | 		setupSlides(); | ||||||
|  |  | ||||||
|  | 		// Updates the presentation to match the current configuration values | ||||||
|  | 		configure(); | ||||||
|  |  | ||||||
|  | 		// Read the initial hash | ||||||
|  | 		readURL(); | ||||||
|  |  | ||||||
|  | 		// Notify listeners that the presentation is ready but use a 1ms | ||||||
|  | 		// timeout to ensure it's not fired synchronously after #initialize() | ||||||
|  | 		setTimeout( function() { | ||||||
|  | 			// Enable transitions now that we're loaded | ||||||
|  | 			dom.slides.classList.remove( 'no-transition' ); | ||||||
|  |  | ||||||
|  | 			loaded = true; | ||||||
|  |  | ||||||
|  | 			dispatchEvent( 'ready', { | ||||||
|  | 				'indexh': indexh, | ||||||
|  | 				'indexv': indexv, | ||||||
|  | 				'currentSlide': currentSlide | ||||||
|  | 			} ); | ||||||
|  | 		}, 1 ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Iterates through and decorates slides DOM elements with | ||||||
|  | 	 * appropriate classes. | ||||||
|  | 	 */ | ||||||
|  | 	function setupSlides() { | ||||||
|  |  | ||||||
|  | 		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); | ||||||
|  | 		horizontalSlides.forEach( function( horizontalSlide ) { | ||||||
|  |  | ||||||
|  | 			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); | ||||||
|  | 			verticalSlides.forEach( function( verticalSlide, y ) { | ||||||
|  |  | ||||||
|  | 				if( y > 0 ) verticalSlide.classList.add( 'future' ); | ||||||
|  |  | ||||||
|  | 			} ); | ||||||
|  |  | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Finds and stores references to DOM elements which are | 	 * Finds and stores references to DOM elements which are | ||||||
| 	 * required by the presentation. If a required element is | 	 * required by the presentation. If a required element is | ||||||
| @@ -192,50 +329,30 @@ var Reveal = (function(){ | |||||||
| 		dom.wrapper = document.querySelector( '.reveal' ); | 		dom.wrapper = document.querySelector( '.reveal' ); | ||||||
| 		dom.slides = document.querySelector( '.reveal .slides' ); | 		dom.slides = document.querySelector( '.reveal .slides' ); | ||||||
|  |  | ||||||
|  | 		// Prevent transitions while we're loading | ||||||
|  | 		dom.slides.classList.add( 'no-transition' ); | ||||||
|  |  | ||||||
| 		// Background element | 		// Background element | ||||||
| 		if( !document.querySelector( '.reveal .backgrounds' ) ) { | 		dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null ); | ||||||
| 			dom.background = document.createElement( 'div' ); |  | ||||||
| 			dom.background.classList.add( 'backgrounds' ); |  | ||||||
| 			dom.wrapper.appendChild( dom.background ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Progress bar | 		// Progress bar | ||||||
| 		if( !dom.wrapper.querySelector( '.progress' ) ) { | 		dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' ); | ||||||
| 			var progressElement = document.createElement( 'div' ); | 		dom.progressbar = dom.progress.querySelector( 'span' ); | ||||||
| 			progressElement.classList.add( 'progress' ); |  | ||||||
| 			progressElement.innerHTML = '<span></span>'; |  | ||||||
| 			dom.wrapper.appendChild( progressElement ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Arrow controls | 		// Arrow controls | ||||||
| 		if( !dom.wrapper.querySelector( '.controls' ) ) { | 		createSingletonNode( dom.wrapper, 'aside', 'controls', | ||||||
| 			var controlsElement = document.createElement( 'aside' ); | 			'<div class="navigate-left"></div>' + | ||||||
| 			controlsElement.classList.add( 'controls' ); |  | ||||||
| 			controlsElement.innerHTML = '<div class="navigate-left"></div>' + |  | ||||||
| 			'<div class="navigate-right"></div>' + | 			'<div class="navigate-right"></div>' + | ||||||
| 			'<div class="navigate-up"></div>' + | 			'<div class="navigate-up"></div>' + | ||||||
| 										'<div class="navigate-down"></div>'; | 			'<div class="navigate-down"></div>' ); | ||||||
| 			dom.wrapper.appendChild( controlsElement ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// State background element [DEPRECATED] | 		// State background element [DEPRECATED] | ||||||
| 		if( !dom.wrapper.querySelector( '.state-background' ) ) { | 		createSingletonNode( dom.wrapper, 'div', 'state-background', null ); | ||||||
| 			var stateBackgroundElement = document.createElement( 'div' ); |  | ||||||
| 			stateBackgroundElement.classList.add( 'state-background' ); |  | ||||||
| 			dom.wrapper.appendChild( stateBackgroundElement ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Overlay graphic which is displayed during the paused mode | 		// Overlay graphic which is displayed during the paused mode | ||||||
| 		if( !dom.wrapper.querySelector( '.pause-overlay' ) ) { | 		createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null ); | ||||||
| 			var pausedElement = document.createElement( 'div' ); |  | ||||||
| 			pausedElement.classList.add( 'pause-overlay' ); |  | ||||||
| 			dom.wrapper.appendChild( pausedElement ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Cache references to elements | 		// Cache references to elements | ||||||
| 		dom.progress = document.querySelector( '.reveal .progress' ); |  | ||||||
| 		dom.progressbar = document.querySelector( '.reveal .progress span' ); |  | ||||||
|  |  | ||||||
| 		if ( config.controls ) { | 		if ( config.controls ) { | ||||||
| 			dom.controls = document.querySelector( '.reveal .controls' ); | 			dom.controls = document.querySelector( '.reveal .controls' ); | ||||||
|  |  | ||||||
| @@ -250,6 +367,26 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Creates an HTML element and returns a reference to it. | ||||||
|  | 	 * If the element already exists the existing instance will | ||||||
|  | 	 * be returned. | ||||||
|  | 	 */ | ||||||
|  | 	function createSingletonNode( container, tagname, classname, innerHTML ) { | ||||||
|  |  | ||||||
|  | 		var node = container.querySelector( '.' + classname ); | ||||||
|  | 		if( !node ) { | ||||||
|  | 			node = document.createElement( tagname ); | ||||||
|  | 			node.classList.add( classname ); | ||||||
|  | 			if( innerHTML !== null ) { | ||||||
|  | 				node.innerHTML = innerHTML; | ||||||
|  | 			} | ||||||
|  | 			container.appendChild( node ); | ||||||
|  | 		} | ||||||
|  | 		return node; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Creates the slide background elements and appends them | 	 * Creates the slide background elements and appends them | ||||||
| 	 * to the background container. One element is created per | 	 * to the background container. One element is created per | ||||||
| @@ -334,99 +471,6 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Hides the address bar if we're on a mobile device. |  | ||||||
| 	 */ |  | ||||||
| 	function hideAddressBar() { |  | ||||||
|  |  | ||||||
| 		if( /iphone|ipod|android/gi.test( navigator.userAgent ) && !/crios/gi.test( navigator.userAgent ) ) { |  | ||||||
| 			// Events that should trigger the address bar to hide |  | ||||||
| 			window.addEventListener( 'load', removeAddressBar, false ); |  | ||||||
| 			window.addEventListener( 'orientationchange', removeAddressBar, false ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Loads the dependencies of reveal.js. Dependencies are |  | ||||||
| 	 * defined via the configuration option 'dependencies' |  | ||||||
| 	 * and will be loaded prior to starting/binding reveal.js. |  | ||||||
| 	 * Some dependencies may have an 'async' flag, if so they |  | ||||||
| 	 * will load after reveal.js has been started up. |  | ||||||
| 	 */ |  | ||||||
| 	function load() { |  | ||||||
|  |  | ||||||
| 		var scripts = [], |  | ||||||
| 			scriptsAsync = []; |  | ||||||
|  |  | ||||||
| 		for( var i = 0, len = config.dependencies.length; i < len; i++ ) { |  | ||||||
| 			var s = config.dependencies[i]; |  | ||||||
|  |  | ||||||
| 			// Load if there's no condition or the condition is truthy |  | ||||||
| 			if( !s.condition || s.condition() ) { |  | ||||||
| 				if( s.async ) { |  | ||||||
| 					scriptsAsync.push( s.src ); |  | ||||||
| 				} |  | ||||||
| 				else { |  | ||||||
| 					scripts.push( s.src ); |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				// Extension may contain callback functions |  | ||||||
| 				if( typeof s.callback === 'function' ) { |  | ||||||
| 					head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], s.callback ); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Called once synchronous scripts finish loading |  | ||||||
| 		function proceed() { |  | ||||||
| 			if( scriptsAsync.length ) { |  | ||||||
| 				// Load asynchronous scripts |  | ||||||
| 				head.js.apply( null, scriptsAsync ); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			start(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if( scripts.length ) { |  | ||||||
| 			head.ready( proceed ); |  | ||||||
|  |  | ||||||
| 			// Load synchronous scripts |  | ||||||
| 			head.js.apply( null, scripts ); |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			proceed(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Starts up reveal.js by binding input events and navigating |  | ||||||
| 	 * to the current URL deeplink if there is one. |  | ||||||
| 	 */ |  | ||||||
| 	function start() { |  | ||||||
|  |  | ||||||
| 		// Make sure we've got all the DOM elements we need |  | ||||||
| 		setupDOM(); |  | ||||||
|  |  | ||||||
| 		// Updates the presentation to match the current configuration values |  | ||||||
| 		configure(); |  | ||||||
|  |  | ||||||
| 		// Read the initial hash |  | ||||||
| 		readURL(); |  | ||||||
|  |  | ||||||
| 		// Notify listeners that the presentation is ready but use a 1ms |  | ||||||
| 		// timeout to ensure it's not fired synchronously after #initialize() |  | ||||||
| 		setTimeout( function() { |  | ||||||
| 			dispatchEvent( 'ready', { |  | ||||||
| 				'indexh': indexh, |  | ||||||
| 				'indexv': indexv, |  | ||||||
| 				'currentSlide': currentSlide |  | ||||||
| 			} ); |  | ||||||
| 		}, 1 ); |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Applies the configuration settings from the config | 	 * Applies the configuration settings from the config | ||||||
| 	 * object. May be called multiple times. | 	 * object. May be called multiple times. | ||||||
| @@ -630,6 +674,19 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Applies a CSS transform to the target element. | ||||||
|  | 	 */ | ||||||
|  | 	function transformElement( element, transform ) { | ||||||
|  |  | ||||||
|  | 		element.style.WebkitTransform = transform; | ||||||
|  | 		element.style.MozTransform = transform; | ||||||
|  | 		element.style.msTransform = transform; | ||||||
|  | 		element.style.OTransform = transform; | ||||||
|  | 		element.style.transform = transform; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Retrieves the height of the given element by looking | 	 * Retrieves the height of the given element by looking | ||||||
| 	 * at the position and height of its immediate children. | 	 * at the position and height of its immediate children. | ||||||
| @@ -665,6 +722,48 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Returns the remaining height within the parent of the | ||||||
|  | 	 * target element after subtracting the height of all | ||||||
|  | 	 * siblings. | ||||||
|  | 	 * | ||||||
|  | 	 * remaining height = [parent height] - [ siblings height] | ||||||
|  | 	 */ | ||||||
|  | 	function getRemainingHeight( element, height ) { | ||||||
|  |  | ||||||
|  | 		height = height || 0; | ||||||
|  |  | ||||||
|  | 		if( element ) { | ||||||
|  | 			var parent = element.parentNode; | ||||||
|  | 			var siblings = parent.childNodes; | ||||||
|  |  | ||||||
|  | 			// Subtract the height of each sibling | ||||||
|  | 			toArray( siblings ).forEach( function( sibling ) { | ||||||
|  |  | ||||||
|  | 				if( typeof sibling.offsetHeight === 'number' && sibling !== element ) { | ||||||
|  |  | ||||||
|  | 					var styles = window.getComputedStyle( sibling ), | ||||||
|  | 						marginTop = parseInt( styles.marginTop, 10 ), | ||||||
|  | 						marginBottom = parseInt( styles.marginBottom, 10 ); | ||||||
|  |  | ||||||
|  | 					height -= sibling.offsetHeight + marginTop + marginBottom; | ||||||
|  |  | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 			} ); | ||||||
|  |  | ||||||
|  | 			var elementStyles = window.getComputedStyle( element ); | ||||||
|  |  | ||||||
|  | 			// Subtract the margins of the target element | ||||||
|  | 			height -= parseInt( elementStyles.marginTop, 10 ) + | ||||||
|  | 						parseInt( elementStyles.marginBottom, 10 ); | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return height; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Checks if this instance is being used to print a PDF. | 	 * Checks if this instance is being used to print a PDF. | ||||||
| 	 */ | 	 */ | ||||||
| @@ -674,6 +773,19 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Hides the address bar if we're on a mobile device. | ||||||
|  | 	 */ | ||||||
|  | 	function hideAddressBar() { | ||||||
|  |  | ||||||
|  | 		if( /iphone|ipod|android/gi.test( navigator.userAgent ) && !/crios/gi.test( navigator.userAgent ) ) { | ||||||
|  | 			// Events that should trigger the address bar to hide | ||||||
|  | 			window.addEventListener( 'load', removeAddressBar, false ); | ||||||
|  | 			window.addEventListener( 'orientationchange', removeAddressBar, false ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Causes the address bar to hide on mobile devices, | 	 * Causes the address bar to hide on mobile devices, | ||||||
| 	 * more vertical space ftw. | 	 * more vertical space ftw. | ||||||
| @@ -886,7 +998,11 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 			// Dimensions of the content | 			// Dimensions of the content | ||||||
| 			var slideWidth = config.width, | 			var slideWidth = config.width, | ||||||
| 				slideHeight = config.height; | 				slideHeight = config.height, | ||||||
|  | 				slidePadding = 20; // TODO Dig this out of DOM | ||||||
|  |  | ||||||
|  | 			// Layout the contents of the slides | ||||||
|  | 			layoutSlideContents( config.width, config.height, slidePadding ); | ||||||
|  |  | ||||||
| 			// Slide width may be a percentage of available width | 			// Slide width may be a percentage of available width | ||||||
| 			if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) { | 			if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) { | ||||||
| @@ -915,13 +1031,7 @@ var Reveal = (function(){ | |||||||
| 			} | 			} | ||||||
| 			// Apply scale transform as a fallback | 			// Apply scale transform as a fallback | ||||||
| 			else { | 			else { | ||||||
| 				var transform = 'translate(-50%, -50%) scale('+ scale +') translate(50%, 50%)'; | 				transformElement( dom.slides, 'translate(-50%, -50%) scale('+ scale +') translate(50%, 50%)' ); | ||||||
|  |  | ||||||
| 				dom.slides.style.WebkitTransform = transform; |  | ||||||
| 				dom.slides.style.MozTransform = transform; |  | ||||||
| 				dom.slides.style.msTransform = transform; |  | ||||||
| 				dom.slides.style.OTransform = transform; |  | ||||||
| 				dom.slides.style.transform = transform; |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Select all slides, vertical and horizontal | 			// Select all slides, vertical and horizontal | ||||||
| @@ -942,7 +1052,7 @@ var Reveal = (function(){ | |||||||
| 						slide.style.top = 0; | 						slide.style.top = 0; | ||||||
| 					} | 					} | ||||||
| 					else { | 					else { | ||||||
| 						slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) - 20, -slideHeight / 2 ) + 'px'; | 						slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) - slidePadding, -slideHeight / 2 ) + 'px'; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				else { | 				else { | ||||||
| @@ -957,6 +1067,38 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Applies layout logic to the contents of all slides in | ||||||
|  | 	 * the presentation. | ||||||
|  | 	 */ | ||||||
|  | 	function layoutSlideContents( width, height, padding ) { | ||||||
|  |  | ||||||
|  | 		// Handle sizing of elements with the 'stretch' class | ||||||
|  | 		toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) { | ||||||
|  |  | ||||||
|  | 			// Determine how much vertical space we can use | ||||||
|  | 			var remainingHeight = getRemainingHeight( element, ( height - ( padding * 2 ) ) ); | ||||||
|  |  | ||||||
|  | 			// Consider the aspect ratio of media elements | ||||||
|  | 			if( /(img|video)/gi.test( element.nodeName ) ) { | ||||||
|  | 				var nw = element.naturalWidth || element.videoWidth, | ||||||
|  | 					nh = element.naturalHeight || element.videoHeight; | ||||||
|  |  | ||||||
|  | 				var es = Math.min( width / nw, remainingHeight / nh ); | ||||||
|  |  | ||||||
|  | 				element.style.width = ( nw * es ) + 'px'; | ||||||
|  | 				element.style.height = ( nh * es ) + 'px'; | ||||||
|  |  | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				element.style.width = width + 'px'; | ||||||
|  | 				element.style.height = remainingHeight + 'px'; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Stores the vertical index of a stack so that the same | 	 * Stores the vertical index of a stack so that the same | ||||||
| 	 * vertical slide can be selected when navigating to and | 	 * vertical slide can be selected when navigating to and | ||||||
| @@ -1010,6 +1152,9 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 			var wasActive = dom.wrapper.classList.contains( 'overview' ); | 			var wasActive = dom.wrapper.classList.contains( 'overview' ); | ||||||
|  |  | ||||||
|  | 			// Vary the depth of the overview based on screen size | ||||||
|  | 			var depth = window.innerWidth < 400 ? 1000 : 2500; | ||||||
|  |  | ||||||
| 			dom.wrapper.classList.add( 'overview' ); | 			dom.wrapper.classList.add( 'overview' ); | ||||||
| 			dom.wrapper.classList.remove( 'exit-overview' ); | 			dom.wrapper.classList.remove( 'exit-overview' ); | ||||||
|  |  | ||||||
| @@ -1025,16 +1170,12 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 				for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) { | 				for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) { | ||||||
| 					var hslide = horizontalSlides[i], | 					var hslide = horizontalSlides[i], | ||||||
| 						hoffset = config.rtl ? -105 : 105, | 						hoffset = config.rtl ? -105 : 105; | ||||||
| 						htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)'; |  | ||||||
|  |  | ||||||
| 					hslide.setAttribute( 'data-index-h', i ); | 					hslide.setAttribute( 'data-index-h', i ); | ||||||
| 					hslide.style.display = 'block'; |  | ||||||
| 					hslide.style.WebkitTransform = htransform; | 					// Apply CSS transform | ||||||
| 					hslide.style.MozTransform = htransform; | 					transformElement( hslide, 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)' ); | ||||||
| 					hslide.style.msTransform = htransform; |  | ||||||
| 					hslide.style.OTransform = htransform; |  | ||||||
| 					hslide.style.transform = htransform; |  | ||||||
|  |  | ||||||
| 					if( hslide.classList.contains( 'stack' ) ) { | 					if( hslide.classList.contains( 'stack' ) ) { | ||||||
|  |  | ||||||
| @@ -1043,17 +1184,13 @@ var Reveal = (function(){ | |||||||
| 						for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) { | 						for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) { | ||||||
| 							var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide ); | 							var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide ); | ||||||
|  |  | ||||||
| 							var vslide = verticalSlides[j], | 							var vslide = verticalSlides[j]; | ||||||
| 								vtransform = 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)'; |  | ||||||
|  |  | ||||||
| 							vslide.setAttribute( 'data-index-h', i ); | 							vslide.setAttribute( 'data-index-h', i ); | ||||||
| 							vslide.setAttribute( 'data-index-v', j ); | 							vslide.setAttribute( 'data-index-v', j ); | ||||||
| 							vslide.style.display = 'block'; |  | ||||||
| 							vslide.style.WebkitTransform = vtransform; | 							// Apply CSS transform | ||||||
| 							vslide.style.MozTransform = vtransform; | 							transformElement( vslide, 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)' ); | ||||||
| 							vslide.style.msTransform = vtransform; |  | ||||||
| 							vslide.style.OTransform = vtransform; |  | ||||||
| 							vslide.style.transform = vtransform; |  | ||||||
|  |  | ||||||
| 							// Navigate to this slide on click | 							// Navigate to this slide on click | ||||||
| 							vslide.addEventListener( 'click', onOverviewSlideClicked, true ); | 							vslide.addEventListener( 'click', onOverviewSlideClicked, true ); | ||||||
| @@ -1068,6 +1205,8 @@ var Reveal = (function(){ | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				updateSlidesVisibility(); | ||||||
|  |  | ||||||
| 				layout(); | 				layout(); | ||||||
|  |  | ||||||
| 				if( !wasActive ) { | 				if( !wasActive ) { | ||||||
| @@ -1117,11 +1256,7 @@ var Reveal = (function(){ | |||||||
| 				element.style.display = ''; | 				element.style.display = ''; | ||||||
|  |  | ||||||
| 				// Resets all transforms to use the external styles | 				// Resets all transforms to use the external styles | ||||||
| 				element.style.WebkitTransform = ''; | 				transformElement( element, '' ); | ||||||
| 				element.style.MozTransform = ''; |  | ||||||
| 				element.style.msTransform = ''; |  | ||||||
| 				element.style.OTransform = ''; |  | ||||||
| 				element.style.transform = ''; |  | ||||||
|  |  | ||||||
| 				element.removeEventListener( 'click', onOverviewSlideClicked, true ); | 				element.removeEventListener( 'click', onOverviewSlideClicked, true ); | ||||||
| 			} | 			} | ||||||
| @@ -1182,7 +1317,7 @@ var Reveal = (function(){ | |||||||
| 		// Prefer slide argument, otherwise use current slide | 		// Prefer slide argument, otherwise use current slide | ||||||
| 		slide = slide ? slide : currentSlide; | 		slide = slide ? slide : currentSlide; | ||||||
|  |  | ||||||
| 		return slide && !!slide.parentNode.nodeName.match( /section/i ); | 		return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i ); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1302,13 +1437,16 @@ var Reveal = (function(){ | |||||||
| 		// Reset the state array | 		// Reset the state array | ||||||
| 		state.length = 0; | 		state.length = 0; | ||||||
|  |  | ||||||
| 		var indexhBefore = indexh, | 		var indexhBefore = indexh || 0, | ||||||
| 			indexvBefore = indexv; | 			indexvBefore = indexv || 0; | ||||||
|  |  | ||||||
| 		// Activate and transition to the new slide | 		// Activate and transition to the new slide | ||||||
| 		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h ); | 		indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h ); | ||||||
| 		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v ); | 		indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v ); | ||||||
|  |  | ||||||
|  | 		// Update the visibility of slides now that the indices have changed | ||||||
|  | 		updateSlidesVisibility(); | ||||||
|  |  | ||||||
| 		layout(); | 		layout(); | ||||||
|  |  | ||||||
| 		// Apply the new state | 		// Apply the new state | ||||||
| @@ -1338,10 +1476,6 @@ var Reveal = (function(){ | |||||||
| 			activateOverview(); | 			activateOverview(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Update the URL hash after a delay since updating it mid-transition |  | ||||||
| 		// is likely to cause visual lag |  | ||||||
| 		writeURL( 1500 ); |  | ||||||
|  |  | ||||||
| 		// Find the current horizontal slide and any possible vertical slides | 		// Find the current horizontal slide and any possible vertical slides | ||||||
| 		// within it | 		// within it | ||||||
| 		var currentHorizontalSlide = horizontalSlides[ indexh ], | 		var currentHorizontalSlide = horizontalSlides[ indexh ], | ||||||
| @@ -1413,6 +1547,9 @@ var Reveal = (function(){ | |||||||
| 		updateProgress(); | 		updateProgress(); | ||||||
| 		updateBackground(); | 		updateBackground(); | ||||||
|  |  | ||||||
|  | 		// Update the URL hash | ||||||
|  | 		writeURL(); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -1481,16 +1618,6 @@ var Reveal = (function(){ | |||||||
| 			for( var i = 0; i < slidesLength; i++ ) { | 			for( var i = 0; i < slidesLength; i++ ) { | ||||||
| 				var element = slides[i]; | 				var element = slides[i]; | ||||||
|  |  | ||||||
| 				// Optimization; hide all slides that are three or more steps |  | ||||||
| 				// away from the present slide |  | ||||||
| 				if( isOverview() === false ) { |  | ||||||
| 					// The distance loops so that it measures 1 between the first |  | ||||||
| 					// and last slides |  | ||||||
| 					var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0; |  | ||||||
|  |  | ||||||
| 					element.style.display = distance > 3 ? 'none' : 'block'; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				var reverse = config.rtl && !isVerticalSlide( element ); | 				var reverse = config.rtl && !isVerticalSlide( element ); | ||||||
|  |  | ||||||
| 				element.classList.remove( 'past' ); | 				element.classList.remove( 'past' ); | ||||||
| @@ -1507,6 +1634,13 @@ var Reveal = (function(){ | |||||||
| 				else if( i > index ) { | 				else if( i > index ) { | ||||||
| 					// Any element subsequent to index is given the 'future' class | 					// Any element subsequent to index is given the 'future' class | ||||||
| 					element.classList.add( reverse ? 'past' : 'future' ); | 					element.classList.add( reverse ? 'past' : 'future' ); | ||||||
|  |  | ||||||
|  | 					var fragments = toArray( element.querySelectorAll( '.fragment.visible' ) ); | ||||||
|  |  | ||||||
|  | 					// No fragments in future slides should be visible ahead of time | ||||||
|  | 					while( fragments.length ) { | ||||||
|  | 						fragments.pop().classList.remove( 'visible' ); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				// If this element contains vertical slides | 				// If this element contains vertical slides | ||||||
| @@ -1526,7 +1660,7 @@ var Reveal = (function(){ | |||||||
| 				state = state.concat( slideState.split( ' ' ) ); | 				state = state.concat( slideState.split( ' ' ) ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// If this slide has a data-autoslide attribtue associated use this as | 			// If this slide has a data-autoslide attribute associated use this as | ||||||
| 			// autoSlide value otherwise use the global configured time | 			// autoSlide value otherwise use the global configured time | ||||||
| 			var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' ); | 			var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' ); | ||||||
| 			if( slideAutoSlide ) { | 			if( slideAutoSlide ) { | ||||||
| @@ -1536,6 +1670,8 @@ var Reveal = (function(){ | |||||||
| 				autoSlide = config.autoSlide; | 				autoSlide = config.autoSlide; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			cueAutoSlide(); | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			// Since there are no slides we can't be anywhere beyond the | 			// Since there are no slides we can't be anywhere beyond the | ||||||
| @@ -1547,6 +1683,61 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Optimization method; hide all slides that are far away | ||||||
|  | 	 * from the present slide. | ||||||
|  | 	 */ | ||||||
|  | 	function updateSlidesVisibility() { | ||||||
|  |  | ||||||
|  | 		// Select all slides and convert the NodeList result to | ||||||
|  | 		// an array | ||||||
|  | 		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ), | ||||||
|  | 			horizontalSlidesLength = horizontalSlides.length, | ||||||
|  | 			distanceX, | ||||||
|  | 			distanceY; | ||||||
|  |  | ||||||
|  | 		if( horizontalSlidesLength ) { | ||||||
|  |  | ||||||
|  | 			// The number of steps away from the present slide that will | ||||||
|  | 			// be visible | ||||||
|  | 			var viewDistance = isOverview() ? 10 : config.viewDistance; | ||||||
|  |  | ||||||
|  | 			// Limit view distance on weaker devices | ||||||
|  | 			if( isMobileDevice ) { | ||||||
|  | 				viewDistance = isOverview() ? 6 : 1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			for( var x = 0; x < horizontalSlidesLength; x++ ) { | ||||||
|  | 				var horizontalSlide = horizontalSlides[x]; | ||||||
|  |  | ||||||
|  | 				var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ), | ||||||
|  | 					verticalSlidesLength = verticalSlides.length; | ||||||
|  |  | ||||||
|  | 				// Loops so that it measures 1 between the first and last slides | ||||||
|  | 				distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0; | ||||||
|  |  | ||||||
|  | 				// Show the horizontal slide if it's within the view distance | ||||||
|  | 				horizontalSlide.style.display = distanceX > viewDistance ? 'none' : 'block'; | ||||||
|  |  | ||||||
|  | 				if( verticalSlidesLength ) { | ||||||
|  |  | ||||||
|  | 					var oy = getPreviousVerticalIndex( horizontalSlide ); | ||||||
|  |  | ||||||
|  | 					for( var y = 0; y < verticalSlidesLength; y++ ) { | ||||||
|  | 						var verticalSlide = verticalSlides[y]; | ||||||
|  |  | ||||||
|  | 						distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy ); | ||||||
|  |  | ||||||
|  | 						verticalSlide.style.display = ( distanceX + distanceY ) > viewDistance ? 'none' : 'block'; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Updates the progress bar to reflect the current slide. | 	 * Updates the progress bar to reflect the current slide. | ||||||
| 	 */ | 	 */ | ||||||
| @@ -1803,7 +1994,7 @@ var Reveal = (function(){ | |||||||
| 			} | 			} | ||||||
| 			// If the slide doesn't exist, navigate to the current slide | 			// If the slide doesn't exist, navigate to the current slide | ||||||
| 			else { | 			else { | ||||||
| 				slide( indexh, indexv ); | 				slide( indexh || 0, indexv || 0 ); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| @@ -1811,8 +2002,10 @@ var Reveal = (function(){ | |||||||
| 			var h = parseInt( bits[0], 10 ) || 0, | 			var h = parseInt( bits[0], 10 ) || 0, | ||||||
| 				v = parseInt( bits[1], 10 ) || 0; | 				v = parseInt( bits[1], 10 ) || 0; | ||||||
|  |  | ||||||
|  | 			if( h !== indexh || v !== indexv ) { | ||||||
| 				slide( h, v ); | 				slide( h, v ); | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1888,8 +2081,9 @@ var Reveal = (function(){ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if( !slide && currentSlide ) { | 		if( !slide && currentSlide ) { | ||||||
|  | 			var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0; | ||||||
|  | 			if( hasFragments ) { | ||||||
| 				var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' ); | 				var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' ); | ||||||
| 			if( visibleFragments.length ) { |  | ||||||
| 				f = visibleFragments.length; | 				f = visibleFragments.length; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -2119,7 +2313,7 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 					var value = config.keyboard[ key ]; | 					var value = config.keyboard[ key ]; | ||||||
|  |  | ||||||
| 					// Calback function | 					// Callback function | ||||||
| 					if( typeof value === 'function' ) { | 					if( typeof value === 'function' ) { | ||||||
| 						value.apply( null, [ event ] ); | 						value.apply( null, [ event ] ); | ||||||
| 					} | 					} | ||||||
| @@ -2178,7 +2372,8 @@ var Reveal = (function(){ | |||||||
| 		if( triggered ) { | 		if( triggered ) { | ||||||
| 			event.preventDefault(); | 			event.preventDefault(); | ||||||
| 		} | 		} | ||||||
| 		else if ( event.keyCode === 27 && supports3DTransforms ) { | 		// ESC or O key | ||||||
|  | 		else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && supports3DTransforms ) { | ||||||
| 			toggleOverview(); | 			toggleOverview(); | ||||||
|  |  | ||||||
| 			event.preventDefault(); | 			event.preventDefault(); | ||||||
| @@ -2220,11 +2415,11 @@ var Reveal = (function(){ | |||||||
| 	function onTouchMove( event ) { | 	function onTouchMove( event ) { | ||||||
|  |  | ||||||
| 		// Each touch should only trigger one action | 		// Each touch should only trigger one action | ||||||
| 		if( !touch.handled ) { | 		if( !touch.captured ) { | ||||||
| 			var currentX = event.touches[0].clientX; | 			var currentX = event.touches[0].clientX; | ||||||
| 			var currentY = event.touches[0].clientY; | 			var currentY = event.touches[0].clientY; | ||||||
|  |  | ||||||
| 			// If the touch started off with two points and still has | 			// If the touch started with two points and still has | ||||||
| 			// two active touches; test for the pinch gesture | 			// two active touches; test for the pinch gesture | ||||||
| 			if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) { | 			if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) { | ||||||
|  |  | ||||||
| @@ -2240,7 +2435,7 @@ var Reveal = (function(){ | |||||||
| 				// If the span is larger than the desire amount we've got | 				// If the span is larger than the desire amount we've got | ||||||
| 				// ourselves a pinch | 				// ourselves a pinch | ||||||
| 				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) { | 				if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) { | ||||||
| 					touch.handled = true; | 					touch.captured = true; | ||||||
|  |  | ||||||
| 					if( currentSpan < touch.startSpan ) { | 					if( currentSpan < touch.startSpan ) { | ||||||
| 						activateOverview(); | 						activateOverview(); | ||||||
| @@ -2260,23 +2455,34 @@ var Reveal = (function(){ | |||||||
| 					deltaY = currentY - touch.startY; | 					deltaY = currentY - touch.startY; | ||||||
|  |  | ||||||
| 				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { | 				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { | ||||||
| 					touch.handled = true; | 					touch.captured = true; | ||||||
| 					navigateLeft(); | 					navigateLeft(); | ||||||
| 				} | 				} | ||||||
| 				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { | 				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { | ||||||
| 					touch.handled = true; | 					touch.captured = true; | ||||||
| 					navigateRight(); | 					navigateRight(); | ||||||
| 				} | 				} | ||||||
| 				else if( deltaY > touch.threshold ) { | 				else if( deltaY > touch.threshold ) { | ||||||
| 					touch.handled = true; | 					touch.captured = true; | ||||||
| 					navigateUp(); | 					navigateUp(); | ||||||
| 				} | 				} | ||||||
| 				else if( deltaY < -touch.threshold ) { | 				else if( deltaY < -touch.threshold ) { | ||||||
| 					touch.handled = true; | 					touch.captured = true; | ||||||
| 					navigateDown(); | 					navigateDown(); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				// If we're embedded, only block touch events if they have | ||||||
|  | 				// triggered an action | ||||||
|  | 				if( config.embedded ) { | ||||||
|  | 					if( touch.captured || isVerticalSlide( currentSlide ) ) { | ||||||
| 						event.preventDefault(); | 						event.preventDefault(); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				// Not embedded? Block them all to avoid needless tossing | ||||||
|  | 				// around of the viewport in iOS | ||||||
|  | 				else { | ||||||
|  | 					event.preventDefault(); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -2293,7 +2499,7 @@ var Reveal = (function(){ | |||||||
| 	 */ | 	 */ | ||||||
| 	function onTouchEnd( event ) { | 	function onTouchEnd( event ) { | ||||||
|  |  | ||||||
| 		touch.handled = false; | 		touch.captured = false; | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2553,12 +2759,22 @@ var Reveal = (function(){ | |||||||
|  |  | ||||||
| 		// Returns true if we're currently on the last slide | 		// Returns true if we're currently on the last slide | ||||||
| 		isLastSlide: function() { | 		isLastSlide: function() { | ||||||
| 			if( currentSlide && currentSlide.classList.contains( '.stack' ) ) { | 			if( currentSlide ) { | ||||||
| 				return currentSlide.querySelector( SLIDES_SELECTOR + '.future' ) == null ? true : false; | 				// Does this slide has next a sibling? | ||||||
| 			} | 				if( currentSlide.nextElementSibling ) return false; | ||||||
| 			else { |  | ||||||
| 				return document.querySelector( SLIDES_SELECTOR + '.future' ) == null ? true : false; | 				// If it's vertical, does its parent have a next sibling? | ||||||
|  | 				if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false; | ||||||
|  |  | ||||||
|  | 				return true; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		// Checks if reveal.js has been loaded and is ready for use | ||||||
|  | 		isReady: function() { | ||||||
|  | 			return loaded; | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		// Forward event binding to the reveal DOM element | 		// Forward event binding to the reveal DOM element | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,11 +1,11 @@ | |||||||
| { | { | ||||||
|   "name": "reveal.js", |   "name": "reveal.js", | ||||||
|   "version": "2.5.0", |   "version": "2.6.0-dev", | ||||||
|   "description": "The HTML Presentation Framework", |   "description": "The HTML Presentation Framework", | ||||||
|   "homepage": "http://lab.hakim.se/reveal-js", |   "homepage": "http://lab.hakim.se/reveal-js", | ||||||
|   "subdomain": "revealjs", |   "subdomain": "revealjs", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "test": "grunt jshint", |     "test": "grunt test", | ||||||
|     "start": "" |     "start": "" | ||||||
|   }, |   }, | ||||||
|   "author": { |   "author": { | ||||||
| @@ -27,6 +27,7 @@ | |||||||
|     "socket.io": "~0.9.13" |     "socket.io": "~0.9.13" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "grunt-contrib-qunit": "~0.2.2", | ||||||
|     "grunt-contrib-jshint": "~0.2.0", |     "grunt-contrib-jshint": "~0.2.0", | ||||||
|     "grunt-contrib-cssmin": "~0.4.1", |     "grunt-contrib-cssmin": "~0.4.1", | ||||||
|     "grunt-contrib-uglify": "~0.1.1", |     "grunt-contrib-uglify": "~0.1.1", | ||||||
|   | |||||||
| @@ -48,6 +48,9 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re | |||||||
|  |  | ||||||
|       pointer.id = 'leap'; |       pointer.id = 'leap'; | ||||||
|  |  | ||||||
|  |       pointer.style.position        = 'absolute'; | ||||||
|  |       pointer.style.visibility      = 'hidden'; | ||||||
|  |       pointer.style.zIndex          = 50; | ||||||
|       pointer.style.opacity         = config.pointerOpacity; |       pointer.style.opacity         = config.pointerOpacity; | ||||||
|       pointer.style.backgroundColor = config.pointerColor; |       pointer.style.backgroundColor = config.pointerColor; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
|  |  | ||||||
| 			<div class="slides"> | 			<div class="slides"> | ||||||
|  |  | ||||||
|                 <!-- Use external markdown resource, and separate slides by three newlines; vertical slides by two newlines --> |                 <!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines --> | ||||||
|                 <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> |                 <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> | ||||||
|  |  | ||||||
|                 <!-- Slides are separated by three dashes (quick 'n dirty regular expression) --> |                 <!-- Slides are separated by three dashes (quick 'n dirty regular expression) --> | ||||||
| @@ -87,7 +87,8 @@ | |||||||
| 				dependencies: [ | 				dependencies: [ | ||||||
| 					{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } }, | 					{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } }, | ||||||
| 					{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, | 					{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, | ||||||
| 					{ src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } } |                     { src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, | ||||||
|  | 					{ src: '../notes/notes.js' } | ||||||
| 				] | 				] | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ | |||||||
|  |  | ||||||
| Content 1.1 | Content 1.1 | ||||||
|  |  | ||||||
|  | Note: This will only appear in the speaker notes window. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## External 1.2 | ## External 1.2 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,12 +1,27 @@ | |||||||
| // From https://gist.github.com/1343518 | /** | ||||||
| // Modified by Hakim to handle Markdown indented with tabs |  * The reveal.js markdown plugin. Handles parsing of | ||||||
|  |  * markdown inside of presentations as well as loading | ||||||
|  |  * of external markdown documents. | ||||||
|  |  */ | ||||||
| (function(){ | (function(){ | ||||||
|  |  | ||||||
| 	if( typeof marked === 'undefined' ) { | 	if( typeof marked === 'undefined' ) { | ||||||
| 		throw 'The reveal.js Markdown plugin requires marked to be loaded'; | 		throw 'The reveal.js Markdown plugin requires marked to be loaded'; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     var stripLeadingWhitespace = function(section) { | 	if( typeof hljs !== 'undefined' ) { | ||||||
|  | 		marked.setOptions({ | ||||||
|  | 			highlight: function( lang, code ) { | ||||||
|  | 				return hljs.highlightAuto( lang, code ).value; | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Retrieves the markdown contents of a slide section | ||||||
|  | 	 * element. Normalizes leading tabs/whitespace. | ||||||
|  | 	 */ | ||||||
|  | 	function getMarkdownFromSlide( section ) { | ||||||
|  |  | ||||||
| 		var template = section.querySelector( 'script' ); | 		var template = section.querySelector( 'script' ); | ||||||
|  |  | ||||||
| @@ -25,13 +40,16 @@ | |||||||
|  |  | ||||||
| 		return text; | 		return text; | ||||||
|  |  | ||||||
|     }; | 	} | ||||||
|  |  | ||||||
|     var twrap = function(el) { | 	/** | ||||||
|       return '<script type="text/template">' + el + '</script>'; | 	 * 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 getForwardedAttributes = function(section) { |  | ||||||
| 		var attributes = section.attributes; | 		var attributes = section.attributes; | ||||||
| 		var result = []; | 		var result = []; | ||||||
|  |  | ||||||
| @@ -40,7 +58,7 @@ | |||||||
| 				value = attributes[i].value; | 				value = attributes[i].value; | ||||||
|  |  | ||||||
| 			// disregard attributes that are used for markdown loading/parsing | 			// disregard attributes that are used for markdown loading/parsing | ||||||
|             if( /data\-(markdown|separator|vertical)/gi.test( name ) ) continue; | 			if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue; | ||||||
|  |  | ||||||
| 			if( value ) { | 			if( value ) { | ||||||
| 				result.push( name + '=' + value ); | 				result.push( name + '=' + value ); | ||||||
| @@ -51,27 +69,55 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return result.join( ' ' ); | 		return result.join( ' ' ); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     var slidifyMarkdown = function(markdown, separator, vertical, attributes) { | 	/** | ||||||
|  | 	 * Helper function for constructing a markdown slide. | ||||||
|  | 	 */ | ||||||
|  | 	function createMarkdownSlide( data ) { | ||||||
|  |  | ||||||
|         separator = separator || '^\n---\n$'; | 		var content = data.content || data; | ||||||
|  |  | ||||||
|         var reSeparator = new RegExp(separator + (vertical ? '|' + vertical : ''), 'mg'), | 		if( data.notes ) { | ||||||
|             reHorSeparator = new RegExp(separator), | 			content += '<aside class="notes" data-markdown>' + data.notes + '</aside>'; | ||||||
|             matches, | 		} | ||||||
|  |  | ||||||
|  | 		return '<script type="text/template">' + content + '</script>'; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Parses a data string into multiple slides based | ||||||
|  | 	 * on the passed in separator arguments. | ||||||
|  | 	 */ | ||||||
|  | 	function slidifyMarkdown( markdown, options ) { | ||||||
|  |  | ||||||
|  | 		options = options || {}; | ||||||
|  | 		options.separator = options.separator || '^\n---\n$'; | ||||||
|  | 		options.notesSeparator = options.notesSeparator || 'note:'; | ||||||
|  | 		options.attributes = options.attributes || ''; | ||||||
|  |  | ||||||
|  | 		var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ), | ||||||
|  | 			horizontalSeparatorRegex = new RegExp( options.separator ), | ||||||
|  | 			notesSeparatorRegex = new RegExp( options.notesSeparator, 'mgi' ); | ||||||
|  |  | ||||||
|  | 		var matches, | ||||||
|  | 			noteMatch, | ||||||
| 			lastIndex = 0, | 			lastIndex = 0, | ||||||
| 			isHorizontal, | 			isHorizontal, | ||||||
| 			wasHorizontal = true, | 			wasHorizontal = true, | ||||||
| 			content, | 			content, | ||||||
|             sectionStack = [], | 			notes, | ||||||
|             markdownSections = ''; | 			slide, | ||||||
|  | 			sectionStack = []; | ||||||
|  |  | ||||||
| 		// iterate until all blocks between separators are stacked up | 		// iterate until all blocks between separators are stacked up | ||||||
|         while( matches = reSeparator.exec(markdown) ) { | 		while( matches = separatorRegex.exec( markdown ) ) { | ||||||
|  | 			notes = null; | ||||||
|  |  | ||||||
| 			// determine direction (horizontal by default) | 			// determine direction (horizontal by default) | ||||||
|             isHorizontal = reHorSeparator.test(matches[0]); | 			isHorizontal = horizontalSeparatorRegex.test( matches[0] ); | ||||||
|  |  | ||||||
| 			if( !isHorizontal && wasHorizontal ) { | 			if( !isHorizontal && wasHorizontal ) { | ||||||
| 				// create vertical stack | 				// create vertical stack | ||||||
| @@ -80,111 +126,146 @@ | |||||||
|  |  | ||||||
| 			// pluck slide content from markdown input | 			// pluck slide content from markdown input | ||||||
| 			content = markdown.substring( lastIndex, matches.index ); | 			content = markdown.substring( lastIndex, matches.index ); | ||||||
|  | 			noteMatch = content.split( notesSeparatorRegex ); | ||||||
|  |  | ||||||
|  | 			if( noteMatch.length === 2 ) { | ||||||
|  | 				content = noteMatch[0]; | ||||||
|  | 				notes = noteMatch[1].trim(); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			slide = { | ||||||
|  | 				content: content, | ||||||
|  | 				notes: notes || '' | ||||||
|  | 			}; | ||||||
|  |  | ||||||
| 			if( isHorizontal && wasHorizontal ) { | 			if( isHorizontal && wasHorizontal ) { | ||||||
| 				// add to horizontal stack | 				// add to horizontal stack | ||||||
|                 sectionStack.push(content); | 				sectionStack.push( slide ); | ||||||
|             } else { | 			} | ||||||
|  | 			else { | ||||||
| 				// add to vertical stack | 				// add to vertical stack | ||||||
|                 sectionStack[sectionStack.length-1].push(content); | 				sectionStack[sectionStack.length-1].push( slide ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|             lastIndex = reSeparator.lastIndex; | 			lastIndex = separatorRegex.lastIndex; | ||||||
| 			wasHorizontal = isHorizontal; | 			wasHorizontal = isHorizontal; | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// add the remaining slide | 		// add the remaining slide | ||||||
| 		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) ); | 		( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) ); | ||||||
|  |  | ||||||
|  | 		var markdownSections = ''; | ||||||
|  |  | ||||||
| 		// flatten the hierarchical stack, and insert <section data-markdown> tags | 		// flatten the hierarchical stack, and insert <section data-markdown> tags | ||||||
|         for( var k = 0, klen = sectionStack.length; k < klen; k++ ) { | 		for( var i = 0, len = sectionStack.length; i < len; i++ ) { | ||||||
|             // horizontal |  | ||||||
|             if( typeof sectionStack[k] === 'string' ) { |  | ||||||
|                 markdownSections += '<section '+ attributes +' data-markdown>' +  twrap( sectionStack[k] )  + '</section>'; |  | ||||||
|             } |  | ||||||
| 			// vertical | 			// vertical | ||||||
|             else { | 			if( sectionStack[i].propertyIsEnumerable( length ) && typeof sectionStack[i].splice === 'function' ) { | ||||||
|                 markdownSections += '<section '+ attributes +'>' + | 				markdownSections += '<section '+ options.attributes +'>' + | ||||||
|                                         '<section data-markdown>' +  sectionStack[k].map(twrap).join('</section><section data-markdown>') + '</section>' + | 										'<section data-markdown>' +  sectionStack[i].map( createMarkdownSlide ).join( '</section><section data-markdown>' ) + '</section>' + | ||||||
| 									'</section>'; | 									'</section>'; | ||||||
| 			} | 			} | ||||||
|  | 			else { | ||||||
|  | 				markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i] ) + '</section>'; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return markdownSections; | 		return markdownSections; | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     var querySlidingMarkdown = function() { | 	} | ||||||
|  |  | ||||||
|  | 	function loadExternalMarkdown() { | ||||||
|  |  | ||||||
| 		var sections = document.querySelectorAll( '[data-markdown]'), | 		var sections = document.querySelectorAll( '[data-markdown]'), | ||||||
| 			section; | 			section; | ||||||
|  |  | ||||||
|         for( var j = 0, jlen = sections.length; j < jlen; j++ ) { | 		for( var i = 0, len = sections.length; i < len; i++ ) { | ||||||
|  |  | ||||||
|             section = sections[j]; | 			section = sections[i]; | ||||||
|  |  | ||||||
| 			if( section.getAttribute( 'data-markdown' ).length ) { | 			if( section.getAttribute( 'data-markdown' ).length ) { | ||||||
|  |  | ||||||
| 				var xhr = new XMLHttpRequest(), | 				var xhr = new XMLHttpRequest(), | ||||||
| 					url = section.getAttribute( 'data-markdown' ); | 					url = section.getAttribute( 'data-markdown' ); | ||||||
|  |  | ||||||
|  | 				datacharset = section.getAttribute( 'data-charset' ); | ||||||
|  |  | ||||||
|  | 				// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes | ||||||
|  | 				if( datacharset != null && datacharset != '' ) { | ||||||
|  | 					xhr.overrideMimeType( 'text/html; charset=' + datacharset ); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				xhr.onreadystatechange = function() { | 				xhr.onreadystatechange = function() { | ||||||
| 					if( xhr.readyState === 4 ) { | 					if( xhr.readyState === 4 ) { | ||||||
| 						if ( xhr.status >= 200 && xhr.status < 300 ) { | 						if ( xhr.status >= 200 && xhr.status < 300 ) { | ||||||
|                             section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), getForwardedAttributes(section) ); |  | ||||||
|                         } else { | 							section.outerHTML = slidifyMarkdown( xhr.responseText, { | ||||||
|                             section.outerHTML = '<section data-state="alert">ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status + | 								separator: section.getAttribute( 'data-separator' ), | ||||||
|                                 '. Check your browser\'s JavaScript console for more details.' + | 								verticalSeparator: section.getAttribute( 'data-vertical' ), | ||||||
|                                 '<p>Remember that you need to serve the presentation HTML from a HTTP server and the Markdown file must be there too.</p></section>'; | 								notesSeparator: section.getAttribute( 'data-notes' ), | ||||||
|  | 								attributes: getForwardedAttributes( section ) | ||||||
|  | 							}); | ||||||
|  |  | ||||||
|  | 						} | ||||||
|  | 						else { | ||||||
|  |  | ||||||
|  | 							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>'; | ||||||
|  |  | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				}; | 				}; | ||||||
|  |  | ||||||
| 				xhr.open( 'GET', url, false ); | 				xhr.open( 'GET', url, false ); | ||||||
|  |  | ||||||
| 				try { | 				try { | ||||||
| 					xhr.send(); | 					xhr.send(); | ||||||
|                 } catch (e) { | 				} | ||||||
|  | 				catch ( e ) { | ||||||
| 					alert( '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 ); | 					alert( '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 ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|             } else if( section.getAttribute('data-separator') ) { | 			} | ||||||
|  | 			else if( section.getAttribute( 'data-separator' ) ) { | ||||||
|  |  | ||||||
|                 var markdown = stripLeadingWhitespace(section); | 				section.outerHTML = slidifyMarkdown( getMarkdownFromSlide( section ), { | ||||||
|                 section.outerHTML = slidifyMarkdown( markdown, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), getForwardedAttributes(section) ); | 					separator: section.getAttribute( 'data-separator' ), | ||||||
|  | 					verticalSeparator: section.getAttribute( 'data-vertical' ), | ||||||
|  | 					notesSeparator: section.getAttribute( 'data-notes' ), | ||||||
|  | 					attributes: getForwardedAttributes( section ) | ||||||
|  | 				}); | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|     }; | 	} | ||||||
|  |  | ||||||
|     var queryMarkdownSlides = function() { | 	function convertMarkdownToHTML() { | ||||||
|  |  | ||||||
| 		var sections = document.querySelectorAll( '[data-markdown]'); | 		var sections = document.querySelectorAll( '[data-markdown]'); | ||||||
|  |  | ||||||
|         for( var j = 0, jlen = sections.length; j < jlen; j++ ) { | 		for( var i = 0, len = sections.length; i < len; i++ ) { | ||||||
|  |  | ||||||
|             makeHtml(sections[j]); | 			var section = sections[i]; | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     var makeHtml = function(section) { |  | ||||||
|  |  | ||||||
| 			var notes = section.querySelector( 'aside.notes' ); | 			var notes = section.querySelector( 'aside.notes' ); | ||||||
|  | 			var markdown = getMarkdownFromSlide( section ); | ||||||
|         var markdown = stripLeadingWhitespace(section); |  | ||||||
|  |  | ||||||
| 			section.innerHTML = marked( markdown ); | 			section.innerHTML = marked( markdown ); | ||||||
|  |  | ||||||
|  | 			// If there were notes, we need to re-add them after | ||||||
|  | 			// having overwritten the section's HTML | ||||||
| 			if( notes ) { | 			if( notes ) { | ||||||
| 				section.appendChild( notes ); | 				section.appendChild( notes ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|     }; | 		} | ||||||
|  |  | ||||||
|     querySlidingMarkdown(); | 	} | ||||||
|  |  | ||||||
|     queryMarkdownSlides(); | 	loadExternalMarkdown(); | ||||||
|  | 	convertMarkdownToHTML(); | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								plugin/math/math.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										64
									
								
								plugin/math/math.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | /** | ||||||
|  |  * A plugin which enables rendering of math equations inside | ||||||
|  |  * of reveal.js slides. Essentially a thin wrapper for MathJax. | ||||||
|  |  * | ||||||
|  |  * @author Hakim El Hattab | ||||||
|  |  */ | ||||||
|  | var RevealMath = window.RevealMath || (function(){ | ||||||
|  |  | ||||||
|  | 	var options = Reveal.getConfig().math || {}; | ||||||
|  | 	options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js'; | ||||||
|  | 	options.config = options.config || 'TeX-AMS_HTML-full'; | ||||||
|  |  | ||||||
|  | 	loadScript( options.mathjax + '?config=' + options.config, function() { | ||||||
|  |  | ||||||
|  | 		MathJax.Hub.Config({ | ||||||
|  | 			messageStyle: 'none', | ||||||
|  | 			tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }, | ||||||
|  | 			skipStartupTypeset: true | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		// 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( Reveal.layout ); | ||||||
|  |  | ||||||
|  | 		// Reprocess equations in slides when they turn visible | ||||||
|  | 		Reveal.addEventListener( 'slidechanged', function( event ) { | ||||||
|  |  | ||||||
|  | 			MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); | ||||||
|  |  | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
|  | 	} ); | ||||||
|  |  | ||||||
|  | 	function loadScript( url, callback ) { | ||||||
|  |  | ||||||
|  | 		var head = document.querySelector( 'head' ); | ||||||
|  | 		var script = document.createElement( 'script' ); | ||||||
|  | 		script.type = 'text/javascript'; | ||||||
|  | 		script.src = url; | ||||||
|  |  | ||||||
|  | 		// Wrapper for callback to make sure it only fires once | ||||||
|  | 		var finish = function() { | ||||||
|  | 			if( typeof callback === 'function' ) { | ||||||
|  | 				callback.call(); | ||||||
|  | 				callback = null; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		script.onload = finish; | ||||||
|  |  | ||||||
|  | 		// IE | ||||||
|  | 		script.onreadystatechange = function() { | ||||||
|  | 			if ( this.readyState === 'loaded' ) { | ||||||
|  | 				finish(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Normal browsers | ||||||
|  | 		head.appendChild( script ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | })(); | ||||||
| @@ -169,10 +169,12 @@ | |||||||
|  |  | ||||||
| 					var notes = document.getElementById( 'notes' ), | 					var notes = document.getElementById( 'notes' ), | ||||||
| 						currentSlide = document.getElementById( 'current-slide' ), | 						currentSlide = document.getElementById( 'current-slide' ), | ||||||
| 						nextSlide = document.getElementById( 'next-slide' ); | 						nextSlide = document.getElementById( 'next-slide' ), | ||||||
|  | 						silenced = false; | ||||||
|  |  | ||||||
| 					window.addEventListener( 'message', function( event ) { | 					window.addEventListener( 'message', function( event ) { | ||||||
| 						var data = JSON.parse( event.data ); | 						var data = JSON.parse( event.data ); | ||||||
|  |  | ||||||
| 						// No need for updating the notes in case of fragment changes | 						// No need for updating the notes in case of fragment changes | ||||||
| 						if ( data.notes !== undefined) { | 						if ( data.notes !== undefined) { | ||||||
| 							if( data.markdown ) { | 							if( data.markdown ) { | ||||||
| @@ -183,18 +185,13 @@ | |||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						// Showing and hiding fragments | 						silenced = true; | ||||||
| 						if( data.fragment === 'next' ) { |  | ||||||
| 							currentSlide.contentWindow.Reveal.nextFragment(); |  | ||||||
| 						} |  | ||||||
| 						else if( data.fragment === 'prev' ) { |  | ||||||
| 							currentSlide.contentWindow.Reveal.prevFragment(); |  | ||||||
| 						} |  | ||||||
| 						else { |  | ||||||
| 						// Update the note slides | 						// Update the note slides | ||||||
| 							currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv ); | 						currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv, data.indexf ); | ||||||
| 						nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv ); | 						nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv ); | ||||||
| 						} |  | ||||||
|  | 						silenced = false; | ||||||
|  |  | ||||||
| 					}, false ); | 					}, false ); | ||||||
|  |  | ||||||
| @@ -226,12 +223,21 @@ | |||||||
|  |  | ||||||
| 					}, 1000 ); | 					}, 1000 ); | ||||||
|  |  | ||||||
|  | 					// Broadcasts the state of the notes window to synchronize | ||||||
|  | 					// the main window | ||||||
|  | 					function synchronizeMainWindow() { | ||||||
|  |  | ||||||
|  | 						if( !silenced ) { | ||||||
|  | 							var indices = currentSlide.contentWindow.Reveal.getIndices(); | ||||||
|  | 							window.opener.Reveal.slide( indices.h, indices.v, indices.f ); | ||||||
|  | 						} | ||||||
|  |  | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 					// Navigate the main window when the notes slide changes | 					// Navigate the main window when the notes slide changes | ||||||
| 					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', function( event ) { | 					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', synchronizeMainWindow ); | ||||||
|  | 					currentSlide.contentWindow.Reveal.addEventListener( 'fragmentshown', synchronizeMainWindow ); | ||||||
| 						window.opener.Reveal.slide( event.indexh, event.indexv ); | 					currentSlide.contentWindow.Reveal.addEventListener( 'fragmenthidden', synchronizeMainWindow ); | ||||||
|  |  | ||||||
| 					} ); |  | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
| 				else { | 				else { | ||||||
|   | |||||||
| @@ -10,72 +10,50 @@ var RevealNotes = (function() { | |||||||
| 		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' ); | 		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' ); | ||||||
|  |  | ||||||
| 		// Fires when slide is changed | 		// Fires when slide is changed | ||||||
| 		Reveal.addEventListener( 'slidechanged', function( event ) { | 		Reveal.addEventListener( 'slidechanged', post ); | ||||||
| 			post('slidechanged'); |  | ||||||
| 		} ); |  | ||||||
|  |  | ||||||
| 		// Fires when a fragment is shown | 		// Fires when a fragment is shown | ||||||
| 		Reveal.addEventListener( 'fragmentshown', function( event ) { | 		Reveal.addEventListener( 'fragmentshown', post ); | ||||||
| 			post('fragmentshown'); |  | ||||||
| 		} ); |  | ||||||
|  |  | ||||||
| 		// Fires when a fragment is hidden | 		// Fires when a fragment is hidden | ||||||
| 		Reveal.addEventListener( 'fragmenthidden', function( event ) { | 		Reveal.addEventListener( 'fragmenthidden', post ); | ||||||
| 			post('fragmenthidden'); |  | ||||||
| 		} ); |  | ||||||
|  |  | ||||||
| 		/** | 		/** | ||||||
| 		 * Posts the current slide data to the notes window | 		 * Posts the current slide data to the notes window | ||||||
| 		 * |  | ||||||
| 		 * @param {String} eventType Expecting 'slidechanged', 'fragmentshown'  |  | ||||||
| 		 * or 'fragmenthidden' set in the events above to define the needed  |  | ||||||
| 		 * slideDate. |  | ||||||
| 		 */ | 		 */ | ||||||
| 		function post( eventType ) { | 		function post() { | ||||||
| 			var slideElement = Reveal.getCurrentSlide(), | 			var slideElement = Reveal.getCurrentSlide(), | ||||||
|  | 				slideIndices = Reveal.getIndices(), | ||||||
| 				messageData; | 				messageData; | ||||||
|  |  | ||||||
| 			if( eventType === 'slidechanged' ) { |  | ||||||
| 			var notes = slideElement.querySelector( 'aside.notes' ), | 			var notes = slideElement.querySelector( 'aside.notes' ), | ||||||
| 					indexh = Reveal.getIndices().h, |  | ||||||
| 					indexv = Reveal.getIndices().v, |  | ||||||
| 				nextindexh, | 				nextindexh, | ||||||
| 				nextindexv; | 				nextindexv; | ||||||
|  |  | ||||||
| 			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) { | 			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) { | ||||||
| 					nextindexh = indexh; | 				nextindexh = slideIndices.h; | ||||||
| 					nextindexv = indexv + 1; | 				nextindexv = slideIndices.v + 1; | ||||||
| 			} else { | 			} else { | ||||||
| 					nextindexh = indexh + 1; | 				nextindexh = slideIndices.h + 1; | ||||||
| 				nextindexv = 0; | 				nextindexv = 0; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			messageData = { | 			messageData = { | ||||||
| 				notes : notes ? notes.innerHTML : '', | 				notes : notes ? notes.innerHTML : '', | ||||||
| 					indexh : indexh, | 				indexh : slideIndices.h, | ||||||
| 					indexv : indexv, | 				indexv : slideIndices.v, | ||||||
|  | 				indexf : slideIndices.f, | ||||||
| 				nextindexh : nextindexh, | 				nextindexh : nextindexh, | ||||||
| 				nextindexv : nextindexv, | 				nextindexv : nextindexv, | ||||||
| 				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false | 				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false | ||||||
| 			}; | 			}; | ||||||
| 			} |  | ||||||
| 			else if( eventType === 'fragmentshown' ) { |  | ||||||
| 				messageData = { |  | ||||||
| 					fragment : 'next' |  | ||||||
| 				}; |  | ||||||
| 			} |  | ||||||
| 			else if( eventType === 'fragmenthidden' ) { |  | ||||||
| 				messageData = { |  | ||||||
| 					fragment : 'prev' |  | ||||||
| 				}; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			notesPopup.postMessage( JSON.stringify( messageData ), '*' ); | 			notesPopup.postMessage( JSON.stringify( messageData ), '*' ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Navigate to the current slide when the notes are loaded | 		// Navigate to the current slide when the notes are loaded | ||||||
| 		notesPopup.addEventListener( 'load', function( event ) { | 		notesPopup.addEventListener( 'load', function( event ) { | ||||||
| 			post('slidechanged'); | 			post(); | ||||||
| 		}, false ); | 		}, false ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB | 
| Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB | 
| @@ -6,7 +6,7 @@ | |||||||
| 
 | 
 | ||||||
| 		<title>reveal.js - Barebones</title> | 		<title>reveal.js - Barebones</title> | ||||||
| 
 | 
 | ||||||
| 		<link rel="stylesheet" href="../css/reveal.min.css"> | 		<link rel="stylesheet" href="../../css/reveal.min.css"> | ||||||
| 	</head> | 	</head> | ||||||
| 
 | 
 | ||||||
| 	<body> | 	<body> | ||||||
| @@ -29,8 +29,8 @@ | |||||||
| 
 | 
 | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<script src="../lib/js/head.min.js"></script> | 		<script src="../../lib/js/head.min.js"></script> | ||||||
| 		<script src="../js/reveal.min.js"></script> | 		<script src="../../js/reveal.min.js"></script> | ||||||
| 
 | 
 | ||||||
| 		<script> | 		<script> | ||||||
| 
 | 
 | ||||||
| @@ -8,8 +8,8 @@ | |||||||
| 
 | 
 | ||||||
| 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | ||||||
| 
 | 
 | ||||||
| 		<link rel="stylesheet" href="../css/reveal.min.css"> | 		<link rel="stylesheet" href="../../css/reveal.min.css"> | ||||||
| 		<link rel="stylesheet" href="../css/theme/default.css" id="theme"> | 		<link rel="stylesheet" href="../../css/theme/default.css" id="theme"> | ||||||
| 	</head> | 	</head> | ||||||
| 
 | 
 | ||||||
| 	<body> | 	<body> | ||||||
| @@ -34,8 +34,8 @@ | |||||||
| 
 | 
 | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<script src="../lib/js/head.min.js"></script> | 		<script src="../../lib/js/head.min.js"></script> | ||||||
| 		<script src="../js/reveal.min.js"></script> | 		<script src="../../js/reveal.min.js"></script> | ||||||
| 
 | 
 | ||||||
| 		<script> | 		<script> | ||||||
| 
 | 
 | ||||||
							
								
								
									
										185
									
								
								test/examples/math.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								test/examples/math.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  |  | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="utf-8"> | ||||||
|  |  | ||||||
|  | 		<title>reveal.js - Math Plugin</title> | ||||||
|  |  | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | ||||||
|  |  | ||||||
|  | 		<link rel="stylesheet" href="../../css/reveal.min.css"> | ||||||
|  | 		<link rel="stylesheet" href="../../css/theme/night.css" id="theme"> | ||||||
|  | 	</head> | ||||||
|  |  | ||||||
|  | 	<body> | ||||||
|  |  | ||||||
|  | 		<div class="reveal"> | ||||||
|  |  | ||||||
|  | 			<div class="slides"> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h2>reveal.js Math Plugin</h2> | ||||||
|  | 					<p>A thin wrapper for MathJax</p> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>The Lorenz Equations</h3> | ||||||
|  |  | ||||||
|  | 					\[\begin{aligned} | ||||||
|  | 					\dot{x} & = \sigma(y-x) \\ | ||||||
|  | 					\dot{y} & = \rho x - y - xz \\ | ||||||
|  | 					\dot{z} & = -\beta z + xy | ||||||
|  | 					\end{aligned} \] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>The Cauchy-Schwarz Inequality</h3> | ||||||
|  |  | ||||||
|  | 					<script type="math/tex; mode=display"> | ||||||
|  | 						\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) | ||||||
|  | 					</script> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>A Cross Product Formula</h3> | ||||||
|  |  | ||||||
|  | 					\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix} | ||||||
|  | 					\mathbf{i} & \mathbf{j} & \mathbf{k} \\ | ||||||
|  | 					\frac{\partial X}{\partial u} &  \frac{\partial Y}{\partial u} & 0 \\ | ||||||
|  | 					\frac{\partial X}{\partial v} &  \frac{\partial Y}{\partial v} & 0 | ||||||
|  | 					\end{vmatrix}  \] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3> | ||||||
|  |  | ||||||
|  | 					\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>An Identity of Ramanujan</h3> | ||||||
|  |  | ||||||
|  | 					\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = | ||||||
|  | 					1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} | ||||||
|  | 					{1+\frac{e^{-8\pi}} {1+\ldots} } } } \] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>A Rogers-Ramanujan Identity</h3> | ||||||
|  |  | ||||||
|  | 					\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots = | ||||||
|  | 					\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h3>Maxwell’s Equations</h3> | ||||||
|  |  | ||||||
|  | 					\[  \begin{aligned} | ||||||
|  | 					\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ | ||||||
|  | 					\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ | ||||||
|  | 					\nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned} | ||||||
|  | 					\] | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<section> | ||||||
|  | 						<h3>The Lorenz Equations</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[\begin{aligned} | ||||||
|  | 							\dot{x} & = \sigma(y-x) \\ | ||||||
|  | 							\dot{y} & = \rho x - y - xz \\ | ||||||
|  | 							\dot{z} & = -\beta z + xy | ||||||
|  | 							\end{aligned} \] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>The Cauchy-Schwarz Inequality</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>A Cross Product Formula</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix} | ||||||
|  | 							\mathbf{i} & \mathbf{j} & \mathbf{k} \\ | ||||||
|  | 							\frac{\partial X}{\partial u} &  \frac{\partial Y}{\partial u} & 0 \\ | ||||||
|  | 							\frac{\partial X}{\partial v} &  \frac{\partial Y}{\partial v} & 0 | ||||||
|  | 							\end{vmatrix}  \] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>An Identity of Ramanujan</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = | ||||||
|  | 							1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} | ||||||
|  | 							{1+\frac{e^{-8\pi}} {1+\ldots} } } } \] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>A Rogers-Ramanujan Identity</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[  1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots = | ||||||
|  | 							\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  |  | ||||||
|  | 					<section> | ||||||
|  | 						<h3>Maxwell’s Equations</h3> | ||||||
|  |  | ||||||
|  | 						<div class="fragment"> | ||||||
|  | 							\[  \begin{aligned} | ||||||
|  | 							\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ | ||||||
|  | 							\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ | ||||||
|  | 							\nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned} | ||||||
|  | 							\] | ||||||
|  | 						</div> | ||||||
|  | 					</section> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 			</div> | ||||||
|  |  | ||||||
|  | 		</div> | ||||||
|  |  | ||||||
|  | 		<script src="../../lib/js/head.min.js"></script> | ||||||
|  | 		<script src="../../js/reveal.min.js"></script> | ||||||
|  |  | ||||||
|  | 		<script> | ||||||
|  |  | ||||||
|  | 			Reveal.initialize({ | ||||||
|  | 				history: true, | ||||||
|  | 				transition: 'linear', | ||||||
|  |  | ||||||
|  | 				math: { | ||||||
|  | 					// mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js', | ||||||
|  | 					config: 'TeX-AMS_HTML-full' | ||||||
|  | 				}, | ||||||
|  |  | ||||||
|  | 				dependencies: [ | ||||||
|  | 					{ src: '../../lib/js/classList.js' }, | ||||||
|  | 					{ src: '../../plugin/math/math.js', async: true } | ||||||
|  | 				] | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 		</script> | ||||||
|  |  | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
| @@ -8,8 +8,8 @@ | |||||||
| 
 | 
 | ||||||
| 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | ||||||
| 
 | 
 | ||||||
| 		<link rel="stylesheet" href="../css/reveal.min.css"> | 		<link rel="stylesheet" href="../../css/reveal.min.css"> | ||||||
| 		<link rel="stylesheet" href="../css/theme/serif.css" id="theme"> | 		<link rel="stylesheet" href="../../css/theme/serif.css" id="theme"> | ||||||
| 	</head> | 	</head> | ||||||
| 
 | 
 | ||||||
| 	<body> | 	<body> | ||||||
| @@ -79,8 +79,8 @@ | |||||||
| 
 | 
 | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<script src="../lib/js/head.min.js"></script> | 		<script src="../../lib/js/head.min.js"></script> | ||||||
| 		<script src="../js/reveal.min.js"></script> | 		<script src="../../js/reveal.min.js"></script> | ||||||
| 
 | 
 | ||||||
| 		<script> | 		<script> | ||||||
| 
 | 
 | ||||||
							
								
								
									
										244
									
								
								test/qunit-1.12.0.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								test/qunit-1.12.0.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | |||||||
|  | /** | ||||||
|  |  * QUnit v1.12.0 - A JavaScript Unit Testing Framework | ||||||
|  |  * | ||||||
|  |  * http://qunitjs.com | ||||||
|  |  * | ||||||
|  |  * Copyright 2012 jQuery Foundation and other contributors | ||||||
|  |  * Released under the MIT license. | ||||||
|  |  * http://jquery.org/license | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** Font Family and Sizes */ | ||||||
|  |  | ||||||
|  | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { | ||||||
|  | 	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } | ||||||
|  | #qunit-tests { font-size: smaller; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** Resets */ | ||||||
|  |  | ||||||
|  | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { | ||||||
|  | 	margin: 0; | ||||||
|  | 	padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** Header */ | ||||||
|  |  | ||||||
|  | #qunit-header { | ||||||
|  | 	padding: 0.5em 0 0.5em 1em; | ||||||
|  |  | ||||||
|  | 	color: #8699a4; | ||||||
|  | 	background-color: #0d3349; | ||||||
|  |  | ||||||
|  | 	font-size: 1.5em; | ||||||
|  | 	line-height: 1em; | ||||||
|  | 	font-weight: normal; | ||||||
|  |  | ||||||
|  | 	border-radius: 5px 5px 0 0; | ||||||
|  | 	-moz-border-radius: 5px 5px 0 0; | ||||||
|  | 	-webkit-border-top-right-radius: 5px; | ||||||
|  | 	-webkit-border-top-left-radius: 5px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-header a { | ||||||
|  | 	text-decoration: none; | ||||||
|  | 	color: #c2ccd1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-header a:hover, | ||||||
|  | #qunit-header a:focus { | ||||||
|  | 	color: #fff; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-testrunner-toolbar label { | ||||||
|  | 	display: inline-block; | ||||||
|  | 	padding: 0 .5em 0 .1em; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-banner { | ||||||
|  | 	height: 5px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-testrunner-toolbar { | ||||||
|  | 	padding: 0.5em 0 0.5em 2em; | ||||||
|  | 	color: #5E740B; | ||||||
|  | 	background-color: #eee; | ||||||
|  | 	overflow: hidden; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-userAgent { | ||||||
|  | 	padding: 0.5em 0 0.5em 2.5em; | ||||||
|  | 	background-color: #2b81af; | ||||||
|  | 	color: #fff; | ||||||
|  | 	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-modulefilter-container { | ||||||
|  | 	float: right; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** Tests: Pass/Fail */ | ||||||
|  |  | ||||||
|  | #qunit-tests { | ||||||
|  | 	list-style-position: inside; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests li { | ||||||
|  | 	padding: 0.4em 0.5em 0.4em 2.5em; | ||||||
|  | 	border-bottom: 1px solid #fff; | ||||||
|  | 	list-style-position: inside; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  { | ||||||
|  | 	display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests li strong { | ||||||
|  | 	cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests li a { | ||||||
|  | 	padding: 0.5em; | ||||||
|  | 	color: #c2ccd1; | ||||||
|  | 	text-decoration: none; | ||||||
|  | } | ||||||
|  | #qunit-tests li a:hover, | ||||||
|  | #qunit-tests li a:focus { | ||||||
|  | 	color: #000; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests li .runtime { | ||||||
|  | 	float: right; | ||||||
|  | 	font-size: smaller; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .qunit-assert-list { | ||||||
|  | 	margin-top: 0.5em; | ||||||
|  | 	padding: 0.5em; | ||||||
|  |  | ||||||
|  | 	background-color: #fff; | ||||||
|  |  | ||||||
|  | 	border-radius: 5px; | ||||||
|  | 	-moz-border-radius: 5px; | ||||||
|  | 	-webkit-border-radius: 5px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .qunit-collapsed { | ||||||
|  | 	display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests table { | ||||||
|  | 	border-collapse: collapse; | ||||||
|  | 	margin-top: .2em; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests th { | ||||||
|  | 	text-align: right; | ||||||
|  | 	vertical-align: top; | ||||||
|  | 	padding: 0 .5em 0 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests td { | ||||||
|  | 	vertical-align: top; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests pre { | ||||||
|  | 	margin: 0; | ||||||
|  | 	white-space: pre-wrap; | ||||||
|  | 	word-wrap: break-word; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests del { | ||||||
|  | 	background-color: #e0f2be; | ||||||
|  | 	color: #374e0c; | ||||||
|  | 	text-decoration: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests ins { | ||||||
|  | 	background-color: #ffcaca; | ||||||
|  | 	color: #500; | ||||||
|  | 	text-decoration: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*** Test Counts */ | ||||||
|  |  | ||||||
|  | #qunit-tests b.counts                       { color: black; } | ||||||
|  | #qunit-tests b.passed                       { color: #5E740B; } | ||||||
|  | #qunit-tests b.failed                       { color: #710909; } | ||||||
|  |  | ||||||
|  | #qunit-tests li li { | ||||||
|  | 	padding: 5px; | ||||||
|  | 	background-color: #fff; | ||||||
|  | 	border-bottom: none; | ||||||
|  | 	list-style-position: inside; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*** Passing Styles */ | ||||||
|  |  | ||||||
|  | #qunit-tests li li.pass { | ||||||
|  | 	color: #3c510c; | ||||||
|  | 	background-color: #fff; | ||||||
|  | 	border-left: 10px solid #C6E746; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; } | ||||||
|  | #qunit-tests .pass .test-name               { color: #366097; } | ||||||
|  |  | ||||||
|  | #qunit-tests .pass .test-actual, | ||||||
|  | #qunit-tests .pass .test-expected           { color: #999999; } | ||||||
|  |  | ||||||
|  | #qunit-banner.qunit-pass                    { background-color: #C6E746; } | ||||||
|  |  | ||||||
|  | /*** Failing Styles */ | ||||||
|  |  | ||||||
|  | #qunit-tests li li.fail { | ||||||
|  | 	color: #710909; | ||||||
|  | 	background-color: #fff; | ||||||
|  | 	border-left: 10px solid #EE5757; | ||||||
|  | 	white-space: pre; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests > li:last-child { | ||||||
|  | 	border-radius: 0 0 5px 5px; | ||||||
|  | 	-moz-border-radius: 0 0 5px 5px; | ||||||
|  | 	-webkit-border-bottom-right-radius: 5px; | ||||||
|  | 	-webkit-border-bottom-left-radius: 5px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #qunit-tests .fail                          { color: #000000; background-color: #EE5757; } | ||||||
|  | #qunit-tests .fail .test-name, | ||||||
|  | #qunit-tests .fail .module-name             { color: #000000; } | ||||||
|  |  | ||||||
|  | #qunit-tests .fail .test-actual             { color: #EE5757; } | ||||||
|  | #qunit-tests .fail .test-expected           { color: green;   } | ||||||
|  |  | ||||||
|  | #qunit-banner.qunit-fail                    { background-color: #EE5757; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** Result */ | ||||||
|  |  | ||||||
|  | #qunit-testresult { | ||||||
|  | 	padding: 0.5em 0.5em 0.5em 2.5em; | ||||||
|  |  | ||||||
|  | 	color: #2b81af; | ||||||
|  | 	background-color: #D2E0E6; | ||||||
|  |  | ||||||
|  | 	border-bottom: 1px solid white; | ||||||
|  | } | ||||||
|  | #qunit-testresult .module-name { | ||||||
|  | 	font-weight: bold; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** Fixture */ | ||||||
|  |  | ||||||
|  | #qunit-fixture { | ||||||
|  | 	position: absolute; | ||||||
|  | 	top: -10000px; | ||||||
|  | 	left: -10000px; | ||||||
|  | 	width: 1000px; | ||||||
|  | 	height: 1000px; | ||||||
|  | } | ||||||
							
								
								
									
										2212
									
								
								test/qunit-1.12.0.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2212
									
								
								test/qunit-1.12.0.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										62
									
								
								test/test.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								test/test.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  |  | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="utf-8"> | ||||||
|  |  | ||||||
|  | 		<title>reveal.js - Tests</title> | ||||||
|  |  | ||||||
|  | 		<link rel="stylesheet" href="../css/reveal.min.css"> | ||||||
|  | 		<link rel="stylesheet" href="qunit-1.12.0.css"> | ||||||
|  | 	</head> | ||||||
|  |  | ||||||
|  | 	<body style="overflow: auto;"> | ||||||
|  |  | ||||||
|  | 		<div id="qunit"></div> | ||||||
|  |   		<div id="qunit-fixture"></div> | ||||||
|  |  | ||||||
|  | 		<div class="reveal" style="display: none;"> | ||||||
|  |  | ||||||
|  | 			<div class="slides"> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h1>1</h1> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<section> | ||||||
|  | 						<h1>2.1</h1> | ||||||
|  | 					</section> | ||||||
|  | 					<section> | ||||||
|  | 						<h1>2.2</h1> | ||||||
|  | 					</section> | ||||||
|  | 					<section> | ||||||
|  | 						<h1>2.3</h1> | ||||||
|  | 					</section> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h1>4</h1> | ||||||
|  | 					<ul> | ||||||
|  | 						<li class="fragment">4.1</li> | ||||||
|  | 						<li class="fragment">4.2</li> | ||||||
|  | 						<li class="fragment">4.3</li> | ||||||
|  | 					</ul> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 				<section> | ||||||
|  | 					<h1>4</h1> | ||||||
|  | 				</section> | ||||||
|  |  | ||||||
|  | 			</div> | ||||||
|  |  | ||||||
|  | 		</div> | ||||||
|  |  | ||||||
|  | 		<script src="../lib/js/head.min.js"></script> | ||||||
|  | 		<script src="../js/reveal.min.js"></script> | ||||||
|  | 		<script src="qunit-1.12.0.js"></script> | ||||||
|  |  | ||||||
|  | 		<script src="test.js"></script> | ||||||
|  |  | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
							
								
								
									
										353
									
								
								test/test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								test/test.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,353 @@ | |||||||
|  |  | ||||||
|  | // These tests expect the DOM to contain a presentation | ||||||
|  | // with the following slide structure: | ||||||
|  | // | ||||||
|  | // 1 | ||||||
|  | // 2 - Three sub-slides | ||||||
|  | // 3 - Three fragment elements | ||||||
|  | // 4 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Reveal.addEventListener( 'ready', function() { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------- | ||||||
|  | 	// API TESTS | ||||||
|  |  | ||||||
|  | 	QUnit.module( 'API' ); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.isReady', function() { | ||||||
|  | 		strictEqual( Reveal.isReady(), true, 'returns true' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.isOverview', function() { | ||||||
|  | 		strictEqual( Reveal.isOverview(), false, 'false by default' ); | ||||||
|  |  | ||||||
|  | 		Reveal.toggleOverview(); | ||||||
|  | 		strictEqual( Reveal.isOverview(), true, 'true after toggling on' ); | ||||||
|  |  | ||||||
|  | 		Reveal.toggleOverview(); | ||||||
|  | 		strictEqual( Reveal.isOverview(), false, 'false after toggling off' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.isPaused', function() { | ||||||
|  | 		strictEqual( Reveal.isPaused(), false, 'false by default' ); | ||||||
|  |  | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  | 		strictEqual( Reveal.isPaused(), true, 'true after pausing' ); | ||||||
|  |  | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  | 		strictEqual( Reveal.isPaused(), false, 'false after resuming' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.isFirstSlide', function() { | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 1, 0 ); | ||||||
|  | 		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.isLastSlide', function() { | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' ); | ||||||
|  |  | ||||||
|  | 		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1; | ||||||
|  |  | ||||||
|  | 		Reveal.slide( lastSlideIndex, 0 ); | ||||||
|  | 		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.getIndices', function() { | ||||||
|  | 		var indices = Reveal.getIndices(); | ||||||
|  |  | ||||||
|  | 		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' ); | ||||||
|  | 		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' ); | ||||||
|  | 		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 1, 0 ); | ||||||
|  | 		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 1, 2 ); | ||||||
|  | 		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.getSlide', function() { | ||||||
|  | 		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' ); | ||||||
|  |  | ||||||
|  | 		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' ); | ||||||
|  |  | ||||||
|  | 		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() { | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		Reveal.slide( 1, 0 ); | ||||||
|  |  | ||||||
|  | 		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' ); | ||||||
|  | 		var secondSlide = document.querySelector( '.reveal .slides>section:nth-child(2)>section' ); | ||||||
|  |  | ||||||
|  | 		equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' ); | ||||||
|  | 		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.getScale', function() { | ||||||
|  | 		ok( typeof Reveal.getScale() === 'number', 'has scale' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.getConfig', function() { | ||||||
|  | 		ok( typeof Reveal.getConfig() === 'object', 'has config' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.configure', function() { | ||||||
|  | 		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ loop: true }); | ||||||
|  | 		strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ loop: false, customTestValue: 1 }); | ||||||
|  | 		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.availableRoutes', function() { | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  | 		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 1, 0 ); | ||||||
|  | 		deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Reveal.next', function() { | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  |  | ||||||
|  | 		// Step through the vertical child slides | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } ); | ||||||
|  |  | ||||||
|  | 		// There's fragments on this slide | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 3 } ); | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||||
|  |  | ||||||
|  | 		// We're at the end, this should have no effect | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------- | ||||||
|  | 	// FRAGMENT TESTS | ||||||
|  |  | ||||||
|  | 	QUnit.module( 'Fragments' ); | ||||||
|  |  | ||||||
|  | 	test( 'Sliding to fragments', function() { | ||||||
|  | 		Reveal.slide( 2, 0, 0 ); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 2, 0, 2 ); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'Reveal.slide( 2, 0, 2 )' ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 2, 0, 1 ); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Stepping through fragments', function() { | ||||||
|  | 		Reveal.slide( 2, 0, 0 ); | ||||||
|  |  | ||||||
|  | 		// forwards: | ||||||
|  |  | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'next() goes to next fragment' ); | ||||||
|  |  | ||||||
|  | 		Reveal.right(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'right() goes to next fragment' ); | ||||||
|  |  | ||||||
|  | 		Reveal.down(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 3 }, 'down() goes to next fragment' ); | ||||||
|  |  | ||||||
|  | 		Reveal.down(); // moves to f #3 | ||||||
|  |  | ||||||
|  | 		// backwards: | ||||||
|  |  | ||||||
|  | 		Reveal.prev(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' ); | ||||||
|  |  | ||||||
|  | 		Reveal.left(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' ); | ||||||
|  |  | ||||||
|  | 		Reveal.up(); | ||||||
|  | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'left() goes to prev fragment' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	asyncTest( 'fragmentshown event', function() { | ||||||
|  | 		expect( 2 ); | ||||||
|  |  | ||||||
|  | 		var _onEvent = function( event ) { | ||||||
|  | 			ok( true, 'event fired' ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Reveal.addEventListener( 'fragmentshown', _onEvent ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 2, 0 ); | ||||||
|  | 		Reveal.slide( 2, 0 ); // should do nothing | ||||||
|  | 		Reveal.slide( 2, 0, 0 ); // should do nothing | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		Reveal.next(); | ||||||
|  | 		Reveal.prev(); // shouldn't fire fragmentshown | ||||||
|  |  | ||||||
|  | 		start(); | ||||||
|  |  | ||||||
|  | 		Reveal.removeEventListener( 'fragmentshown', _onEvent ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	asyncTest( 'fragmenthidden event', function() { | ||||||
|  | 		expect( 2 ); | ||||||
|  |  | ||||||
|  | 		var _onEvent = function( event ) { | ||||||
|  | 			ok( true, 'event fired' ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Reveal.addEventListener( 'fragmenthidden', _onEvent ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 2, 0, 2 ); | ||||||
|  | 		Reveal.slide( 2, 0, 2 ); // should do nothing | ||||||
|  | 		Reveal.prev(); | ||||||
|  | 		Reveal.prev(); | ||||||
|  | 		Reveal.next(); // shouldn't fire fragmenthidden | ||||||
|  |  | ||||||
|  | 		start(); | ||||||
|  |  | ||||||
|  | 		Reveal.removeEventListener( 'fragmenthidden', _onEvent ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------- | ||||||
|  | 	// CONFIGURATION VALUES | ||||||
|  |  | ||||||
|  | 	QUnit.module( 'Configuration' ); | ||||||
|  |  | ||||||
|  | 	test( 'Controls', function() { | ||||||
|  | 		var controlsElement = document.querySelector( '.reveal>.controls' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ controls: false }); | ||||||
|  | 		equal( controlsElement.style.display, 'none', 'controls are hidden' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ controls: true }); | ||||||
|  | 		equal( controlsElement.style.display, 'block', 'controls are visible' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Progress', function() { | ||||||
|  | 		var progressElement = document.querySelector( '.reveal>.progress' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ progress: false }); | ||||||
|  | 		equal( progressElement.style.display, 'none', 'progress are hidden' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ progress: true }); | ||||||
|  | 		equal( progressElement.style.display, 'block', 'progress are visible' ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test( 'Loop', function() { | ||||||
|  | 		Reveal.configure({ loop: true }); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 0, 0 ); | ||||||
|  |  | ||||||
|  | 		Reveal.left(); | ||||||
|  | 		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' ); | ||||||
|  |  | ||||||
|  | 		Reveal.right(); | ||||||
|  | 		equal( Reveal.getIndices().h, 0, 'looped from end to start' ); | ||||||
|  |  | ||||||
|  | 		Reveal.configure({ loop: false }); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------- | ||||||
|  | 	// EVENT TESTS | ||||||
|  |  | ||||||
|  | 	QUnit.module( 'Events' ); | ||||||
|  |  | ||||||
|  | 	asyncTest( 'slidechanged', function() { | ||||||
|  | 		expect( 3 ); | ||||||
|  |  | ||||||
|  | 		var _onEvent = function( event ) { | ||||||
|  | 			ok( true, 'event fired' ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Reveal.addEventListener( 'slidechanged', _onEvent ); | ||||||
|  |  | ||||||
|  | 		Reveal.slide( 1, 0 ); // should trigger | ||||||
|  | 		Reveal.slide( 1, 0 ); // should do nothing | ||||||
|  | 		Reveal.next(); // should trigger | ||||||
|  | 		Reveal.slide( 3, 0 ); // should trigger | ||||||
|  | 		Reveal.next(); // should do nothing | ||||||
|  |  | ||||||
|  | 		start(); | ||||||
|  |  | ||||||
|  | 		Reveal.removeEventListener( 'slidechanged', _onEvent ); | ||||||
|  |  | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	asyncTest( 'paused', function() { | ||||||
|  | 		expect( 1 ); | ||||||
|  |  | ||||||
|  | 		var _onEvent = function( event ) { | ||||||
|  | 			ok( true, 'event fired' ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Reveal.addEventListener( 'paused', _onEvent ); | ||||||
|  |  | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  |  | ||||||
|  | 		start(); | ||||||
|  |  | ||||||
|  | 		Reveal.removeEventListener( 'paused', _onEvent ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	asyncTest( 'resumed', function() { | ||||||
|  | 		expect( 1 ); | ||||||
|  |  | ||||||
|  | 		var _onEvent = function( event ) { | ||||||
|  | 			ok( true, 'event fired' ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Reveal.addEventListener( 'resumed', _onEvent ); | ||||||
|  |  | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  | 		Reveal.togglePause(); | ||||||
|  |  | ||||||
|  | 		start(); | ||||||
|  |  | ||||||
|  | 		Reveal.removeEventListener( 'resumed', _onEvent ); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } ); | ||||||
|  |  | ||||||
|  | Reveal.initialize(); | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user