Browse Source

Merge branch 'dev' of github.com:hakimel/reveal.js

Hakim El Hattab 6 years ago
parent
commit
b6aa0cac23

+ 2 - 1
.gitignore

@@ -8,6 +8,7 @@ out/
 log/*.log
 tmp/**
 node_modules/
+package-lock.json
 .sass-cache
 css/reveal.min.css
-js/reveal.min.js
+js/reveal.min.js

+ 1 - 3
.travis.yml

@@ -1,7 +1,5 @@
 language: node_js
 node_js:
   - 4
-before_script:
-  - npm install -g grunt-cli
 after_script:
-  - grunt retire
+  - npm run build -- retire

+ 4 - 3
Gruntfile.js

@@ -15,7 +15,7 @@ module.exports = function(grunt) {
 				' * http://revealjs.com\n' +
 				' * MIT licensed\n' +
 				' *\n' +
-				' * Copyright (C) 2017 Hakim El Hattab, http://hakim.se\n' +
+				' * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n' +
 				' */'
 		},
 
@@ -26,7 +26,7 @@ module.exports = function(grunt) {
 		uglify: {
 			options: {
 				banner: '<%= meta.banner %>\n',
-				screwIE8: false
+				ie8: true
 			},
 			build: {
 				src: 'js/reveal.js',
@@ -78,6 +78,7 @@ module.exports = function(grunt) {
 				eqnull: true,
 				browser: true,
 				expr: true,
+				loopfunc: true,
 				globals: {
 					head: false,
 					module: false,
@@ -164,7 +165,7 @@ module.exports = function(grunt) {
 	grunt.loadNpmTasks( 'grunt-retire' );
 	grunt.loadNpmTasks( 'grunt-sass' );
 	grunt.loadNpmTasks( 'grunt-zip' );
-	
+
 	// Default task
 	grunt.registerTask( 'default', [ 'css', 'js' ] );
 

+ 1 - 1
LICENSE

@@ -1,4 +1,4 @@
-Copyright (C) 2017 Hakim El Hattab, http://hakim.se, and reveal.js contributors
+Copyright (C) 2018 Hakim El Hattab, http://hakim.se, and reveal.js contributors
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 62 - 17
README.md

@@ -206,9 +206,6 @@ Reveal.initialize({
 	// Display a presentation progress bar
 	progress: true,
 
-	// Set default timing of 2 minutes per slide
-	defaultTiming: 120,
-
 	// Display the page number of the current slide
 	slideNumber: false,
 
@@ -239,6 +236,10 @@ Reveal.initialize({
 	// Turns fragments on and off globally
 	fragments: true,
 
+	// Flags whether to include the current fragment in the URL,
+	// so that reloading brings you to the same fragment position
+	fragmentInURL: false,
+
 	// Flags if the presentation is running in an embedded mode,
 	// i.e. contained within a limited portion of the screen
 	embedded: false,
@@ -267,6 +268,11 @@ Reveal.initialize({
 	// Use this method for navigation when auto-sliding
 	autoSlideMethod: Reveal.navigateNext,
 
+	// Specify the average time in seconds that you think you will spend
+	// presenting each slide. This is used to show a pacing timer in the
+	// speaker view
+	defaultTiming: 120,
+
 	// Enable slide navigation via mouse wheel
 	mouseWheel: false,
 
@@ -531,6 +537,37 @@ Reveal.isPaused();
 Reveal.isAutoSliding();
 ```
 
+### Custom Key Bindings
+
+Custom key bindings can be added and removed using the following Javascript API. Custom key bindings will override the default keyboard bindings, but will in turn be overridden by the user defined bindings in the ``keyboard`` config option.
+
+```javascript
+Reveal.addKeyBinding( binding, callback );
+Reveal.removeKeyBinding( keyCode );
+```
+
+For example
+
+```javascript
+// The binding parameter provides the following properties
+//      keyCode: the keycode for binding to the callback
+//          key: the key label to show in the help overlay
+//  description: the description of the action to show in the help overlay
+Reveal.addKeyBinding( { keyCode: 84, key: 'T', description: 'Start timer' }, function() {
+	// start timer
+} )
+
+// The binding parameter can also be a direct keycode without providing the help description
+Reveal.addKeyBinding( 82, function() {
+	// reset timer
+} )
+```
+
+This allows plugins to add key bindings directly to Reveal so they can
+
+* make use of Reveal's pre-processing logic for key handling (for example, ignoring key presses when paused); and
+* be included in the help overlay (optional)
+
 ### Slide Changed Event
 
 A `slidechanged` event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
@@ -590,12 +627,13 @@ All CSS color formats are supported, including hex values, keywords, `rgba()` or
 
 By default, background images are resized to cover the full page. Available options:
 
-| Attribute                    | Default    | Description |
-| :--------------------------- | :--------- | :---------- |
-| data-background-image        |            | URL of the image to show. GIFs restart when the slide opens. |
-| data-background-size         | cover      | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN.  |
-| data-background-position     | center     | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. |
-| data-background-repeat       | no-repeat  | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. |
+| Attribute                        | Default    | Description |
+| :------------------------------- | :--------- | :---------- |
+| data-background-image            |            | URL of the image to show. GIFs restart when the slide opens. |
+| data-background-size             | cover      | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN.  |
+| data-background-position         | center     | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. |
+| data-background-repeat           | no-repeat  | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. |
+| data-background-opacity          | 1          | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. |
 
 ```html
 <section data-background-image="http://example.com/image.png">
@@ -610,12 +648,13 @@ By default, background images are resized to cover the full page. Available opti
 
 Automatically plays a full size video behind the slide.
 
-| Attribute                    | Default | Description |
-| :--------------------------- | :------ | :---------- |
-| data-background-video        |         | A single video source, or a comma separated list of video sources. |
-| data-background-video-loop   | false   | Flags if the video should play repeatedly. |
-| data-background-video-muted  | false   | Flags if the audio should be muted. |
-| data-background-size         | cover   | Use `cover` for full screen and some cropping or `contain` for letterboxing. |
+| Attribute                        | Default | Description |
+| :---------------------------     | :------ | :---------- |
+| data-background-video            |         | A single video source, or a comma separated list of video sources. |
+| data-background-video-loop       | false   | Flags if the video should play repeatedly. |
+| data-background-video-muted      | false   | Flags if the audio should be muted. |
+| data-background-size             | cover   | Use `cover` for full screen and some cropping or `contain` for letterboxing. |
+| data-background-opacity          | 1       | Opacity of the background video on a 0-1 scale. 0 is transparent and 1 is fully opaque. |
 
 ```html
 <section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-video-loop data-background-video-muted>
@@ -728,7 +767,8 @@ The default fragment style is to start out invisible and fade in. This style can
 	<p class="fragment shrink">shrink</p>
 	<p class="fragment fade-out">fade-out</p>
 	<p class="fragment fade-up">fade-up (also down, left and right!)</p>
-	<p class="fragment current-visible">visible only once</p>
+	<p class="fragment fade-in-then-out">fades in, then out when we move to the next step</p>
+	<p class="fragment fade-in-then-semi-out">fades in, then obfuscate when we move to the next step</p>
 	<p class="fragment highlight-current-blue">blue only once</p>
 	<p class="fragment highlight-red">highlight-red</p>
 	<p class="fragment highlight-green">highlight-green</p>
@@ -907,6 +947,11 @@ Reveal.initialize({
 Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome) or [Chromium](https://www.chromium.org/Home) and to be serving the presentation from a webserver.
 Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-300.
 
+### Separate pages for fragments
+[Fragments](#fragments) are printed on separate slides by default. Meaning if you have a slide with three fragment steps, it will generate three separate slides where the fragments appear incrementally.
+
+If you prefer printing all fragments in their visible states on the same slide you can set the `pdfSeparateFragments` config option to false.
+
 ### Page size
 
 Export dimensions are inferred from the configured [presentation size](#presentation-size). Slides that are too tall to fit within a single page will expand onto multiple pages. You can limit how many pages a slide may expand onto using the `pdfMaxPagesPerSlide` config option, for example `Reveal.configure({ pdfMaxPagesPerSlide: 1 })` ensures that no slide ever grows to more than one printed page.
@@ -1261,4 +1306,4 @@ Some reveal.js features, like external Markdown and speaker notes, require that
 
 MIT licensed
 
-Copyright (C) 2017 Hakim El Hattab, http://hakim.se
+Copyright (C) 2018 Hakim El Hattab, http://hakim.se

+ 4 - 18
css/print/pdf.css

@@ -72,15 +72,8 @@ ul, ol, div, p {
 	overflow: visible;
 	display: block;
 
-	-webkit-perspective: none;
-	   -moz-perspective: none;
-	    -ms-perspective: none;
-	        perspective: none;
-
-	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
-	   -moz-perspective-origin: 50% 50%;
-	    -ms-perspective-origin: 50% 50%;
-	        perspective-origin: 50% 50%;
+	perspective: none;
+	perspective-origin: 50% 50%;
 }
 
 .reveal .slides .pdf-page {
@@ -103,15 +96,8 @@ ul, ol, div, p {
 
 	opacity: 1 !important;
 
-	-webkit-transform-style: flat !important;
-	   -moz-transform-style: flat !important;
-	    -ms-transform-style: flat !important;
-	        transform-style: flat !important;
-
-	-webkit-transform: none !important;
-	   -moz-transform: none !important;
-	    -ms-transform: none !important;
-	        transform: none !important;
+	transform-style: flat !important;
+	transform: none !important;
 }
 
 .reveal section.stack {

+ 41 - 5
css/reveal.css

@@ -3,7 +3,7 @@
  * http://revealjs.com
  * MIT licensed
  *
- * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2018 Hakim El Hattab, http://hakim.se
  */
 /*********************************************
  * RESET STYLES
@@ -127,13 +127,25 @@ body {
     -webkit-transform: translate(0, 0);
             transform: translate(0, 0); }
 
+.reveal .slides section .fragment.fade-in-then-out,
 .reveal .slides section .fragment.current-visible {
   opacity: 0;
   visibility: hidden; }
+  .reveal .slides section .fragment.fade-in-then-out.current-fragment,
   .reveal .slides section .fragment.current-visible.current-fragment {
     opacity: 1;
     visibility: inherit; }
 
+.reveal .slides section .fragment.fade-in-then-semi-out {
+  opacity: 0;
+  visibility: hidden; }
+  .reveal .slides section .fragment.fade-in-then-semi-out.visible {
+    opacity: 0.5;
+    visibility: inherit; }
+  .reveal .slides section .fragment.fade-in-then-semi-out.current-fragment {
+    opacity: 1;
+    visibility: inherit; }
+
 .reveal .slides section .fragment.highlight-red,
 .reveal .slides section .fragment.highlight-current-red,
 .reveal .slides section .fragment.highlight-green,
@@ -448,7 +460,7 @@ body {
  * SLIDE NUMBER
  *********************************************/
 .reveal .slide-number {
-  position: fixed;
+  position: absolute;
   display: block;
   right: 8px;
   bottom: 8px;
@@ -460,6 +472,9 @@ body {
   background-color: rgba(0, 0, 0, 0.4);
   padding: 5px; }
 
+.reveal .slide-number a {
+  color: currentColor; }
+
 .reveal .slide-number-delimiter {
   margin: 0 3px; }
 
@@ -528,7 +543,8 @@ body {
 
 .reveal .slides > section.stack {
   padding-top: 0;
-  padding-bottom: 0; }
+  padding-bottom: 0;
+  pointer-events: none; }
 
 .reveal .slides > section.present,
 .reveal .slides > section > section.present {
@@ -948,6 +964,21 @@ body {
   z-index: 100;
   transition: all 1s ease; }
 
+.reveal .pause-overlay .resume-button {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+  color: #ccc;
+  border-radius: 2px;
+  padding: 6px 14px;
+  border: 2px solid #ccc;
+  font-size: 16px;
+  background: transparent;
+  cursor: pointer; }
+  .reveal .pause-overlay .resume-button:hover {
+    color: #fff;
+    border-color: #fff; }
+
 .reveal.paused .pause-overlay {
   visibility: visible;
   opacity: 1; }
@@ -1011,10 +1042,15 @@ body {
   visibility: hidden;
   overflow: hidden;
   background-color: transparent;
+  transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+.reveal .slide-background-content {
+  position: absolute;
+  width: 100%;
+  height: 100%;
   background-position: 50% 50%;
   background-repeat: no-repeat;
-  background-size: cover;
-  transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+  background-size: cover; }
 
 .reveal .slide-background.stack {
   display: block; }

+ 51 - 4
css/reveal.scss

@@ -3,7 +3,7 @@
  * http://revealjs.com
  * MIT licensed
  *
- * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2018 Hakim El Hattab, http://hakim.se
  */
 
 
@@ -160,6 +160,7 @@ body {
 	}
 }
 
+.reveal .slides section .fragment.fade-in-then-out,
 .reveal .slides section .fragment.current-visible {
 	opacity: 0;
 	visibility: hidden;
@@ -170,6 +171,21 @@ body {
 	}
 }
 
+.reveal .slides section .fragment.fade-in-then-semi-out {
+	opacity: 0;
+	visibility: hidden;
+
+	&.visible {
+		opacity: 0.5;
+		visibility: inherit;
+	}
+
+	&.current-fragment {
+		opacity: 1;
+		visibility: inherit;
+	}
+}
+
 .reveal .slides section .fragment.highlight-red,
 .reveal .slides section .fragment.highlight-current-red,
 .reveal .slides section .fragment.highlight-green,
@@ -540,7 +556,7 @@ $controlsArrowAngleActive: 36deg;
  *********************************************/
 
 .reveal .slide-number {
-	position: fixed;
+	position: absolute;
 	display: block;
 	right: 8px;
 	bottom: 8px;
@@ -553,6 +569,10 @@ $controlsArrowAngleActive: 36deg;
 	padding: 5px;
 }
 
+.reveal .slide-number a {
+	color: currentColor;
+}
+
 .reveal .slide-number-delimiter {
 	margin: 0 3px;
 }
@@ -636,6 +656,7 @@ $controlsArrowAngleActive: 36deg;
 .reveal .slides>section.stack {
 	padding-top: 0;
 	padding-bottom: 0;
+	pointer-events: none;
 }
 
 .reveal .slides>section.present,
@@ -1013,6 +1034,25 @@ $controlsArrowAngleActive: 36deg;
 	z-index: 100;
 	transition: all 1s ease;
 }
+
+.reveal .pause-overlay .resume-button {
+	position: absolute;
+	bottom: 20px;
+	right: 20px;
+	color: #ccc;
+	border-radius: 2px;
+	padding: 6px 14px;
+	border: 2px solid #ccc;
+	font-size: 16px;
+	background: transparent;
+	cursor: pointer;
+
+	&:hover {
+		color: #fff;
+		border-color: #fff;
+	}
+}
+
 .reveal.paused .pause-overlay {
 	visibility: visible;
 	opacity: 1;
@@ -1086,11 +1126,18 @@ $controlsArrowAngleActive: 36deg;
 		overflow: hidden;
 
 		background-color: rgba( 0, 0, 0, 0 );
+
+		transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+	.reveal .slide-background-content {
+		position: absolute;
+		width: 100%;
+		height: 100%;
+
 		background-position: 50% 50%;
 		background-repeat: no-repeat;
 		background-size: cover;
-
-		transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 	}
 
 	.reveal .slide-background.stack {

+ 13 - 4
css/theme/beige.css

@@ -34,8 +34,8 @@ body {
   background: rgba(79, 64, 28, 0.99);
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -193,10 +193,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -266,3 +268,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #f7f3de; } }

+ 13 - 4
css/theme/black.css

@@ -30,8 +30,8 @@ body {
   background: #bee4fd;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -189,10 +189,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -262,3 +264,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #222; } }

+ 13 - 4
css/theme/blood.css

@@ -33,8 +33,8 @@ body {
   background: #a23;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -192,10 +192,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -266,6 +268,13 @@ body {
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #222; } }
+
 .reveal p {
   font-weight: 300;
   text-shadow: 1px 1px #222; }

+ 13 - 4
css/theme/league.css

@@ -36,8 +36,8 @@ body {
   background: #FF5E99;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -195,10 +195,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -268,3 +270,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #2b2b2b; } }

+ 13 - 4
css/theme/moon.css

@@ -34,8 +34,8 @@ body {
   background: #d33682;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -193,10 +193,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -266,3 +268,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #002b36; } }

+ 13 - 4
css/theme/night.css

@@ -28,8 +28,8 @@ body {
   background: #e7ad52;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -187,10 +187,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -260,3 +262,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #111; } }

+ 13 - 4
css/theme/serif.css

@@ -30,8 +30,8 @@ body {
   background: #26351C;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -189,10 +189,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -262,3 +264,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #F0F1EB; } }

+ 13 - 4
css/theme/simple.css

@@ -33,8 +33,8 @@ body {
   background: rgba(0, 0, 0, 0.99);
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -192,10 +192,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -265,3 +267,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #fff; } }

+ 13 - 4
css/theme/sky.css

@@ -37,8 +37,8 @@ body {
   background: #134674;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -196,10 +196,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -269,3 +271,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #f7fbfc; } }

+ 13 - 4
css/theme/solarized.css

@@ -34,8 +34,8 @@ body {
   background: #d33682;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -193,10 +193,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -266,3 +268,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #fdf6e3; } }

+ 13 - 4
css/theme/template/theme.scss

@@ -28,8 +28,8 @@ body {
 	text-shadow: none;
 }
 
-.reveal .slides>section,
-.reveal .slides>section>section {
+.reveal .slides section,
+.reveal .slides section>section {
 	line-height: 1.3;
 	font-weight: inherit;
 }
@@ -217,9 +217,11 @@ body {
 
 .reveal sup {
 	vertical-align: super;
+	font-size: smaller;
 }
 .reveal sub {
 	vertical-align: sub;
+	font-size: smaller;
 }
 
 .reveal small {
@@ -310,7 +312,14 @@ body {
 	.reveal .progress span {
 		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+			transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 	}
 
-
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+ @media print {
+    .backgrounds {
+        background-color: $backgroundColor;
+    }
+}

+ 13 - 4
css/theme/white.css

@@ -30,8 +30,8 @@ body {
   background: #98bdef;
   text-shadow: none; }
 
-.reveal .slides > section,
-.reveal .slides > section > section {
+.reveal .slides section,
+.reveal .slides section > section {
   line-height: 1.3;
   font-weight: inherit; }
 
@@ -189,10 +189,12 @@ body {
   border-bottom: none; }
 
 .reveal sup {
-  vertical-align: super; }
+  vertical-align: super;
+  font-size: smaller; }
 
 .reveal sub {
-  vertical-align: sub; }
+  vertical-align: sub;
+  font-size: smaller; }
 
 .reveal small {
   display: inline-block;
@@ -262,3 +264,10 @@ body {
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * PRINT BACKGROUND
+ *********************************************/
+@media print {
+  .backgrounds {
+    background-color: #fff; } }

+ 8 - 2
demo.html

@@ -139,8 +139,14 @@
 						<p class="fragment grow">grow</p>
 						<p class="fragment shrink">shrink</p>
 						<p class="fragment fade-out">fade-out</p>
-						<p class="fragment fade-up">fade-up (also down, left and right!)</p>
-						<p class="fragment current-visible">current-visible</p>
+						<p>
+							<span style="display: inline-block;" class="fragment fade-right">fade-right, </span>
+							<span style="display: inline-block;" class="fragment fade-up">up, </span>
+							<span style="display: inline-block;" class="fragment fade-down">down, </span>
+							<span style="display: inline-block;" class="fragment fade-left">left</span>
+						</p>
+						<p class="fragment fade-in-then-out">fade-in-then-out</p>
+						<p class="fragment fade-in-then-semi-out">fade-in-then-semi-out</p>
 						<p>Highlight <span class="fragment highlight-red">red</span> <span class="fragment highlight-blue">blue</span> <span class="fragment highlight-green">green</span></p>
 					</section>
 				</section>

File diff suppressed because it is too large
+ 506 - 170
js/reveal.js


+ 4 - 4
package.json

@@ -23,15 +23,15 @@
     "node": ">=4.0.0"
   },
   "devDependencies": {
-    "express": "^4.15.2",
+    "express": "^4.16.2",
     "grunt": "^1.0.1",
     "grunt-autoprefixer": "^3.0.4",
     "grunt-cli": "^1.2.0",
     "grunt-contrib-connect": "^1.0.2",
-    "grunt-contrib-cssmin": "^2.1.0",
+    "grunt-contrib-cssmin": "^2.2.1",
     "grunt-contrib-jshint": "^1.1.0",
-    "grunt-contrib-qunit": "~1.2.0",
-    "grunt-contrib-uglify": "^2.3.0",
+    "grunt-contrib-qunit": "^2.0.0",
+    "grunt-contrib-uglify": "^3.3.0",
     "grunt-contrib-watch": "^1.0.0",
     "grunt-sass": "^2.0.0",
     "grunt-retire": "^1.0.7",

+ 4 - 4
plugin/math/math.js

@@ -9,15 +9,15 @@ var RevealMath = window.RevealMath || (function(){
 	var options = Reveal.getConfig().math || {};
 	options.mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
 	options.config = options.config || 'TeX-AMS_HTML-full';
+	options.tex2jax = options.tex2jax || {
+				inlineMath: [['$','$'],['\\(','\\)']] ,
+				skipTags: ['script','noscript','style','textarea','pre'] };
 
 	loadScript( options.mathjax + '?config=' + options.config, function() {
 
 		MathJax.Hub.Config({
 			messageStyle: 'none',
-			tex2jax: {
-				inlineMath: [['$','$'],['\\(','\\)']] ,
-				skipTags: ['script','noscript','style','textarea','pre']
-			},
+			tex2jax: options.tex2jax,
 			skipStartupTypeset: true
 		});
 

+ 33 - 0
plugin/notes/notes.html

@@ -34,6 +34,22 @@
 				z-index: 2;
 			}
 
+			#connection-status {
+				position: absolute;
+				top: 0;
+				left: 0;
+				width: 100%;
+				height: 100%;
+				z-index: 20;
+				padding: 30% 20% 20% 20%;
+				font-size: 18px;
+				color: #222;
+				background: #fff;
+				text-align: center;
+				box-sizing: border-box;
+				line-height: 1.4;
+			}
+
 			.overlay-element {
 				height: 34px;
 				line-height: 34px;
@@ -288,6 +304,8 @@
 
 	<body>
 
+		<div id="connection-status">Loading speaker view...</div>
+
 		<div id="current-slide"></div>
 		<div id="upcoming-slide"><span class="overlay-element label">Upcoming</span></div>
 		<div id="speaker-controls">
@@ -340,8 +358,16 @@
 
 				setupLayout();
 
+				var connectionStatus = document.querySelector( '#connection-status' );
+				var connectionTimeout = setTimeout( function() {
+					connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
+				}, 5000 );
+
 				window.addEventListener( 'message', function( event ) {
 
+					clearTimeout( connectionTimeout );
+					connectionStatus.style.display = 'none';
+
 					var data = JSON.parse( event.data );
 
 					// The overview mode is only useful to the reveal.js instance
@@ -427,10 +453,17 @@
 				 * Forward keyboard events to the current slide window.
 				 * This enables keyboard events to work even if focus
 				 * isn't set on the current slide iframe.
+				 *
+				 * Block F5 default handling, it reloads and disconnects
+				 * the speaker notes window.
 				 */
 				function setupKeyboard() {
 
 					document.addEventListener( 'keydown', function( event ) {
+						if( event.keyCode === 116 || ( event.metaKey && event.keyCode === 82 ) ) {
+							event.preventDefault();
+							return false;
+						}
 						currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'triggerKey', args: [ event.keyCode ] }), '*' );
 					} );
 

+ 9 - 17
plugin/notes/notes.js

@@ -21,8 +21,13 @@ var RevealNotes = (function() {
 
 		var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
 
+		if( !notesPopup ) {
+			alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
+			return;
+		}
+
 		// Allow popup window access to Reveal API
-		notesPopup.Reveal = this.Reveal;
+		notesPopup.Reveal = window.Reveal;
 
 		/**
 		 * Connect to the notes window through a postmessage handshake.
@@ -131,22 +136,9 @@ var RevealNotes = (function() {
 		}
 
 		// Open the notes when the 's' key is hit
-		document.addEventListener( 'keydown', function( event ) {
-			// Disregard the event if the target is editable or a
-			// modifier is present
-			if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
-
-			// Disregard the event if keyboard is disabled
-			if ( Reveal.getConfig().keyboard === false ) return;
-
-			if( event.keyCode === 83 ) {
-				event.preventDefault();
-				openNotes();
-			}
-		}, false );
-
-		// Show our keyboard shortcut in the reveal.js help overlay
-		if( window.Reveal ) Reveal.registerKeyboardShortcut( 'S', 'Speaker notes view' );
+		Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
+			openNotes();
+		} );
 
 	}
 

+ 8 - 10
plugin/print-pdf/print-pdf.js

@@ -42,28 +42,26 @@ probePage.open( inputFile, function( status ) {
 
 		printPage.open( inputFile, function( status ) {
 			console.log( 'Export PDF: Preparing pdf [3/4]')
-			printPage.evaluate(function() {
+			printPage.evaluate( function() {
 				Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom );
-			});
+			} );
 		} );
 
-		printPage.onCallback = function(data) {
+		printPage.onCallback = function( data ) {
 			// For some reason we need to "jump the queue" for syntax highlighting to work.
 			// See: http://stackoverflow.com/a/3580132/129269
-			setTimeout(function() {
+			setTimeout( function() {
 				console.log( 'Export PDF: Writing file [4/4]' );
 				printPage.render( outputFile );
 				console.log( 'Export PDF: Finished successfully!' );
 				phantom.exit();
-			}, 0);
+			}, 0 );
 		};
 	}
 	else {
 
-        console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
-        phantom.exit(1);
+		console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
+		phantom.exit( 1 );
 
-    }
+	}
 } );
-
-

File diff suppressed because it is too large
+ 94 - 94
plugin/search/search.js


+ 0 - 244
test/qunit-1.12.0.css

@@ -1,244 +0,0 @@
-/**
- * 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;
-}

File diff suppressed because it is too large
+ 0 - 2212
test/qunit-1.12.0.js


+ 436 - 0
test/qunit-2.5.0.css

@@ -0,0 +1,436 @@
+/*!
+ * QUnit 2.5.0
+ * https://qunitjs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2018-01-10T02:56Z
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult {
+	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+	margin: 0;
+	padding: 0;
+}
+
+
+/** Header (excluding toolbar) */
+
+#qunit-header {
+	padding: 0.5em 0 0.5em 1em;
+
+	color: #8699A4;
+	background-color: #0D3349;
+
+	font-size: 1.5em;
+	line-height: 1em;
+	font-weight: 400;
+
+	border-radius: 5px 5px 0 0;
+}
+
+#qunit-header a {
+	text-decoration: none;
+	color: #C2CCD1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+	color: #FFF;
+}
+
+#qunit-banner {
+	height: 5px;
+}
+
+#qunit-filteredTest {
+	padding: 0.5em 1em 0.5em 1em;
+	color: #366097;
+	background-color: #F4FF77;
+}
+
+#qunit-userAgent {
+	padding: 0.5em 1em 0.5em 1em;
+	color: #FFF;
+	background-color: #2B81AF;
+	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+
+/** Toolbar */
+
+#qunit-testrunner-toolbar {
+	padding: 0.5em 1em 0.5em 1em;
+	color: #5E740B;
+	background-color: #EEE;
+}
+
+#qunit-testrunner-toolbar .clearfix {
+	height: 0;
+	clear: both;
+}
+
+#qunit-testrunner-toolbar label {
+	display: inline-block;
+}
+
+#qunit-testrunner-toolbar input[type=checkbox],
+#qunit-testrunner-toolbar input[type=radio] {
+	margin: 3px;
+	vertical-align: -2px;
+}
+
+#qunit-testrunner-toolbar input[type=text] {
+	box-sizing: border-box;
+	height: 1.6em;
+}
+
+.qunit-url-config,
+.qunit-filter,
+#qunit-modulefilter {
+	display: inline-block;
+	line-height: 2.1em;
+}
+
+.qunit-filter,
+#qunit-modulefilter {
+	float: right;
+	position: relative;
+	margin-left: 1em;
+}
+
+.qunit-url-config label {
+	margin-right: 0.5em;
+}
+
+#qunit-modulefilter-search {
+	box-sizing: border-box;
+	width: 400px;
+}
+
+#qunit-modulefilter-search-container:after {
+	position: absolute;
+	right: 0.3em;
+	content: "\25bc";
+	color: black;
+}
+
+#qunit-modulefilter-dropdown {
+	/* align with #qunit-modulefilter-search */
+	box-sizing: border-box;
+	width: 400px;
+	position: absolute;
+	right: 0;
+	top: 50%;
+	margin-top: 0.8em;
+
+	border: 1px solid #D3D3D3;
+	border-top: none;
+	border-radius: 0 0 .25em .25em;
+	color: #000;
+	background-color: #F5F5F5;
+	z-index: 99;
+}
+
+#qunit-modulefilter-dropdown a {
+	color: inherit;
+	text-decoration: none;
+}
+
+#qunit-modulefilter-dropdown .clickable.checked {
+	font-weight: bold;
+	color: #000;
+	background-color: #D2E0E6;
+}
+
+#qunit-modulefilter-dropdown .clickable:hover {
+	color: #FFF;
+	background-color: #0D3349;
+}
+
+#qunit-modulefilter-actions {
+	display: block;
+	overflow: auto;
+
+	/* align with #qunit-modulefilter-dropdown-list */
+	font: smaller/1.5em sans-serif;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * {
+	box-sizing: border-box;
+	max-height: 2.8em;
+	display: block;
+	padding: 0.4em;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button {
+	float: right;
+	font: inherit;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child {
+	/* insert padding to align with checkbox margins */
+	padding-left: 3px;
+}
+
+#qunit-modulefilter-dropdown-list {
+	max-height: 200px;
+	overflow-y: auto;
+	margin: 0;
+	border-top: 2px groove threedhighlight;
+	padding: 0.4em 0 0;
+	font: smaller/1.5em sans-serif;
+}
+
+#qunit-modulefilter-dropdown-list li {
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+
+#qunit-modulefilter-dropdown-list .clickable {
+	display: block;
+	padding-left: 0.15em;
+}
+
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+	list-style-position: inside;
+}
+
+#qunit-tests li {
+	padding: 0.4em 1em 0.4em 1em;
+	border-bottom: 1px solid #FFF;
+	list-style-position: inside;
+}
+
+#qunit-tests > li {
+	display: none;
+}
+
+#qunit-tests li.running,
+#qunit-tests li.pass,
+#qunit-tests li.fail,
+#qunit-tests li.skipped,
+#qunit-tests li.aborted {
+	display: list-item;
+}
+
+#qunit-tests.hidepass {
+	position: relative;
+}
+
+#qunit-tests.hidepass li.running,
+#qunit-tests.hidepass li.pass:not(.todo) {
+	visibility: hidden;
+	position: absolute;
+	width:   0;
+	height:  0;
+	padding: 0;
+	border:  0;
+	margin:  0;
+}
+
+#qunit-tests li strong {
+	cursor: pointer;
+}
+
+#qunit-tests li.skipped strong {
+	cursor: default;
+}
+
+#qunit-tests li a {
+	padding: 0.5em;
+	color: #C2CCD1;
+	text-decoration: none;
+}
+
+#qunit-tests li p a {
+	padding: 0.25em;
+	color: #6B6464;
+}
+#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;
+}
+
+.qunit-source {
+	margin: 0.6em 0 0.3em;
+}
+
+.qunit-collapsed {
+	display: none;
+}
+
+#qunit-tests table {
+	border-collapse: collapse;
+	margin-top: 0.2em;
+}
+
+#qunit-tests th {
+	text-align: right;
+	vertical-align: top;
+	padding: 0 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 {
+	color: #374E0C;
+	background-color: #E0F2BE;
+	text-decoration: none;
+}
+
+#qunit-tests ins {
+	color: #500;
+	background-color: #FFCACA;
+	text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: #000; }
+#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: #999; }
+
+#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;
+}
+
+#qunit-tests .fail                          { color: #000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: #008000; }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+
+/*** Aborted tests */
+#qunit-tests .aborted { color: #000; background-color: orange; }
+/*** Skipped tests */
+
+#qunit-tests .skipped {
+	background-color: #EBECE9;
+}
+
+#qunit-tests .qunit-todo-label,
+#qunit-tests .qunit-skipped-label {
+	background-color: #F4FF77;
+	display: inline-block;
+	font-style: normal;
+	color: #366097;
+	line-height: 1.8em;
+	padding: 0 0.5em;
+	margin: -0.4em 0.4em -0.4em 0;
+}
+
+#qunit-tests .qunit-todo-label {
+	background-color: #EEE;
+}
+
+/** Result */
+
+#qunit-testresult {
+	color: #2B81AF;
+	background-color: #D2E0E6;
+
+	border-bottom: 1px solid #FFF;
+}
+#qunit-testresult .clearfix {
+	height: 0;
+	clear: both;
+}
+#qunit-testresult .module-name {
+	font-weight: 700;
+}
+#qunit-testresult-display {
+	padding: 0.5em 1em 0.5em 1em;
+	width: 85%;
+	float:left;
+}
+#qunit-testresult-controls {
+	padding: 0.5em 1em 0.5em 1em;
+  width: 10%;
+	float:left;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+	position: absolute;
+	top: -10000px;
+	left: -10000px;
+	width: 1000px;
+	height: 1000px;
+}

File diff suppressed because it is too large
+ 5188 - 0
test/qunit-2.5.0.js


+ 2 - 2
test/test-markdown-element-attributes.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Test Markdown Element Attributes</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -126,7 +126,7 @@
 		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-markdown-element-attributes.js"></script>
 

+ 21 - 23
test/test-markdown-element-attributes.js

@@ -1,46 +1,44 @@
-
-
 Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Markdown' );
 
-	test( 'Vertical separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
+	QUnit.test( 'Vertical separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
 	});
 
-
-	test( 'Attributes on element header in vertical slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
-		strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
+	QUnit.test( 'Attributes on element header in vertical slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
 	});
 
-	test( 'Attributes on element paragraphs in vertical slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
+	QUnit.test( 'Attributes on element paragraphs in vertical slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
 	});
 
-	test( 'Attributes on element list items in vertical slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.grow' ).length, 3, 'found a vertical slide with three list items with class fragment.grow' );
+	QUnit.test( 'Attributes on element list items in vertical slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.grow' ).length, 3, 'found a vertical slide with three list items with class fragment.grow' );
 	});
 
-	test( 'Attributes on element paragraphs in horizontal slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
+	QUnit.test( 'Attributes on element paragraphs in horizontal slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
 	});
-	test( 'Attributes on element list items in horizontal slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
+
+	QUnit.test( 'Attributes on element list items in horizontal slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
 	});
-	test( 'Attributes on element list items in horizontal slides', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
+
+	QUnit.test( 'Attributes on element image in horizontal slides', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
 	});
 
-	test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
+	QUnit.test( 'Attributes on elements in vertical slides with default element attribute separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
 	});
 
-	test( 'Attributes on elements in single slides with default element attribute separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
+	QUnit.test( 'Attributes on elements in single slides with default element attribute separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
 	});
 
 } );
 
 Reveal.initialize();
-

+ 3 - 3
test/test-markdown-external.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Test Markdown</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -18,7 +18,7 @@
 		<div class="reveal" style="display: none;">
 
 			<div class="slides">
-				<section data-markdown="simple.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
+				<section data-markdown="simple.md" data-separator="^\r?\n\r?\n\r?\n" data-separator-vertical="^\r?\n\r?\n"></section>
 			</div>
 
 		</div>
@@ -28,7 +28,7 @@
 		<script src="../plugin/highlight/highlight.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-markdown-external.js"></script>
 

+ 7 - 11
test/test-markdown-external.js

@@ -1,24 +1,20 @@
-
-
 Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Markdown' );
 
-	test( 'Vertical separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	QUnit.test( 'Vertical separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
 	});
 
-	test( 'Horizontal separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section' ).length, 2, 'found two slides' );
+	QUnit.test( 'Horizontal separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section' ).length, 2, 'found two slides' );
 	});
 
-	test( 'Language highlighter', function() {
-		strictEqual( document.querySelectorAll( '.hljs-keyword' ).length, 1, 'got rendered highlight tag.' );
-		strictEqual( document.querySelector( '.hljs-keyword' ).innerHTML, 'var', 'the same keyword: var.' );
+	QUnit.test( 'Language highlighter', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.hljs-keyword' ).length, 1, 'got rendered highlight tag.' );
+		assert.strictEqual( document.querySelector( '.hljs-keyword' ).innerHTML, 'var', 'the same keyword: var.' );
 	});
 
-
 } );
 
 Reveal.initialize();
-

+ 2 - 2
test/test-markdown-options.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Test Markdown Options</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -33,7 +33,7 @@
 
 		<script src="../lib/js/head.min.js"></script>
 		<script src="../js/reveal.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-markdown-options.js"></script>
 

+ 7 - 6
test/test-markdown-options.js

@@ -2,15 +2,15 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Markdown' );
 
-	test( 'Options are set', function() {
-		strictEqual( marked.defaults.smartypants, true );
+	QUnit.test( 'Options are set', function( assert ) {
+		assert.strictEqual( marked.defaults.smartypants, true );
 	});
 
-	test( 'Smart quotes are activated', function() {
+	QUnit.test( 'Smart quotes are activated', function( assert ) {
 		var text = document.querySelector( '.reveal .slides>section>p' ).textContent;
 
-		strictEqual( /['"]/.test( text ), false );
-		strictEqual( /[“”‘’]/.test( text ), true );
+		assert.strictEqual( /['"]/.test( text ), false );
+		assert.strictEqual( /[“”‘’]/.test( text ), true );
 	});
 
 } );
@@ -18,7 +18,8 @@ Reveal.addEventListener( 'ready', function() {
 Reveal.initialize({
 	dependencies: [
 		{ src: '../plugin/markdown/marked.js' },
-		{ src: '../plugin/markdown/markdown.js' },
+		// Test loading JS files with query strings
+		{ src: '../plugin/markdown/markdown.js?query=string' },
 	],
 	markdown: {
 		smartypants: true

+ 2 - 2
test/test-markdown-slide-attributes.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Test Markdown Attributes</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -120,7 +120,7 @@
 		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-markdown-slide-attributes.js"></script>
 

+ 23 - 26
test/test-markdown-slide-attributes.js

@@ -1,47 +1,44 @@
-
-
 Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Markdown' );
 
-	test( 'Vertical separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
+	QUnit.test( 'Vertical separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' );
 	});
 
-	test( 'Id on slide', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
+	QUnit.test( 'Id on slide', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' );
 	});
 
-	test( 'data-background attributes', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	QUnit.test( 'data-background attributes', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
 	});
 
-	test( 'data-transition attributes', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	QUnit.test( 'data-transition attributes', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' );
 	});
 
-	test( 'data-background attributes with default separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
+	QUnit.test( 'data-background attributes with default separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' );
 	});
 
-	test( 'data-transition attributes with default separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
-		strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
+	QUnit.test( 'data-transition attributes with default separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' );
 	});
 
-	test( 'data-transition attributes with inline content', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
+	QUnit.test( 'data-transition attributes with inline content', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' );
 	});
 
 } );
 
 Reveal.initialize();
-

+ 2 - 2
test/test-markdown.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Test Markdown</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -44,7 +44,7 @@
 		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-markdown.js"></script>
 

+ 2 - 6
test/test-markdown.js

@@ -1,15 +1,11 @@
-
-
 Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Markdown' );
 
-	test( 'Vertical separator', function() {
-		strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
+	QUnit.test( 'Vertical separator', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
 	});
 
-
 } );
 
 Reveal.initialize();
-

+ 2 - 2
test/test-pdf.html

@@ -8,7 +8,7 @@
 
 		<link rel="stylesheet" href="../css/reveal.css">
 		<link rel="stylesheet" href="../css/print/pdf.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -75,7 +75,7 @@
 
 		<script src="../lib/js/head.min.js"></script>
 		<script src="../js/reveal.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test-pdf.js"></script>
 

+ 2 - 5
test/test-pdf.js

@@ -1,15 +1,12 @@
-
 Reveal.addEventListener( 'ready', function() {
 
 	// Only one test for now, we're mainly ensuring that there
 	// are no execution errors when running PDF mode
 
-	test( 'Reveal.isReady', function() {
-		strictEqual( Reveal.isReady(), true, 'returns true' );
+	QUnit.test( 'Reveal.isReady', function( assert ) {
+		assert.strictEqual( Reveal.isReady(), true, 'returns true' );
 	});
 
-
 } );
 
 Reveal.initialize({ pdf: true });
-

+ 2 - 2
test/test.html

@@ -7,7 +7,7 @@
 		<title>reveal.js - Tests</title>
 
 		<link rel="stylesheet" href="../css/reveal.css">
-		<link rel="stylesheet" href="qunit-1.12.0.css">
+		<link rel="stylesheet" href="qunit-2.5.0.css">
 	</head>
 
 	<body style="overflow: auto;">
@@ -78,7 +78,7 @@
 
 		<script src="../lib/js/head.min.js"></script>
 		<script src="../js/reveal.js"></script>
-		<script src="qunit-1.12.0.js"></script>
+		<script src="qunit-2.5.0.js"></script>
 
 		<script src="test.js"></script>
 

+ 184 - 188
test/test.js

@@ -1,4 +1,3 @@
-
 // These tests expect the DOM to contain a presentation
 // with the following slide structure:
 //
@@ -8,7 +7,6 @@
 // 3 - Two fragments with same data-fragment-index
 // 4
 
-
 Reveal.addEventListener( 'ready', function() {
 
 	// ---------------------------------------------------------------
@@ -16,16 +14,16 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'DOM' );
 
-	test( 'Initial slides classes', function() {
+	QUnit.test( 'Initial slides classes', function( assert ) {
 		var horizontalSlides = document.querySelectorAll( '.reveal .slides>section' )
 
-		strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
-		strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
-		strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section.past' ).length, 0, 'no .past slides' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section.present' ).length, 1, 'one .present slide' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides>section.future' ).length, horizontalSlides.length - 1, 'remaining horizontal slides are .future' );
 
-		strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
+		assert.strictEqual( document.querySelectorAll( '.reveal .slides section.stack' ).length, 2, 'two .stacks' );
 
-		ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
+		assert.ok( document.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length > 0, 'vertical slides are given .future' );
 	});
 
 	// ---------------------------------------------------------------
@@ -33,203 +31,203 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'API' );
 
-	test( 'Reveal.isReady', function() {
-		strictEqual( Reveal.isReady(), true, 'returns true' );
+	QUnit.test( 'Reveal.isReady', function( assert ) {
+		assert.strictEqual( Reveal.isReady(), true, 'returns true' );
 	});
 
-	test( 'Reveal.isOverview', function() {
-		strictEqual( Reveal.isOverview(), false, 'false by default' );
+	QUnit.test( 'Reveal.isOverview', function( assert ) {
+		assert.strictEqual( Reveal.isOverview(), false, 'false by default' );
 
 		Reveal.toggleOverview();
-		strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
+		assert.strictEqual( Reveal.isOverview(), true, 'true after toggling on' );
 
 		Reveal.toggleOverview();
-		strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
+		assert.strictEqual( Reveal.isOverview(), false, 'false after toggling off' );
 	});
 
-	test( 'Reveal.isPaused', function() {
-		strictEqual( Reveal.isPaused(), false, 'false by default' );
+	QUnit.test( 'Reveal.isPaused', function( assert ) {
+		assert.strictEqual( Reveal.isPaused(), false, 'false by default' );
 
 		Reveal.togglePause();
-		strictEqual( Reveal.isPaused(), true, 'true after pausing' );
+		assert.strictEqual( Reveal.isPaused(), true, 'true after pausing' );
 
 		Reveal.togglePause();
-		strictEqual( Reveal.isPaused(), false, 'false after resuming' );
+		assert.strictEqual( Reveal.isPaused(), false, 'false after resuming' );
 	});
 
-	test( 'Reveal.isFirstSlide', function() {
+	QUnit.test( 'Reveal.isFirstSlide', function( assert ) {
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+		assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
 
 		Reveal.slide( 1, 0 );
-		strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
+		assert.strictEqual( Reveal.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
 
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
+		assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
 	});
 
-	test( 'Reveal.isFirstSlide after vertical slide', function() {
+	QUnit.test( 'Reveal.isFirstSlide after vertical slide', function( assert ) {
 		Reveal.slide( 1, 1 );
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( 0, 0 )' );
+		assert.strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( 0, 0 )' );
 	});
 
-	test( 'Reveal.isLastSlide', function() {
+	QUnit.test( 'Reveal.isLastSlide', function( assert ) {
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+		assert.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( '+ lastSlideIndex +', 0 )' );
+		assert.strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( '+ lastSlideIndex +', 0 )' );
 
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
+		assert.strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
 	});
 
-	test( 'Reveal.isLastSlide after vertical slide', function() {
+	QUnit.test( 'Reveal.isLastSlide after vertical slide', function( assert ) {
 		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
 
 		Reveal.slide( 1, 1 );
 		Reveal.slide( lastSlideIndex );
-		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( '+ lastSlideIndex +', 0 )' );
+		assert.strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( '+ lastSlideIndex +', 0 )' );
 	});
 
-	test( 'Reveal.getTotalSlides', function() {
-		strictEqual( Reveal.getTotalSlides(), 8, 'eight slides in total' );
+	QUnit.test( 'Reveal.getTotalSlides', function( assert ) {
+		assert.strictEqual( Reveal.getTotalSlides(), 8, 'eight slides in total' );
 	});
 
-	test( 'Reveal.getIndices', function() {
+	QUnit.test( 'Reveal.getIndices', function( assert ) {
 		var indices = Reveal.getIndices();
 
-		ok( indices.hasOwnProperty( 'h' ), 'h exists' );
-		ok( indices.hasOwnProperty( 'v' ), 'v exists' );
-		ok( indices.hasOwnProperty( 'f' ), 'f exists' );
+		assert.ok( indices.hasOwnProperty( 'h' ), 'h exists' );
+		assert.ok( indices.hasOwnProperty( 'v' ), 'v exists' );
+		assert.ok( indices.hasOwnProperty( 'f' ), 'f exists' );
 
 		Reveal.slide( 1, 0 );
-		strictEqual( Reveal.getIndices().h, 1, 'h 1' );
-		strictEqual( Reveal.getIndices().v, 0, 'v 0' );
+		assert.strictEqual( Reveal.getIndices().h, 1, 'h 1' );
+		assert.strictEqual( Reveal.getIndices().v, 0, 'v 0' );
 
 		Reveal.slide( 1, 2 );
-		strictEqual( Reveal.getIndices().h, 1, 'h 1' );
-		strictEqual( Reveal.getIndices().v, 2, 'v 2' );
+		assert.strictEqual( Reveal.getIndices().h, 1, 'h 1' );
+		assert.strictEqual( Reveal.getIndices().v, 2, 'v 2' );
 
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.getIndices().h, 0, 'h 0' );
-		strictEqual( Reveal.getIndices().v, 0, 'v 0' );
+		assert.strictEqual( Reveal.getIndices().h, 0, 'h 0' );
+		assert.strictEqual( Reveal.getIndices().v, 0, 'v 0' );
 	});
 
-	test( 'Reveal.getSlide', function() {
-		equal( Reveal.getSlide( 0 ), document.querySelector( '.reveal .slides>section:first-child' ), 'gets correct first slide' );
-		equal( Reveal.getSlide( 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)' ), 'no v index returns stack' );
-		equal( Reveal.getSlide( 1, 0 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(1)' ), 'v index 0 returns first vertical child' );
-		equal( Reveal.getSlide( 1, 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(2)' ), 'v index 1 returns second vertical child' );
+	QUnit.test( 'Reveal.getSlide', function( assert ) {
+		assert.equal( Reveal.getSlide( 0 ), document.querySelector( '.reveal .slides>section:first-child' ), 'gets correct first slide' );
+		assert.equal( Reveal.getSlide( 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)' ), 'no v index returns stack' );
+		assert.equal( Reveal.getSlide( 1, 0 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(1)' ), 'v index 0 returns first vertical child' );
+		assert.equal( Reveal.getSlide( 1, 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(2)' ), 'v index 1 returns second vertical child' );
 
-		strictEqual( Reveal.getSlide( 100 ), undefined, 'undefined when out of horizontal bounds' );
-		strictEqual( Reveal.getSlide( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
+		assert.strictEqual( Reveal.getSlide( 100 ), undefined, 'undefined when out of horizontal bounds' );
+		assert.strictEqual( Reveal.getSlide( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
 	});
 
-	test( 'Reveal.getSlideBackground', function() {
-		equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' );
-		equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' );
-		equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(1)' ), 'v index 0 returns first vertical child' );
-		equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 1 returns second vertical child' );
+	QUnit.test( 'Reveal.getSlideBackground', function( assert ) {
+		assert.equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' );
+		assert.equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' );
+		assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 0 returns first vertical child' );
+		assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(3)' ), 'v index 1 returns second vertical child' );
 
-		strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' );
-		strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
+		assert.strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' );
+		assert.strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
 	});
 
-	test( 'Reveal.getSlideNotes', function() {
+	QUnit.test( 'Reveal.getSlideNotes', function( assert ) {
 		Reveal.slide( 0, 0 );
-		ok( Reveal.getSlideNotes() === 'speaker notes 1', 'works with <aside class="notes">' );
+		assert.ok( Reveal.getSlideNotes() === 'speaker notes 1', 'works with <aside class="notes">' );
 
 		Reveal.slide( 1, 0 );
-		ok( Reveal.getSlideNotes() === 'speaker notes 2', 'works with <section data-notes="">' );
+		assert.ok( Reveal.getSlideNotes() === 'speaker notes 2', 'works with <section data-notes="">' );
 	});
 
-	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
+	QUnit.test( 'Reveal.getPreviousSlide/getCurrentSlide', function( assert ) {
 		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' );
+		assert.equal( Reveal.getPreviousSlide(), firstSlide, 'previous is slide #0' );
+		assert.equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
 	});
 
-	test( 'Reveal.getProgress', function() {
+	QUnit.test( 'Reveal.getProgress', function( assert ) {
 		Reveal.slide( 0, 0 );
-		strictEqual( Reveal.getProgress(), 0, 'progress is 0 on first slide' );
+		assert.strictEqual( Reveal.getProgress(), 0, 'progress is 0 on first slide' );
 
 		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
 
 		Reveal.slide( lastSlideIndex, 0 );
-		strictEqual( Reveal.getProgress(), 1, 'progress is 1 on last slide' );
+		assert.strictEqual( Reveal.getProgress(), 1, 'progress is 1 on last slide' );
 	});
 
-	test( 'Reveal.getScale', function() {
-		ok( typeof Reveal.getScale() === 'number', 'has scale' );
+	QUnit.test( 'Reveal.getScale', function( assert ) {
+		assert.ok( typeof Reveal.getScale() === 'number', 'has scale' );
 	});
 
-	test( 'Reveal.getConfig', function() {
-		ok( typeof Reveal.getConfig() === 'object', 'has config' );
+	QUnit.test( 'Reveal.getConfig', function( assert ) {
+		assert.ok( typeof Reveal.getConfig() === 'object', 'has config' );
 	});
 
-	test( 'Reveal.configure', function() {
-		strictEqual( Reveal.getConfig().loop, false, '"loop" is false to start with' );
+	QUnit.test( 'Reveal.configure', function( assert ) {
+		assert.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' );
+		assert.strictEqual( Reveal.getConfig().loop, true, '"loop" has changed to true' );
 
 		Reveal.configure({ loop: false, customTestValue: 1 });
-		strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
+		assert.strictEqual( Reveal.getConfig().customTestValue, 1, 'supports custom values' );
 	});
 
-	test( 'Reveal.availableRoutes', function() {
+	QUnit.test( 'Reveal.availableRoutes', function( assert ) {
 		Reveal.slide( 0, 0 );
-		deepEqual( Reveal.availableRoutes(), { left: false, up: false, down: false, right: true }, 'correct for first slide' );
+		assert.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' );
+		assert.deepEqual( Reveal.availableRoutes(), { left: true, up: false, down: true, right: true }, 'correct for vertical slide' );
 	});
 
-	test( 'Reveal.next', function() {
+	QUnit.test( 'Reveal.next', function( assert ) {
 		Reveal.slide( 0, 0 );
 
 		// Step through vertical child slides
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
+		assert.deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
+		assert.deepEqual( Reveal.getIndices(), { h: 1, v: 1, f: undefined } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
+		assert.deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } );
 
 		// Step through fragments
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } );
 	});
 
-	test( 'Reveal.next at end', function() {
+	QUnit.test( 'Reveal.next at end', function( assert ) {
 		Reveal.slide( 3 );
 
 		// We're at the end, this should have no effect
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+		assert.deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
+		assert.deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } );
 	});
 
 
@@ -238,121 +236,123 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Fragments' );
 
-	test( 'Sliding to fragments', function() {
+	QUnit.test( 'Sliding to fragments', function( assert ) {
 		Reveal.slide( 2, 0, -1 );
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' );
 
 		Reveal.slide( 2, 0, 0 );
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' );
+		assert.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 )' );
+		assert.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 )' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' );
 	});
 
-	test( 'Hiding all fragments', function() {
+	QUnit.test( 'Hiding all fragments', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
 
 		Reveal.slide( 2, 0, 0 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' );
 
 		Reveal.slide( 2, 0, -1 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' );
 	});
 
-	test( 'Current fragment', function() {
+	QUnit.test( 'Current fragment', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
 
 		Reveal.slide( 2, 0 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
 
 		Reveal.slide( 2, 0, 0 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' );
 
 		Reveal.slide( 1, 0, 0 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' );
 
 		Reveal.slide( 3, 0, 0 );
-		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
 	});
 
-	test( 'Stepping through fragments', function() {
+	QUnit.test( 'Stepping through fragments', function( assert ) {
 		Reveal.slide( 2, 0, -1 );
 
 		// forwards:
 
 		Reveal.next();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' );
 
 		Reveal.right();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' );
 
 		Reveal.down();
-		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, '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' );
+		assert.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' );
+		assert.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 }, 'up() goes to prev fragment' );
+		assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' );
 	});
 
-	test( 'Stepping past fragments', function() {
+	QUnit.test( 'Stepping past fragments', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
 
 		Reveal.slide( 0, 0, 0 );
-		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' );
 
 		Reveal.slide( 3, 0, 0 );
-		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' );
 	});
 
-	test( 'Fragment indices', function() {
+	QUnit.test( 'Fragment indices', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' );
 
 		Reveal.slide( 3, 0, 0 );
-		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' );
 
 		// This slide has three fragments, first one is index 0, second and third have index 1
 		Reveal.slide( 2, 2, 0 );
-		equal( Reveal.getIndices().f, 0, 'returns correct index for first fragment' );
+		assert.equal( Reveal.getIndices().f, 0, 'returns correct index for first fragment' );
 
 		Reveal.slide( 2, 2, 1 );
-		equal( Reveal.getIndices().f, 1, 'returns correct index for two fragments with same index' );
+		assert.equal( Reveal.getIndices().f, 1, 'returns correct index for two fragments with same index' );
 	});
 
-	test( 'Index generation', function() {
+	QUnit.test( 'Index generation', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
 
 		// These have no indices defined to start with
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
 	});
 
-	test( 'Index normalization', function() {
+	QUnit.test( 'Index normalization', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' );
 
 		// These start out as 1-4-4 and should normalize to 0-1-1
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
-		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
+		assert.equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
 	});
 
-	asyncTest( 'fragmentshown event', function() {
-		expect( 2 );
+	QUnit.test( 'fragmentshown event', function( assert ) {
+		assert.expect( 2 );
+		var done = assert.async( 2 );
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'fragmentshown', _onEvent );
@@ -364,16 +364,16 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.next();
 		Reveal.prev(); // shouldn't fire fragmentshown
 
-		start();
-
 		Reveal.removeEventListener( 'fragmentshown', _onEvent );
 	});
 
-	asyncTest( 'fragmenthidden event', function() {
-		expect( 2 );
+	QUnit.test( 'fragmenthidden event', function( assert ) {
+		assert.expect( 2 );
+		var done = assert.async( 2 );
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'fragmenthidden', _onEvent );
@@ -384,8 +384,6 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.prev();
 		Reveal.next(); // shouldn't fire fragmenthidden
 
-		start();
-
 		Reveal.removeEventListener( 'fragmenthidden', _onEvent );
 	});
 
@@ -395,50 +393,52 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Auto Sliding' );
 
-	test( 'Reveal.isAutoSliding', function() {
-		strictEqual( Reveal.isAutoSliding(), false, 'false by default' );
+	QUnit.test( 'Reveal.isAutoSliding', function( assert ) {
+		assert.strictEqual( Reveal.isAutoSliding(), false, 'false by default' );
 
 		Reveal.configure({ autoSlide: 10000 });
-		strictEqual( Reveal.isAutoSliding(), true, 'true after starting' );
+		assert.strictEqual( Reveal.isAutoSliding(), true, 'true after starting' );
 
 		Reveal.configure({ autoSlide: 0 });
-		strictEqual( Reveal.isAutoSliding(), false, 'false after setting to 0' );
+		assert.strictEqual( Reveal.isAutoSliding(), false, 'false after setting to 0' );
 	});
 
-	test( 'Reveal.toggleAutoSlide', function() {
+	QUnit.test( 'Reveal.toggleAutoSlide', function( assert ) {
 		Reveal.configure({ autoSlide: 10000 });
 
 		Reveal.toggleAutoSlide();
-		strictEqual( Reveal.isAutoSliding(), false, 'false after first toggle' );
+		assert.strictEqual( Reveal.isAutoSliding(), false, 'false after first toggle' );
 		Reveal.toggleAutoSlide();
-		strictEqual( Reveal.isAutoSliding(), true, 'true after second toggle' );
+		assert.strictEqual( Reveal.isAutoSliding(), true, 'true after second toggle' );
 
 		Reveal.configure({ autoSlide: 0 });
 	});
 
-	asyncTest( 'autoslidepaused', function() {
-		expect( 1 );
+	QUnit.test( 'autoslidepaused', function( assert ) {
+		assert.expect( 1 );
+		var done = assert.async();
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'autoslidepaused', _onEvent );
 		Reveal.configure({ autoSlide: 10000 });
 		Reveal.toggleAutoSlide();
 
-		start();
-
 		// cleanup
 		Reveal.configure({ autoSlide: 0 });
 		Reveal.removeEventListener( 'autoslidepaused', _onEvent );
 	});
 
-	asyncTest( 'autoslideresumed', function() {
-		expect( 1 );
+	QUnit.test( 'autoslideresumed', function( assert ) {
+		assert.expect( 1 );
+		var done = assert.async();
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'autoslideresumed', _onEvent );
@@ -446,8 +446,6 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.toggleAutoSlide();
 		Reveal.toggleAutoSlide();
 
-		start();
-
 		// cleanup
 		Reveal.configure({ autoSlide: 0 });
 		Reveal.removeEventListener( 'autoslideresumed', _onEvent );
@@ -459,36 +457,36 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Configuration' );
 
-	test( 'Controls', function() {
+	QUnit.test( 'Controls', function( assert ) {
 		var controlsElement = document.querySelector( '.reveal>.controls' );
 
 		Reveal.configure({ controls: false });
-		equal( controlsElement.style.display, 'none', 'controls are hidden' );
+		assert.equal( controlsElement.style.display, 'none', 'controls are hidden' );
 
 		Reveal.configure({ controls: true });
-		equal( controlsElement.style.display, 'block', 'controls are visible' );
+		assert.equal( controlsElement.style.display, 'block', 'controls are visible' );
 	});
 
-	test( 'Progress', function() {
+	QUnit.test( 'Progress', function( assert ) {
 		var progressElement = document.querySelector( '.reveal>.progress' );
 
 		Reveal.configure({ progress: false });
-		equal( progressElement.style.display, 'none', 'progress are hidden' );
+		assert.equal( progressElement.style.display, 'none', 'progress are hidden' );
 
 		Reveal.configure({ progress: true });
-		equal( progressElement.style.display, 'block', 'progress are visible' );
+		assert.equal( progressElement.style.display, 'block', 'progress are visible' );
 	});
 
-	test( 'Loop', function() {
+	QUnit.test( 'Loop', function( assert ) {
 		Reveal.configure({ loop: true });
 
 		Reveal.slide( 0, 0 );
 
 		Reveal.left();
-		notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
+		assert.notEqual( Reveal.getIndices().h, 0, 'looped from start to end' );
 
 		Reveal.right();
-		equal( Reveal.getIndices().h, 0, 'looped from end to start' );
+		assert.equal( Reveal.getIndices().h, 0, 'looped from end to start' );
 
 		Reveal.configure({ loop: false });
 	});
@@ -499,34 +497,34 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Lazy-Loading' );
 
-	test( 'img with data-src', function() {
-		strictEqual( document.querySelectorAll( '.reveal section img[src]' ).length, 1, 'Image source has been set' );
+	QUnit.test( 'img with data-src', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal section img[src]' ).length, 1, 'Image source has been set' );
 	});
 
-	test( 'video with data-src', function() {
-		strictEqual( document.querySelectorAll( '.reveal section video[src]' ).length, 1, 'Video source has been set' );
+	QUnit.test( 'video with data-src', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal section video[src]' ).length, 1, 'Video source has been set' );
 	});
 
-	test( 'audio with data-src', function() {
-		strictEqual( document.querySelectorAll( '.reveal section audio[src]' ).length, 1, 'Audio source has been set' );
+	QUnit.test( 'audio with data-src', function( assert ) {
+		assert.strictEqual( document.querySelectorAll( '.reveal section audio[src]' ).length, 1, 'Audio source has been set' );
 	});
 
-	test( 'iframe with data-src', function() {
+	QUnit.test( 'iframe with data-src', function( assert ) {
 		Reveal.slide( 0, 0 );
-		strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
+		assert.strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
 		Reveal.slide( 2, 1 );
-		strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 1, 'Iframe source is set' );
+		assert.strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 1, 'Iframe source is set' );
 		Reveal.slide( 2, 2 );
-		strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
+		assert.strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
 	});
 
-	test( 'background images', function() {
+	QUnit.test( 'background images', function( assert ) {
 		var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' );
 		var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
 
 		// check that the images are applied to the background elements
-		ok( Reveal.getSlideBackground( 0 ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' );
-		ok( Reveal.getSlideBackground( 1, 0 ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
+		assert.ok( Reveal.getSlideBackground( 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' );
+		assert.ok( Reveal.getSlideBackground( 1, 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
 	});
 
 
@@ -535,11 +533,13 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.module( 'Events' );
 
-	asyncTest( 'slidechanged', function() {
-		expect( 3 );
+	QUnit.test( 'slidechanged', function( assert ) {
+		assert.expect( 3 );
+		var done = assert.async( 3 );
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'slidechanged', _onEvent );
@@ -550,17 +550,17 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.slide( 3, 0 ); // should trigger
 		Reveal.next(); // should do nothing
 
-		start();
-
 		Reveal.removeEventListener( 'slidechanged', _onEvent );
 
 	});
 
-	asyncTest( 'paused', function() {
-		expect( 1 );
+	QUnit.test( 'paused', function( assert ) {
+		assert.expect( 1 );
+		var done = assert.async();
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'paused', _onEvent );
@@ -568,16 +568,16 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.togglePause();
 		Reveal.togglePause();
 
-		start();
-
 		Reveal.removeEventListener( 'paused', _onEvent );
 	});
 
-	asyncTest( 'resumed', function() {
-		expect( 1 );
+	QUnit.test( 'resumed', function( assert ) {
+		assert.expect( 1 );
+		var done = assert.async();
 
 		var _onEvent = function( event ) {
-			ok( true, 'event fired' );
+			assert.ok( true, 'event fired' );
+			done();
 		}
 
 		Reveal.addEventListener( 'resumed', _onEvent );
@@ -585,13 +585,9 @@ Reveal.addEventListener( 'ready', function() {
 		Reveal.togglePause();
 		Reveal.togglePause();
 
-		start();
-
 		Reveal.removeEventListener( 'resumed', _onEvent );
 	});
 
-
 } );
 
 Reveal.initialize();
-