Browse Source

Merge branch 'dev' into plugin-key-bindings

Greg Denehy 7 năm trước cách đây
mục cha
commit
f8bc679182
52 tập tin đã thay đổi với 2824 bổ sung1096 xóa
  1. 6 1
      .gitignore
  2. 27 11
      Gruntfile.js
  3. 1 1
      LICENSE
  4. 271 68
      README.md
  5. 1 1
      bower.json
  6. 3 2
      css/print/paper.css
  7. 28 16
      css/print/pdf.css
  8. 124 75
      css/reveal.css
  9. 122 32
      css/reveal.scss
  10. 14 8
      css/theme/beige.css
  11. 15 9
      css/theme/black.css
  12. 14 8
      css/theme/blood.css
  13. 14 8
      css/theme/league.css
  14. 14 8
      css/theme/moon.css
  15. 14 8
      css/theme/night.css
  16. 14 8
      css/theme/serif.css
  17. 17 8
      css/theme/simple.css
  18. 14 8
      css/theme/sky.css
  19. 14 8
      css/theme/solarized.css
  20. 2 2
      css/theme/source/black.scss
  21. 0 1
      css/theme/source/blood.scss
  22. 0 1
      css/theme/source/night.scss
  23. 5 0
      css/theme/source/simple.scss
  24. 2 2
      css/theme/source/white.scss
  25. 1 1
      css/theme/template/settings.scss
  26. 8 1
      css/theme/template/theme.scss
  27. 15 9
      css/theme/white.css
  28. 410 0
      demo.html
  29. 14 376
      index.html
  30. 702 277
      js/reveal.js
  31. 9 8
      lib/js/head.min.js
  32. 17 18
      package.json
  33. 48 1
      plugin/highlight/highlight.js
  34. 28 18
      plugin/markdown/markdown.js
  35. 1 1
      plugin/markdown/marked.js
  36. 1 1
      plugin/math/math.js
  37. 9 1
      plugin/multiplex/index.js
  38. 19 0
      plugin/multiplex/package.json
  39. 3 2
      plugin/notes-server/index.js
  40. 198 20
      plugin/notes-server/notes.html
  41. 371 32
      plugin/notes/notes.html
  42. 34 6
      plugin/notes/notes.js
  43. 47 26
      plugin/print-pdf/print-pdf.js
  44. 11 1
      plugin/zoom-js/zoom.js
  45. 1 1
      test/examples/math.html
  46. 1 1
      test/examples/slide-backgrounds.html
  47. 12 0
      test/simple.md
  48. 36 0
      test/test-markdown-external.html
  49. 24 0
      test/test-markdown-external.js
  50. 41 0
      test/test-markdown-options.html
  51. 26 0
      test/test-markdown-options.js
  52. 1 1
      test/test-markdown.html

+ 6 - 1
.gitignore

@@ -1,3 +1,8 @@
+.idea/
+*.iml
+*.iws
+*.eml
+out/
 .DS_Store
 .svn
 log/*.log
@@ -5,4 +10,4 @@ tmp/**
 node_modules/
 .sass-cache
 css/reveal.min.css
-js/reveal.min.js
+js/reveal.min.js

+ 27 - 11
Gruntfile.js

@@ -1,7 +1,9 @@
 /* global module:false */
 module.exports = function(grunt) {
 	var port = grunt.option('port') || 8000;
-	var base = grunt.option('base') || '.';
+	var root = grunt.option('root') || '.';
+
+	if (!Array.isArray(root)) root = [root];
 
 	// Project configuration
 	grunt.initConfig({
@@ -13,7 +15,7 @@ module.exports = function(grunt) {
 				' * http://lab.hakim.se/reveal-js\n' +
 				' * MIT licensed\n' +
 				' *\n' +
-				' * Copyright (C) 2015 Hakim El Hattab, http://hakim.se\n' +
+				' * Copyright (C) 2017 Hakim El Hattab, http://hakim.se\n' +
 				' */'
 		},
 
@@ -42,7 +44,7 @@ module.exports = function(grunt) {
 					{
 						expand: true,
 						cwd: 'css/theme/source',
-						src: ['*.scss'],
+						src: ['*.sass', '*.scss'],
 						dest: 'css/theme',
 						ext: '.css'
 					}
@@ -69,6 +71,7 @@ module.exports = function(grunt) {
 				curly: false,
 				eqeqeq: true,
 				immed: true,
+				esnext: true,
 				latedef: true,
 				newcap: true,
 				noarg: true,
@@ -93,11 +96,12 @@ module.exports = function(grunt) {
 			server: {
 				options: {
 					port: port,
-					base: base,
+					base: root,
 					livereload: true,
 					open: true
 				}
-			}
+			},
+
 		},
 
 		zip: {
@@ -113,15 +117,17 @@ module.exports = function(grunt) {
 		},
 
 		watch: {
-			options: {
-				livereload: true
-			},
 			js: {
 				files: [ 'Gruntfile.js', 'js/reveal.js' ],
 				tasks: 'js'
 			},
 			theme: {
-				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+				files: [
+					'css/theme/source/*.sass',
+					'css/theme/source/*.scss',
+					'css/theme/template/*.sass',
+					'css/theme/template/*.scss'
+				],
 				tasks: 'css-themes'
 			},
 			css: {
@@ -129,11 +135,20 @@ module.exports = function(grunt) {
 				tasks: 'css-core'
 			},
 			html: {
-				files: [ 'index.html']
+				files: root.map(path => path + '/*.html')
 			},
 			markdown: {
-				files: [ './*.md' ]
+				files: root.map(path => path + '/*.md')
+			},
+			options: {
+				livereload: true
 			}
+		},
+
+		retire: {
+			js: ['js/reveal.js', 'lib/js/*.js', 'plugin/**/*.js'],
+			node: ['.'],
+			options: {}
 		}
 
 	});
@@ -148,6 +163,7 @@ module.exports = function(grunt) {
 	grunt.loadNpmTasks( 'grunt-contrib-connect' );
 	grunt.loadNpmTasks( 'grunt-autoprefixer' );
 	grunt.loadNpmTasks( 'grunt-zip' );
+	grunt.loadNpmTasks( 'grunt-retire' );
 
 	// Default task
 	grunt.registerTask( 'default', [ 'css', 'js' ] );

+ 1 - 1
LICENSE

@@ -1,4 +1,4 @@
-Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+Copyright (C) 2017 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

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 271 - 68
README.md


+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "reveal.js",
-  "version": "3.2.0",
+  "version": "3.5.0",
   "main": [
     "js/reveal.js",
     "css/reveal.css"

+ 3 - 2
css/print/paper.css

@@ -38,7 +38,8 @@
 	.share-reveal,
 	.state-background,
 	.reveal .progress,
-	.reveal .backgrounds {
+	.reveal .backgrounds,
+	.reveal .slide-number {
 		display: none !important;
 	}
 
@@ -199,4 +200,4 @@
 		font-size: 0.8em;
 	}
 
-}
+}

+ 28 - 16
css/print/pdf.css

@@ -60,8 +60,9 @@ ul, ol, div, p {
 }
 .reveal .slides {
 	position: static;
-	width: 100%;
-	height: auto;
+	width: 100% !important;
+	height: auto !important;
+	zoom: 1 !important;
 
 	left: auto;
 	top: auto;
@@ -82,13 +83,18 @@ ul, ol, div, p {
 	        perspective-origin: 50% 50%;
 }
 
-.reveal .slides section {
-	page-break-after: always !important;
+.reveal .slides .pdf-page {
+	position: relative;
+	overflow: hidden;
+	z-index: 1;
 
+	page-break-after: always;
+}
+
+.reveal .slides section {
 	visibility: visible !important;
-	position: relative !important;
 	display: block !important;
-	position: relative !important;
+	position: absolute !important;
 
 	margin: 0 !important;
 	padding: 0 !important;
@@ -109,6 +115,7 @@ ul, ol, div, p {
 }
 
 .reveal section.stack {
+	position: relative !important;
 	margin: 0 !important;
 	padding: 0 !important;
 	page-break-after: avoid !important;
@@ -126,19 +133,14 @@ ul, ol, div, p {
 }
 
 /* Slide backgrounds are placed inside of their slide when exporting to PDF */
-.reveal section .slide-background {
+.reveal .slide-background {
 	display: block !important;
 	position: absolute;
 	top: 0;
 	left: 0;
 	width: 100%;
-	z-index: -1;
-}
-
-/* All elements should be above the slide-background */
-.reveal section>* {
-	position: relative;
-	z-index: 1;
+	height: 100%;
+	z-index: auto !important;
 }
 
 /* Display slide speaker notes when 'showNotes' is enabled */
@@ -146,15 +148,25 @@ ul, ol, div, p {
 	display: block;
 	width: 100%;
 	max-height: none;
-	left: auto;
 	top: auto;
+	right: auto;
+	bottom: auto;
+	left: auto;
 	z-index: 100;
 }
 
+/* Layout option which makes notes appear on a separate page */
+.reveal .speaker-notes-pdf[data-layout="separate-page"] {
+	position: relative;
+	color: inherit;
+	background-color: transparent;
+	padding: 20px;
+	page-break-after: always;
+}
+
 /* Display slide numbers when 'slideNumber' is enabled */
 .reveal .slide-number-pdf {
 	display: block;
 	position: absolute;
 	font-size: 14px;
 }
-

+ 124 - 75
css/reveal.css

@@ -3,7 +3,7 @@
  * http://lab.hakim.se/reveal-js
  * MIT licensed
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
  */
 /*********************************************
  * RESET STYLES
@@ -20,7 +20,7 @@ html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal i
 .reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed,
 .reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup,
 .reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary,
-.reveal time, .reveal mark, .reveal audio, video {
+.reveal time, .reveal mark, .reveal audio, .reveal video {
   margin: 0;
   padding: 0;
   border: 0;
@@ -47,75 +47,93 @@ body {
   background-color: #fff;
   color: #000; }
 
-html:-webkit-full-screen-ancestor {
-  background-color: inherit; }
-
-html:-moz-full-screen-ancestor {
-  background-color: inherit; }
-
 /*********************************************
  * VIEW FRAGMENTS
  *********************************************/
 .reveal .slides section .fragment {
   opacity: 0;
   visibility: hidden;
-  -webkit-transition: all 0.2s ease;
-          transition: all 0.2s ease; }
+  -webkit-transition: all .2s ease;
+          transition: all .2s ease; }
   .reveal .slides section .fragment.visible {
     opacity: 1;
-    visibility: visible; }
+    visibility: inherit; }
 
 .reveal .slides section .fragment.grow {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
   .reveal .slides section .fragment.grow.visible {
     -webkit-transform: scale(1.3);
-        -ms-transform: scale(1.3);
             transform: scale(1.3); }
 
 .reveal .slides section .fragment.shrink {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
   .reveal .slides section .fragment.shrink.visible {
     -webkit-transform: scale(0.7);
-        -ms-transform: scale(0.7);
             transform: scale(0.7); }
 
 .reveal .slides section .fragment.zoom-in {
   -webkit-transform: scale(0.1);
-      -ms-transform: scale(0.1);
           transform: scale(0.1); }
   .reveal .slides section .fragment.zoom-in.visible {
     -webkit-transform: none;
-        -ms-transform: none;
             transform: none; }
 
 .reveal .slides section .fragment.fade-out {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
   .reveal .slides section .fragment.fade-out.visible {
     opacity: 0;
     visibility: hidden; }
 
 .reveal .slides section .fragment.semi-fade-out {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
   .reveal .slides section .fragment.semi-fade-out.visible {
     opacity: 0.5;
-    visibility: visible; }
+    visibility: inherit; }
 
 .reveal .slides section .fragment.strike {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
   .reveal .slides section .fragment.strike.visible {
     text-decoration: line-through; }
 
+.reveal .slides section .fragment.fade-up {
+  -webkit-transform: translate(0, 20%);
+          transform: translate(0, 20%); }
+  .reveal .slides section .fragment.fade-up.visible {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0); }
+
+.reveal .slides section .fragment.fade-down {
+  -webkit-transform: translate(0, -20%);
+          transform: translate(0, -20%); }
+  .reveal .slides section .fragment.fade-down.visible {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0); }
+
+.reveal .slides section .fragment.fade-right {
+  -webkit-transform: translate(-20%, 0);
+          transform: translate(-20%, 0); }
+  .reveal .slides section .fragment.fade-right.visible {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0); }
+
+.reveal .slides section .fragment.fade-left {
+  -webkit-transform: translate(20%, 0);
+          transform: translate(20%, 0); }
+  .reveal .slides section .fragment.fade-left.visible {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0); }
+
 .reveal .slides section .fragment.current-visible {
   opacity: 0;
   visibility: hidden; }
   .reveal .slides section .fragment.current-visible.current-fragment {
     opacity: 1;
-    visibility: visible; }
+    visibility: inherit; }
 
 .reveal .slides section .fragment.highlight-red,
 .reveal .slides section .fragment.highlight-current-red,
@@ -124,7 +142,7 @@ html:-moz-full-screen-ancestor {
 .reveal .slides section .fragment.highlight-blue,
 .reveal .slides section .fragment.highlight-current-blue {
   opacity: 1;
-  visibility: visible; }
+  visibility: inherit; }
 
 .reveal .slides section .fragment.highlight-red.visible {
   color: #ff2c2d; }
@@ -190,7 +208,6 @@ html:-moz-full-screen-ancestor {
   background-color: transparent;
   border: 12px solid transparent;
   -webkit-transform: scale(0.9999);
-      -ms-transform: scale(0.9999);
           transform: scale(0.9999);
   -webkit-transition: all 0.2s ease;
           transition: all 0.2s ease;
@@ -306,6 +323,7 @@ html:-moz-full-screen-ancestor {
   bottom: 0;
   left: 0;
   margin: auto;
+  pointer-events: none;
   overflow: visible;
   z-index: 1;
   text-align: center;
@@ -323,11 +341,11 @@ html:-moz-full-screen-ancestor {
   position: absolute;
   width: 100%;
   padding: 20px 0px;
+  pointer-events: auto;
   z-index: 10;
-  -webkit-transform-style: preserve-3d;
-          transform-style: preserve-3d;
+  -webkit-transform-style: flat;
+          transform-style: flat;
   -webkit-transition: -webkit-transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), -webkit-transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-          transition: -ms-transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
           transition: transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /* Global transition speed settings */
@@ -358,6 +376,12 @@ html:-moz-full-screen-ancestor {
   z-index: 11;
   opacity: 1; }
 
+.reveal .slides > section:empty,
+.reveal .slides > section > section:empty,
+.reveal .slides > section[data-background-interactive],
+.reveal .slides > section > section[data-background-interactive] {
+  pointer-events: none; }
+
 .reveal.center,
 .reveal.center .slides,
 .reveal.center .slides section {
@@ -395,28 +419,24 @@ html:-moz-full-screen-ancestor {
 .reveal .slides > section[data-transition~=slide-out].past,
 .reveal.slide .slides > section:not([data-transition]).past {
   -webkit-transform: translate(-150%, 0);
-      -ms-transform: translate(-150%, 0);
           transform: translate(-150%, 0); }
 
 .reveal .slides > section[data-transition=slide].future,
 .reveal .slides > section[data-transition~=slide-in].future,
 .reveal.slide .slides > section:not([data-transition]).future {
   -webkit-transform: translate(150%, 0);
-      -ms-transform: translate(150%, 0);
           transform: translate(150%, 0); }
 
 .reveal .slides > section > section[data-transition=slide].past,
 .reveal .slides > section > section[data-transition~=slide-out].past,
 .reveal.slide .slides > section > section:not([data-transition]).past {
   -webkit-transform: translate(0, -150%);
-      -ms-transform: translate(0, -150%);
           transform: translate(0, -150%); }
 
 .reveal .slides > section > section[data-transition=slide].future,
 .reveal .slides > section > section[data-transition~=slide-in].future,
 .reveal.slide .slides > section > section:not([data-transition]).future {
   -webkit-transform: translate(0, 150%);
-      -ms-transform: translate(0, 150%);
           transform: translate(0, 150%); }
 
 .reveal.linear section {
@@ -427,34 +447,35 @@ html:-moz-full-screen-ancestor {
 .reveal .slides > section[data-transition~=linear-out].past,
 .reveal.linear .slides > section:not([data-transition]).past {
   -webkit-transform: translate(-150%, 0);
-      -ms-transform: translate(-150%, 0);
           transform: translate(-150%, 0); }
 
 .reveal .slides > section[data-transition=linear].future,
 .reveal .slides > section[data-transition~=linear-in].future,
 .reveal.linear .slides > section:not([data-transition]).future {
   -webkit-transform: translate(150%, 0);
-      -ms-transform: translate(150%, 0);
           transform: translate(150%, 0); }
 
 .reveal .slides > section > section[data-transition=linear].past,
 .reveal .slides > section > section[data-transition~=linear-out].past,
 .reveal.linear .slides > section > section:not([data-transition]).past {
   -webkit-transform: translate(0, -150%);
-      -ms-transform: translate(0, -150%);
           transform: translate(0, -150%); }
 
 .reveal .slides > section > section[data-transition=linear].future,
 .reveal .slides > section > section[data-transition~=linear-in].future,
 .reveal.linear .slides > section > section:not([data-transition]).future {
   -webkit-transform: translate(0, 150%);
-      -ms-transform: translate(0, 150%);
           transform: translate(0, 150%); }
 
 /*********************************************
  * CONVEX TRANSITION
  * Aliased 'default' for backwards compatibility
  *********************************************/
+.reveal .slides section[data-transition=default].stack,
+.reveal.default .slides section.stack {
+  -webkit-transform-style: preserve-3d;
+          transform-style: preserve-3d; }
+
 .reveal .slides > section[data-transition=default].past,
 .reveal .slides > section[data-transition~=default-out].past,
 .reveal.default .slides > section:not([data-transition]).past {
@@ -479,6 +500,11 @@ html:-moz-full-screen-ancestor {
   -webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0);
           transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); }
 
+.reveal .slides section[data-transition=convex].stack,
+.reveal.convex .slides section.stack {
+  -webkit-transform-style: preserve-3d;
+          transform-style: preserve-3d; }
+
 .reveal .slides > section[data-transition=convex].past,
 .reveal .slides > section[data-transition~=convex-out].past,
 .reveal.convex .slides > section:not([data-transition]).past {
@@ -506,6 +532,11 @@ html:-moz-full-screen-ancestor {
 /*********************************************
  * CONCAVE TRANSITION
  *********************************************/
+.reveal .slides section[data-transition=concave].stack,
+.reveal.concave .slides section.stack {
+  -webkit-transform-style: preserve-3d;
+          transform-style: preserve-3d; }
+
 .reveal .slides > section[data-transition=concave].past,
 .reveal .slides > section[data-transition~=concave-out].past,
 .reveal.concave .slides > section:not([data-transition]).past {
@@ -543,7 +574,6 @@ html:-moz-full-screen-ancestor {
 .reveal.zoom .slides > section:not([data-transition]).past {
   visibility: hidden;
   -webkit-transform: scale(16);
-      -ms-transform: scale(16);
           transform: scale(16); }
 
 .reveal .slides > section[data-transition=zoom].future,
@@ -551,25 +581,26 @@ html:-moz-full-screen-ancestor {
 .reveal.zoom .slides > section:not([data-transition]).future {
   visibility: hidden;
   -webkit-transform: scale(0.2);
-      -ms-transform: scale(0.2);
           transform: scale(0.2); }
 
 .reveal .slides > section > section[data-transition=zoom].past,
 .reveal .slides > section > section[data-transition~=zoom-out].past,
 .reveal.zoom .slides > section > section:not([data-transition]).past {
   -webkit-transform: translate(0, -150%);
-      -ms-transform: translate(0, -150%);
           transform: translate(0, -150%); }
 
 .reveal .slides > section > section[data-transition=zoom].future,
 .reveal .slides > section > section[data-transition~=zoom-in].future,
 .reveal.zoom .slides > section > section:not([data-transition]).future {
   -webkit-transform: translate(0, 150%);
-      -ms-transform: translate(0, 150%);
           transform: translate(0, 150%); }
 
 /*********************************************
  * CUBE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
  *********************************************/
 .reveal.cube .slides {
   -webkit-perspective: 1300px;
@@ -580,7 +611,9 @@ html:-moz-full-screen-ancestor {
   min-height: 700px;
   -webkit-backface-visibility: hidden;
           backface-visibility: hidden;
-  box-sizing: border-box; }
+  box-sizing: border-box;
+  -webkit-transform-style: preserve-3d;
+          transform-style: preserve-3d; }
 
 .reveal.center.cube .slides section {
   min-height: 0; }
@@ -619,34 +652,34 @@ html:-moz-full-screen-ancestor {
 
 .reveal.cube .slides > section.past {
   -webkit-transform-origin: 100% 0%;
-      -ms-transform-origin: 100% 0%;
           transform-origin: 100% 0%;
   -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg);
           transform: translate3d(-100%, 0, 0) rotateY(-90deg); }
 
 .reveal.cube .slides > section.future {
   -webkit-transform-origin: 0% 0%;
-      -ms-transform-origin: 0% 0%;
           transform-origin: 0% 0%;
   -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg);
           transform: translate3d(100%, 0, 0) rotateY(90deg); }
 
 .reveal.cube .slides > section > section.past {
   -webkit-transform-origin: 0% 100%;
-      -ms-transform-origin: 0% 100%;
           transform-origin: 0% 100%;
   -webkit-transform: translate3d(0, -100%, 0) rotateX(90deg);
           transform: translate3d(0, -100%, 0) rotateX(90deg); }
 
 .reveal.cube .slides > section > section.future {
   -webkit-transform-origin: 0% 0%;
-      -ms-transform-origin: 0% 0%;
           transform-origin: 0% 0%;
   -webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg);
           transform: translate3d(0, 100%, 0) rotateX(-90deg); }
 
 /*********************************************
  * PAGE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
  *********************************************/
 .reveal.page .slides {
   -webkit-perspective-origin: 0% 50%;
@@ -657,7 +690,9 @@ html:-moz-full-screen-ancestor {
 .reveal.page .slides section {
   padding: 30px;
   min-height: 700px;
-  box-sizing: border-box; }
+  box-sizing: border-box;
+  -webkit-transform-style: preserve-3d;
+          transform-style: preserve-3d; }
 
 .reveal.page .slides section.past {
   z-index: 12; }
@@ -694,28 +729,24 @@ html:-moz-full-screen-ancestor {
 
 .reveal.page .slides > section.past {
   -webkit-transform-origin: 0% 0%;
-      -ms-transform-origin: 0% 0%;
           transform-origin: 0% 0%;
   -webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg);
           transform: translate3d(-40%, 0, 0) rotateY(-80deg); }
 
 .reveal.page .slides > section.future {
   -webkit-transform-origin: 100% 0%;
-      -ms-transform-origin: 100% 0%;
           transform-origin: 100% 0%;
   -webkit-transform: translate3d(0, 0, 0);
           transform: translate3d(0, 0, 0); }
 
 .reveal.page .slides > section > section.past {
   -webkit-transform-origin: 0% 0%;
-      -ms-transform-origin: 0% 0%;
           transform-origin: 0% 0%;
   -webkit-transform: translate3d(0, -40%, 0) rotateX(80deg);
           transform: translate3d(0, -40%, 0) rotateX(80deg); }
 
 .reveal.page .slides > section > section.future {
   -webkit-transform-origin: 0% 100%;
-      -ms-transform-origin: 0% 100%;
           transform-origin: 0% 100%;
   -webkit-transform: translate3d(0, 0, 0);
           transform: translate3d(0, 0, 0); }
@@ -727,7 +758,6 @@ html:-moz-full-screen-ancestor {
 .reveal.fade .slides section:not([data-transition]),
 .reveal.fade .slides > section > section:not([data-transition]) {
   -webkit-transform: none;
-      -ms-transform: none;
           transform: none;
   -webkit-transition: opacity 0.5s;
           transition: opacity 0.5s; }
@@ -743,7 +773,6 @@ html:-moz-full-screen-ancestor {
 .reveal .slides section[data-transition=none],
 .reveal.none .slides section:not([data-transition]) {
   -webkit-transform: none;
-      -ms-transform: none;
           transform: none;
   -webkit-transition: none;
           transition: none; }
@@ -797,7 +826,6 @@ html:-moz-full-screen-ancestor {
   left: -50%;
   margin: 70px 0;
   -webkit-transform: none;
-      -ms-transform: none;
           transform: none; }
 
 .no-transforms .reveal .slides section section {
@@ -827,6 +855,7 @@ html:-moz-full-screen-ancestor {
   height: 100%;
   opacity: 0;
   visibility: hidden;
+  overflow: hidden;
   background-color: transparent;
   background-position: 50% 50%;
   background-repeat: no-repeat;
@@ -839,7 +868,8 @@ html:-moz-full-screen-ancestor {
 
 .reveal .slide-background.present {
   opacity: 1;
-  visibility: visible; }
+  visibility: visible;
+  z-index: 2; }
 
 .print-pdf .reveal .slide-background {
   opacity: 1 !important;
@@ -853,7 +883,13 @@ html:-moz-full-screen-ancestor {
   max-width: none;
   max-height: none;
   top: 0;
-  left: 0; }
+  left: 0;
+  -o-object-fit: cover;
+     object-fit: cover; }
+
+.reveal .slide-background[data-background-size="contain"] video {
+  -o-object-fit: contain;
+     object-fit: contain; }
 
 /* Immediate transition style */
 .reveal[data-background-transition=none] > .backgrounds .slide-background,
@@ -871,25 +907,21 @@ html:-moz-full-screen-ancestor {
 .reveal[data-background-transition=slide] > .backgrounds .slide-background.past,
 .reveal > .backgrounds .slide-background.past[data-background-transition=slide] {
   -webkit-transform: translate(-100%, 0);
-      -ms-transform: translate(-100%, 0);
           transform: translate(-100%, 0); }
 
 .reveal[data-background-transition=slide] > .backgrounds .slide-background.future,
 .reveal > .backgrounds .slide-background.future[data-background-transition=slide] {
   -webkit-transform: translate(100%, 0);
-      -ms-transform: translate(100%, 0);
           transform: translate(100%, 0); }
 
 .reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.past,
 .reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=slide] {
   -webkit-transform: translate(0, -100%);
-      -ms-transform: translate(0, -100%);
           transform: translate(0, -100%); }
 
 .reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.future,
 .reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=slide] {
   -webkit-transform: translate(0, 100%);
-      -ms-transform: translate(0, 100%);
           transform: translate(0, 100%); }
 
 /* Convex */
@@ -953,7 +985,6 @@ html:-moz-full-screen-ancestor {
   opacity: 0;
   visibility: hidden;
   -webkit-transform: scale(16);
-      -ms-transform: scale(16);
           transform: scale(16); }
 
 .reveal[data-background-transition=zoom] > .backgrounds .slide-background.future,
@@ -961,7 +992,6 @@ html:-moz-full-screen-ancestor {
   opacity: 0;
   visibility: hidden;
   -webkit-transform: scale(0.2);
-      -ms-transform: scale(0.2);
           transform: scale(0.2); }
 
 .reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.past,
@@ -969,7 +999,6 @@ html:-moz-full-screen-ancestor {
   opacity: 0;
   visibility: hidden;
   -webkit-transform: scale(16);
-      -ms-transform: scale(16);
           transform: scale(16); }
 
 .reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.future,
@@ -977,7 +1006,6 @@ html:-moz-full-screen-ancestor {
   opacity: 0;
   visibility: hidden;
   -webkit-transform: scale(0.2);
-      -ms-transform: scale(0.2);
           transform: scale(0.2); }
 
 /* Global transition speed settings */
@@ -997,8 +1025,11 @@ html:-moz-full-screen-ancestor {
           perspective-origin: 50% 50%;
   -webkit-perspective: 700px;
           perspective: 700px; }
+  .reveal.overview .slides {
+    -moz-transform-style: preserve-3d; }
   .reveal.overview .slides section {
-    height: 700px;
+    height: 100%;
+    top: 0 !important;
     opacity: 1 !important;
     overflow: hidden;
     visibility: visible !important;
@@ -1023,12 +1054,15 @@ html:-moz-full-screen-ancestor {
     overflow: visible; }
   .reveal.overview .backgrounds {
     -webkit-perspective: inherit;
-            perspective: inherit; }
+            perspective: inherit;
+    -moz-transform-style: preserve-3d; }
   .reveal.overview .backgrounds .slide-background {
     opacity: 1;
     visibility: visible;
     outline: 10px solid rgba(150, 150, 150, 0.1);
     outline-offset: 10px; }
+  .reveal.overview .backgrounds .slide-background.stack {
+    overflow: visible; }
 
 .reveal.overview .slides section,
 .reveal.overview-deactivating .slides section {
@@ -1040,10 +1074,6 @@ html:-moz-full-screen-ancestor {
   -webkit-transition: none;
           transition: none; }
 
-.reveal.overview-animated .slides {
-  -webkit-transition: -webkit-transform 0.4s ease;
-          transition: transform 0.4s ease; }
-
 /*********************************************
  * RTL SUPPORT
  *********************************************/
@@ -1132,6 +1162,7 @@ html:-moz-full-screen-ancestor {
   display: inline-block;
   width: 40px;
   height: 40px;
+  line-height: 36px;
   padding: 0 10px;
   float: right;
   opacity: 0.6;
@@ -1156,6 +1187,10 @@ html:-moz-full-screen-ancestor {
 
 .reveal .overlay .viewport {
   position: absolute;
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
   top: 40px;
   right: 0;
   bottom: 0;
@@ -1176,11 +1211,27 @@ html:-moz-full-screen-ancestor {
   opacity: 1;
   visibility: visible; }
 
+.reveal .overlay.overlay-preview.loaded .viewport-inner {
+  position: absolute;
+  z-index: -1;
+  left: 0;
+  top: 45%;
+  width: 100%;
+  text-align: center;
+  letter-spacing: normal; }
+
+.reveal .overlay.overlay-preview .x-frame-error {
+  opacity: 0;
+  -webkit-transition: opacity 0.3s ease 0.3s;
+          transition: opacity 0.3s ease 0.3s; }
+
+.reveal .overlay.overlay-preview.loaded .x-frame-error {
+  opacity: 1; }
+
 .reveal .overlay.overlay-preview.loaded .spinner {
   opacity: 0;
   visibility: hidden;
   -webkit-transform: scale(0.2);
-      -ms-transform: scale(0.2);
           transform: scale(0.2); }
 
 .reveal .overlay.overlay-help .viewport {
@@ -1189,8 +1240,8 @@ html:-moz-full-screen-ancestor {
 
 .reveal .overlay.overlay-help .viewport .viewport-inner {
   width: 600px;
-  margin: 0 auto;
-  padding: 60px;
+  margin: auto;
+  padding: 20px 20px 80px 20px;
   text-align: center;
   letter-spacing: normal; }
 
@@ -1200,12 +1251,12 @@ html:-moz-full-screen-ancestor {
 .reveal .overlay.overlay-help .viewport .viewport-inner table {
   border: 1px solid #fff;
   border-collapse: collapse;
-  font-size: 14px; }
+  font-size: 16px; }
 
 .reveal .overlay.overlay-help .viewport .viewport-inner table th,
 .reveal .overlay.overlay-help .viewport .viewport-inner table td {
   width: 200px;
-  padding: 10px;
+  padding: 14px;
   border: 1px solid #fff;
   vertical-align: middle; }
 
@@ -1254,7 +1305,6 @@ html:-moz-full-screen-ancestor {
   -webkit-transition: all 400ms ease;
           transition: all 400ms ease;
   -webkit-transform-origin: 50% 0%;
-      -ms-transform-origin: 50% 0%;
           transform-origin: 50% 0%;
   -webkit-transform-style: preserve-3d;
           transform-style: preserve-3d;
@@ -1276,7 +1326,6 @@ html:-moz-full-screen-ancestor {
   -webkit-backface-visibility: hidden;
           backface-visibility: hidden;
   -webkit-transform-origin: 50% 0%;
-      -ms-transform-origin: 50% 0%;
           transform-origin: 50% 0%;
   -webkit-transform: translate3d(0px, 110%, 0px) rotateX(-90deg);
           transform: translate3d(0px, 110%, 0px) rotateX(-90deg); }

+ 122 - 32
css/reveal.scss

@@ -3,7 +3,7 @@
  * http://lab.hakim.se/reveal-js
  * MIT licensed
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
  */
 
 
@@ -23,7 +23,7 @@ html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal i
 .reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed,
 .reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup,
 .reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary,
-.reveal time, .reveal mark, .reveal audio, video {
+.reveal time, .reveal mark, .reveal audio, .reveal video {
 	margin: 0;
 	padding: 0;
 	border: 0;
@@ -57,15 +57,6 @@ body {
 	color: #000;
 }
 
-// Ensures that the main background color matches the
-// theme in fullscreen mode
-html:-webkit-full-screen-ancestor {
-	background-color: inherit;
-}
-html:-moz-full-screen-ancestor {
-	background-color: inherit;
-}
-
 
 /*********************************************
  * VIEW FRAGMENTS
@@ -78,13 +69,13 @@ html:-moz-full-screen-ancestor {
 
 	&.visible {
 		opacity: 1;
-		visibility: visible;
+		visibility: inherit;
 	}
 }
 
 .reveal .slides section .fragment.grow {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 
 	&.visible {
 		transform: scale( 1.3 );
@@ -93,7 +84,7 @@ html:-moz-full-screen-ancestor {
 
 .reveal .slides section .fragment.shrink {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 
 	&.visible {
 		transform: scale( 0.7 );
@@ -110,7 +101,7 @@ html:-moz-full-screen-ancestor {
 
 .reveal .slides section .fragment.fade-out {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 
 	&.visible {
 		opacity: 0;
@@ -120,30 +111,62 @@ html:-moz-full-screen-ancestor {
 
 .reveal .slides section .fragment.semi-fade-out {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 
 	&.visible {
 		opacity: 0.5;
-		visibility: visible;
+		visibility: inherit;
 	}
 }
 
 .reveal .slides section .fragment.strike {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 
 	&.visible {
 		text-decoration: line-through;
 	}
 }
 
+.reveal .slides section .fragment.fade-up {
+	transform: translate(0, 20%);
+
+	&.visible {
+		transform: translate(0, 0);
+	}
+}
+
+.reveal .slides section .fragment.fade-down {
+	transform: translate(0, -20%);
+
+	&.visible {
+		transform: translate(0, 0);
+	}
+}
+
+.reveal .slides section .fragment.fade-right {
+	transform: translate(-20%, 0);
+
+	&.visible {
+		transform: translate(0, 0);
+	}
+}
+
+.reveal .slides section .fragment.fade-left {
+	transform: translate(20%, 0);
+
+	&.visible {
+		transform: translate(0, 0);
+	}
+}
+
 .reveal .slides section .fragment.current-visible {
 	opacity: 0;
 	visibility: hidden;
 
 	&.current-fragment {
 		opacity: 1;
-		visibility: visible;
+		visibility: inherit;
 	}
 }
 
@@ -154,7 +177,7 @@ html:-moz-full-screen-ancestor {
 .reveal .slides section .fragment.highlight-blue,
 .reveal .slides section .fragment.highlight-current-blue {
 	opacity: 1;
-	visibility: visible;
+	visibility: inherit;
 }
 	.reveal .slides section .fragment.highlight-red.visible {
 		color: #ff2c2d
@@ -365,6 +388,7 @@ html:-moz-full-screen-ancestor {
 	bottom: 0;
 	left: 0;
 	margin: auto;
+	pointer-events: none;
 
 	overflow: visible;
 	z-index: 1;
@@ -383,9 +407,10 @@ html:-moz-full-screen-ancestor {
 	position: absolute;
 	width: 100%;
 	padding: 20px 0px;
+	pointer-events: auto;
 
 	z-index: 10;
-	transform-style: preserve-3d;
+	transform-style: flat;
 	transition: transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
 				transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
 				visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985),
@@ -420,6 +445,13 @@ html:-moz-full-screen-ancestor {
 	opacity: 1;
 }
 
+.reveal .slides>section:empty,
+.reveal .slides>section>section:empty,
+.reveal .slides>section[data-background-interactive],
+.reveal .slides>section>section[data-background-interactive] {
+	pointer-events: none;
+}
+
 .reveal.center,
 .reveal.center .slides,
 .reveal.center .slides section {
@@ -457,6 +489,12 @@ html:-moz-full-screen-ancestor {
 		@content;
 	}
 }
+@mixin transition-stack($style) {
+	.reveal .slides section[data-transition=#{$style}].stack,
+	.reveal.#{$style} .slides section.stack {
+		@content;
+	}
+}
 @mixin transition-horizontal-past($style) {
 	.reveal .slides>section[data-transition=#{$style}].past,
 	.reveal .slides>section[data-transition~=#{$style}-out].past,
@@ -516,6 +554,10 @@ html:-moz-full-screen-ancestor {
  *********************************************/
 
 @each $stylename in default, convex {
+	@include transition-stack(#{$stylename}) {
+		transform-style: preserve-3d;
+	}
+
 	@include transition-horizontal-past(#{$stylename}) {
 		transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
 	}
@@ -534,6 +576,10 @@ html:-moz-full-screen-ancestor {
  * CONCAVE TRANSITION
  *********************************************/
 
+@include transition-stack(concave) {
+	transform-style: preserve-3d;
+}
+
 @include transition-horizontal-past(concave) {
 	transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
 }
@@ -573,6 +619,10 @@ html:-moz-full-screen-ancestor {
 
 /*********************************************
  * CUBE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
  *********************************************/
 
 .reveal.cube .slides {
@@ -584,6 +634,7 @@ html:-moz-full-screen-ancestor {
 	min-height: 700px;
 	backface-visibility: hidden;
 	box-sizing: border-box;
+	transform-style: preserve-3d;
 }
 	.reveal.center.cube .slides section {
 		min-height: 0;
@@ -644,6 +695,10 @@ html:-moz-full-screen-ancestor {
 
 /*********************************************
  * PAGE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
  *********************************************/
 
 .reveal.page .slides {
@@ -655,6 +710,7 @@ html:-moz-full-screen-ancestor {
 	padding: 30px;
 	min-height: 700px;
 	box-sizing: border-box;
+	transform-style: preserve-3d;
 }
 	.reveal.page .slides section.past {
 		z-index: 12;
@@ -827,6 +883,7 @@ html:-moz-full-screen-ancestor {
 		height: 100%;
 		opacity: 0;
 		visibility: hidden;
+		overflow: hidden;
 
 		background-color: rgba( 0, 0, 0, 0 );
 		background-position: 50% 50%;
@@ -843,6 +900,7 @@ html:-moz-full-screen-ancestor {
 	.reveal .slide-background.present {
 		opacity: 1;
 		visibility: visible;
+		z-index: 2;
 	}
 
 	.print-pdf .reveal .slide-background {
@@ -859,7 +917,11 @@ html:-moz-full-screen-ancestor {
 	max-height: none;
 	top: 0;
 	left: 0;
+	object-fit: cover;
 }
+	.reveal .slide-background[data-background-size="contain"] video {
+		object-fit: contain;
+	}
 
 /* Immediate transition style */
 .reveal[data-background-transition=none]>.backgrounds .slide-background,
@@ -989,8 +1051,15 @@ html:-moz-full-screen-ancestor {
 	perspective-origin: 50% 50%;
 	perspective: 700px;
 
+	.slides {
+		// Fixes overview rendering errors in FF48+, not applied to
+		// other browsers since it degrades performance
+		-moz-transform-style: preserve-3d;
+	}
+
 	.slides section {
-		height: 700px;
+		height: 100%;
+		top: 0 !important;
 		opacity: 1 !important;
 		overflow: hidden;
 		visibility: visible !important;
@@ -1020,6 +1089,10 @@ html:-moz-full-screen-ancestor {
 
 	.backgrounds {
 		perspective: inherit;
+
+		// Fixes overview rendering errors in FF48+, not applied to
+		// other browsers since it degrades performance
+		-moz-transform-style: preserve-3d;
 	}
 
 	.backgrounds .slide-background {
@@ -1030,6 +1103,10 @@ html:-moz-full-screen-ancestor {
 		outline: 10px solid rgba(150,150,150,0.1);
 		outline-offset: 10px;
 	}
+
+	.backgrounds .slide-background.stack {
+		overflow: visible;
+	}
 }
 
 // Disable transitions transitions while we're activating
@@ -1044,10 +1121,6 @@ html:-moz-full-screen-ancestor {
 	transition: none;
 }
 
-.reveal.overview-animated .slides {
-	transition: transform 0.4s ease;
-}
-
 
 /*********************************************
  * RTL SUPPORT
@@ -1145,6 +1218,7 @@ html:-moz-full-screen-ancestor {
 			display: inline-block;
 			width: 40px;
 			height: 40px;
+			line-height: 36px;
 			padding: 0 10px;
 			float: right;
 			opacity: 0.6;
@@ -1172,6 +1246,7 @@ html:-moz-full-screen-ancestor {
 
 	.reveal .overlay .viewport {
 		position: absolute;
+		display: flex;
 		top: 40px;
 		right: 0;
 		bottom: 0;
@@ -1195,6 +1270,23 @@ html:-moz-full-screen-ancestor {
 		visibility: visible;
 	}
 
+	.reveal .overlay.overlay-preview.loaded .viewport-inner  {
+		position: absolute;
+		z-index: -1;
+		left: 0;
+		top: 45%;
+		width: 100%;
+		text-align: center;
+		letter-spacing: normal;
+	}
+	.reveal .overlay.overlay-preview .x-frame-error  {
+		opacity: 0;
+		transition: opacity 0.3s ease 0.3s;
+	}
+	.reveal .overlay.overlay-preview.loaded .x-frame-error  {
+		opacity: 1;
+	}
+
 	.reveal .overlay.overlay-preview.loaded .spinner {
 		opacity: 0;
 		visibility: hidden;
@@ -1208,8 +1300,8 @@ html:-moz-full-screen-ancestor {
 
 	.reveal .overlay.overlay-help .viewport .viewport-inner {
 		width: 600px;
-		margin: 0 auto;
-		padding: 60px;
+		margin: auto;
+		padding: 20px 20px 80px 20px;
 		text-align: center;
 		letter-spacing: normal;
 	}
@@ -1221,13 +1313,13 @@ html:-moz-full-screen-ancestor {
 	.reveal .overlay.overlay-help .viewport .viewport-inner table {
 		border: 1px solid #fff;
 		border-collapse: collapse;
-		font-size: 14px;
+		font-size: 16px;
 	}
 
 	.reveal .overlay.overlay-help .viewport .viewport-inner table th,
 	.reveal .overlay.overlay-help .viewport .viewport-inner table td {
 		width: 200px;
-		padding: 10px;
+		padding: 14px;
 		border: 1px solid #fff;
 		vertical-align: middle;
 	}
@@ -1375,5 +1467,3 @@ html:-moz-full-screen-ancestor {
 .zoomed .reveal .roll span:after {
 	visibility: hidden;
 }
-
-

+ 14 - 8
css/theme/beige.css

@@ -20,7 +20,7 @@ body {
 
 .reveal {
   font-family: "Lato", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #333; }
 
@@ -29,6 +29,11 @@ body {
   background: rgba(79, 64, 28, 0.99);
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: rgba(79, 64, 28, 0.99);
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -186,7 +191,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -210,9 +216,9 @@ body {
 .reveal a {
   color: #8b743d;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #c0a86e;
@@ -237,9 +243,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 15 - 9
css/theme/black.css

@@ -1,7 +1,7 @@
 /**
  * Black theme for reveal.js. This is the opposite of the 'white' theme.
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * By Hakim El Hattab, http://hakim.se
  */
 @import url(../../lib/font/source-sans-pro/source-sans-pro.css);
 section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
@@ -16,7 +16,7 @@ body {
 
 .reveal {
   font-family: "Source Sans Pro", Helvetica, sans-serif;
-  font-size: 38px;
+  font-size: 42px;
   font-weight: normal;
   color: #fff; }
 
@@ -25,6 +25,11 @@ body {
   background: #bee4fd;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #bee4fd;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -182,7 +187,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -206,9 +212,9 @@ body {
 .reveal a {
   color: #42affa;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #8dcffc;
@@ -233,9 +239,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/blood.css

@@ -19,7 +19,7 @@ body {
 
 .reveal {
   font-family: Ubuntu, "sans-serif";
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #eee; }
 
@@ -28,6 +28,11 @@ body {
   background: #a23;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #a23;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -185,7 +190,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -209,9 +215,9 @@ body {
 .reveal a {
   color: #a23;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #dd5566;
@@ -236,9 +242,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/league.css

@@ -22,7 +22,7 @@ body {
 
 .reveal {
   font-family: "Lato", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #eee; }
 
@@ -31,6 +31,11 @@ body {
   background: #FF5E99;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #FF5E99;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -188,7 +193,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -212,9 +218,9 @@ body {
 .reveal a {
   color: #13DAEC;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #71e9f4;
@@ -239,9 +245,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/moon.css

@@ -20,7 +20,7 @@ body {
 
 .reveal {
   font-family: "Lato", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #93a1a1; }
 
@@ -29,6 +29,11 @@ body {
   background: #d33682;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #d33682;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -186,7 +191,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -210,9 +216,9 @@ body {
 .reveal a {
   color: #268bd2;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #78b9e6;
@@ -237,9 +243,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/night.css

@@ -14,7 +14,7 @@ body {
 
 .reveal {
   font-family: "Open Sans", sans-serif;
-  font-size: 30px;
+  font-size: 40px;
   font-weight: normal;
   color: #eee; }
 
@@ -23,6 +23,11 @@ body {
   background: #e7ad52;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #e7ad52;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -180,7 +185,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -204,9 +210,9 @@ body {
 .reveal a {
   color: #e7ad52;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #f3d7ac;
@@ -231,9 +237,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/serif.css

@@ -16,7 +16,7 @@ body {
 
 .reveal {
   font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #000; }
 
@@ -25,6 +25,11 @@ body {
   background: #26351C;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #26351C;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -182,7 +187,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -206,9 +212,9 @@ body {
 .reveal a {
   color: #51483D;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #8b7c69;
@@ -233,9 +239,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 17 - 8
css/theme/simple.css

@@ -7,6 +7,9 @@
  */
 @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
 @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
+  color: #fff; }
+
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -16,7 +19,7 @@ body {
 
 .reveal {
   font-family: "Lato", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #000; }
 
@@ -25,6 +28,11 @@ body {
   background: rgba(0, 0, 0, 0.99);
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: rgba(0, 0, 0, 0.99);
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -182,7 +190,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -206,9 +215,9 @@ body {
 .reveal a {
   color: #00008B;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #0000f1;
@@ -233,9 +242,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/sky.css

@@ -23,7 +23,7 @@ body {
 
 .reveal {
   font-family: "Open Sans", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #333; }
 
@@ -32,6 +32,11 @@ body {
   background: #134674;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #134674;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -189,7 +194,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -213,9 +219,9 @@ body {
 .reveal a {
   color: #3b759e;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #74a7cb;
@@ -240,9 +246,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 14 - 8
css/theme/solarized.css

@@ -20,7 +20,7 @@ body {
 
 .reveal {
   font-family: "Lato", sans-serif;
-  font-size: 36px;
+  font-size: 40px;
   font-weight: normal;
   color: #657b83; }
 
@@ -29,6 +29,11 @@ body {
   background: #d33682;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #d33682;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -186,7 +191,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -210,9 +216,9 @@ body {
 .reveal a {
   color: #268bd2;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #78b9e6;
@@ -237,9 +243,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 2 - 2
css/theme/source/black.scss

@@ -1,7 +1,7 @@
 /**
  * Black theme for reveal.js. This is the opposite of the 'white' theme.
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * By Hakim El Hattab, http://hakim.se
  */
 
 
@@ -21,7 +21,7 @@ $backgroundColor: #222;
 $mainColor: #fff;
 $headingColor: #fff;
 
-$mainFontSize: 38px;
+$mainFontSize: 42px;
 $mainFont: 'Source Sans Pro', Helvetica, sans-serif;
 $headingFont: 'Source Sans Pro', Helvetica, sans-serif;
 $headingTextShadow: none;

+ 0 - 1
css/theme/source/blood.scss

@@ -28,7 +28,6 @@ $backgroundColor: $coal;
 
 // Main text
 $mainFont: Ubuntu, 'sans-serif';
-$mainFontSize: 36px;
 $mainColor: #eee;
 
 // Headings

+ 0 - 1
css/theme/source/night.scss

@@ -27,7 +27,6 @@ $headingTextShadow: none;
 $headingLetterSpacing: -0.03em;
 $headingTextTransform: none;
 $selectionBackgroundColor: #e7ad52;
-$mainFontSize: 30px;
 
 
 // Theme template ------------------------------

+ 5 - 0
css/theme/source/simple.scss

@@ -31,6 +31,11 @@ $linkColor: #00008B;
 $linkColorHover: lighten( $linkColor, 20% );
 $selectionBackgroundColor: rgba(0, 0, 0, 0.99);
 
+section.has-dark-background {
+	&, h1, h2, h3, h4, h5, h6 {
+		color: #fff;
+	}
+}
 
 
 // Theme template ------------------------------

+ 2 - 2
css/theme/source/white.scss

@@ -1,7 +1,7 @@
 /**
  * White theme for reveal.js. This is the opposite of the 'black' theme.
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * By Hakim El Hattab, http://hakim.se
  */
 
 
@@ -21,7 +21,7 @@ $backgroundColor: #fff;
 $mainColor: #222;
 $headingColor: #222;
 
-$mainFontSize: 38px;
+$mainFontSize: 42px;
 $mainFont: 'Source Sans Pro', Helvetica, sans-serif;
 $headingFont: 'Source Sans Pro', Helvetica, sans-serif;
 $headingTextShadow: none;

+ 1 - 1
css/theme/template/settings.scss

@@ -6,7 +6,7 @@ $backgroundColor: #2b2b2b;
 
 // Primary/body text
 $mainFont: 'Lato', sans-serif;
-$mainFontSize: 36px;
+$mainFontSize: 40px;
 $mainColor: #eee;
 
 // Vertical spacing between blocks of text

+ 8 - 1
css/theme/template/theme.scss

@@ -22,6 +22,12 @@ body {
 	text-shadow: none;
 }
 
+::-moz-selection {
+	color: $selectionColor;
+	background: $selectionBackgroundColor;
+	text-shadow: none;
+}
+
 .reveal .slides>section,
 .reveal .slides>section>section {
 	line-height: 1.3;
@@ -207,7 +213,8 @@ body {
 	text-align: right;
 }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
 	border-bottom: none;
 }
 

+ 15 - 9
css/theme/white.css

@@ -1,7 +1,7 @@
 /**
  * White theme for reveal.js. This is the opposite of the 'black' theme.
  *
- * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
+ * By Hakim El Hattab, http://hakim.se
  */
 @import url(../../lib/font/source-sans-pro/source-sans-pro.css);
 section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
@@ -16,7 +16,7 @@ body {
 
 .reveal {
   font-family: "Source Sans Pro", Helvetica, sans-serif;
-  font-size: 38px;
+  font-size: 42px;
   font-weight: normal;
   color: #222; }
 
@@ -25,6 +25,11 @@ body {
   background: #98bdef;
   text-shadow: none; }
 
+::-moz-selection {
+  color: #fff;
+  background: #98bdef;
+  text-shadow: none; }
+
 .reveal .slides > section,
 .reveal .slides > section > section {
   line-height: 1.3;
@@ -182,7 +187,8 @@ body {
 .reveal table td[align="right"] {
   text-align: right; }
 
-.reveal table tr:last-child td {
+.reveal table tbody tr:last-child th,
+.reveal table tbody tr:last-child td {
   border-bottom: none; }
 
 .reveal sup {
@@ -206,9 +212,9 @@ body {
 .reveal a {
   color: #2a76dd;
   text-decoration: none;
-  -webkit-transition: color 0.15s ease;
-  -moz-transition: color 0.15s ease;
-  transition: color 0.15s ease; }
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  transition: color .15s ease; }
 
 .reveal a:hover {
   color: #6ca0e8;
@@ -233,9 +239,9 @@ body {
   box-shadow: none; }
 
 .reveal a img {
-  -webkit-transition: all 0.15s linear;
-  -moz-transition: all 0.15s linear;
-  transition: all 0.15s linear; }
+  -webkit-transition: all .15s linear;
+  -moz-transition: all .15s linear;
+  transition: all .15s linear; }
 
 .reveal a:hover img {
   background: rgba(255, 255, 255, 0.2);

+ 410 - 0
demo.html

@@ -0,0 +1,410 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js – The HTML Presentation Framework</title>
+
+		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
+		<meta name="author" content="Hakim El Hattab">
+
+		<meta name="apple-mobile-web-app-capable" content="yes">
+		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="css/reveal.css">
+		<link rel="stylesheet" href="css/theme/black.css" id="theme">
+
+		<!-- Theme used for syntax highlighting of code -->
+		<link rel="stylesheet" href="lib/css/zenburn.css">
+
+		<!-- Printing and PDF exports -->
+		<script>
+			var link = document.createElement( 'link' );
+			link.rel = 'stylesheet';
+			link.type = 'text/css';
+			link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
+			document.getElementsByTagName( 'head' )[0].appendChild( link );
+		</script>
+
+		<!--[if lt IE 9]>
+		<script src="lib/js/html5shiv.js"></script>
+		<![endif]-->
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<!-- Any section element inside of this container is displayed as a slide -->
+			<div class="slides">
+				<section>
+					<h1>Reveal.js</h1>
+					<h3>The HTML Presentation Framework</h3>
+					<p>
+						<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
+					</p>
+				</section>
+
+				<section>
+					<h2>Hello There</h2>
+					<p>
+						reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do.
+					</p>
+				</section>
+
+				<!-- Example of nested vertical slides -->
+				<section>
+					<section>
+						<h2>Vertical Slides</h2>
+						<p>Slides can be nested inside of each other.</p>
+						<p>Use the <em>Space</em> key to navigate through all slides.</p>
+						<br>
+						<a href="#" class="navigate-down">
+							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section>
+						<h2>Basement Level 1</h2>
+						<p>Nested slides are useful for adding additional detail underneath a high level horizontal slide.</p>
+					</section>
+					<section>
+						<h2>Basement Level 2</h2>
+						<p>That's it, time to go back up.</p>
+						<br>
+						<a href="#/2">
+							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="transform: rotate(180deg); -webkit-transform: rotate(180deg);">
+						</a>
+					</section>
+				</section>
+
+				<section>
+					<h2>Slides</h2>
+					<p>
+						Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slides.com" target="_blank">http://slides.com</a>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Point of View</h2>
+					<p>
+						Press <strong>ESC</strong> to enter the slide overview.
+					</p>
+					<p>
+						Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
+					</p>
+				</section>
+
+				<section>
+					<h2>Touch Optimized</h2>
+					<p>
+						Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides.
+					</p>
+				</section>
+
+				<section data-markdown>
+					<script type="text/template">
+						## Markdown support
+
+						Write content using inline or external Markdown.
+						Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
+
+						```
+						<section data-markdown>
+						  ## Markdown support
+
+						  Write content using inline or external Markdown.
+						  Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
+						</section>
+						```
+					</script>
+				</section>
+
+				<section>
+					<section id="fragments">
+						<h2>Fragments</h2>
+						<p>Hit the next arrow...</p>
+						<p class="fragment">... to step through ...</p>
+						<p><span class="fragment">... a</span> <span class="fragment">fragmented</span> <span class="fragment">slide.</span></p>
+
+						<aside class="notes">
+							This slide has fragments which are also stepped through in the notes window.
+						</aside>
+					</section>
+					<section>
+						<h2>Fragment Styles</h2>
+						<p>There's different types of fragments, like:</p>
+						<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>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>
+
+				<section id="transitions">
+					<h2>Transition Styles</h2>
+					<p>
+						You can select from different transitions, like: <br>
+						<a href="?transition=none#/transitions">None</a> -
+						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?transition=slide#/transitions">Slide</a> -
+						<a href="?transition=convex#/transitions">Convex</a> -
+						<a href="?transition=concave#/transitions">Concave</a> -
+						<a href="?transition=zoom#/transitions">Zoom</a>
+					</p>
+				</section>
+
+				<section id="themes">
+					<h2>Themes</h2>
+					<p>
+						reveal.js comes with a few themes built in: <br>
+						<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/black.css'); return false;">Black (default)</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/white.css'); return false;">White</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/league.css'); return false;">League</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/sky.css'); return false;">Sky</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/beige.css'); return false;">Beige</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/simple.css'); return false;">Simple</a> <br>
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/serif.css'); return false;">Serif</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/blood.css'); return false;">Blood</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/night.css'); return false;">Night</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/moon.css'); return false;">Moon</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/solarized.css'); return false;">Solarized</a>
+					</p>
+				</section>
+
+				<section>
+					<section data-background="#dddddd">
+						<h2>Slide Backgrounds</h2>
+						<p>
+							Set <code>data-background="#dddddd"</code> on a slide to change the background color. All CSS color formats are supported.
+						</p>
+						<a href="#" class="navigate-down">
+							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						</a>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png">
+						<h2>Image Backgrounds</h2>
+						<pre><code class="hljs">&lt;section data-background="image.png"&gt;</code></pre>
+					</section>
+					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px">
+						<h2>Tiled Backgrounds</h2>
+						<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
+					</section>
+					<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-color="#000000">
+						<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
+							<h2>Video Backgrounds</h2>
+							<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre>
+						</div>
+					</section>
+					<section data-background="http://i.giphy.com/90F8aUepslB84.gif">
+						<h2>... and GIFs!</h2>
+					</section>
+				</section>
+
+				<section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom">
+					<h2>Background Transitions</h2>
+					<p>
+						Different background transitions are available via the backgroundTransition option. This one's called "zoom".
+					</p>
+					<pre><code class="hljs">Reveal.configure({ backgroundTransition: 'zoom' })</code></pre>
+				</section>
+
+				<section data-transition="slide" data-background="#b5533c" data-background-transition="zoom">
+					<h2>Background Transitions</h2>
+					<p>
+						You can override background transitions per-slide.
+					</p>
+					<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-transition="zoom"&gt;</code></pre>
+				</section>
+
+				<section>
+					<h2>Pretty Code</h2>
+					<pre><code class="hljs" data-trim contenteditable>
+function linkify( selector ) {
+  if( supports3DTransforms ) {
+
+    var nodes = document.querySelectorAll( selector );
+
+    for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
+      var node = nodes[i];
+
+      if( !node.className ) {
+        node.className += ' roll';
+      }
+    }
+  }
+}
+					</code></pre>
+					<p>Code syntax highlighting courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
+				</section>
+
+				<section>
+					<h2>Marvelous List</h2>
+					<ul>
+						<li>No order here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+						<li>Or here</li>
+					</ul>
+				</section>
+
+				<section>
+					<h2>Fantastic Ordered List</h2>
+					<ol>
+						<li>One is smaller than...</li>
+						<li>Two is smaller than...</li>
+						<li>Three!</li>
+					</ol>
+				</section>
+
+				<section>
+					<h2>Tabular Tables</h2>
+					<table>
+						<thead>
+							<tr>
+								<th>Item</th>
+								<th>Value</th>
+								<th>Quantity</th>
+							</tr>
+						</thead>
+						<tbody>
+							<tr>
+								<td>Apples</td>
+								<td>$1</td>
+								<td>7</td>
+							</tr>
+							<tr>
+								<td>Lemonade</td>
+								<td>$2</td>
+								<td>18</td>
+							</tr>
+							<tr>
+								<td>Bread</td>
+								<td>$3</td>
+								<td>2</td>
+							</tr>
+						</tbody>
+					</table>
+				</section>
+
+				<section>
+					<h2>Clever Quotes</h2>
+					<p>
+						These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;The nice thing about standards is that there are so many to choose from&rdquo;</q> and block:
+					</p>
+					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
+						&ldquo;For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
+						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.&rdquo;
+					</blockquote>
+				</section>
+
+				<section>
+					<h2>Intergalactic Interconnections</h2>
+					<p>
+						You can link between slides internally,
+						<a href="#/2/3">like this</a>.
+					</p>
+				</section>
+
+				<section>
+					<h2>Speaker View</h2>
+					<p>There's a <a href="https://github.com/hakimel/reveal.js#speaker-notes">speaker view</a>. It includes a timer, preview of the upcoming slide as well as your speaker notes.</p>
+					<p>Press the <em>S</em> key to try it out.</p>
+
+					<aside class="notes">
+						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
+					</aside>
+				</section>
+
+				<section>
+					<h2>Export to PDF</h2>
+					<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, here's an example:</p>
+					<iframe data-src="https://www.slideshare.net/slideshow/embed_code/42840540" width="445" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:3px solid #666; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
+				</section>
+
+				<section>
+					<h2>Global State</h2>
+					<p>
+						Set <code>data-state="something"</code> on a slide and <code>"something"</code>
+						will be added as a class to the document element when the slide is open. This lets you
+						apply broader style changes, like switching the page background.
+					</p>
+				</section>
+
+				<section data-state="customevent">
+					<h2>State Events</h2>
+					<p>
+						Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
+					</p>
+					<pre><code class="javascript" data-trim contenteditable style="font-size: 18px;">
+Reveal.addEventListener( 'customevent', function() {
+	console.log( '"customevent" has fired' );
+} );
+					</code></pre>
+				</section>
+
+				<section>
+					<h2>Take a Moment</h2>
+					<p>
+						Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen.
+					</p>
+				</section>
+
+				<section>
+					<h2>Much more</h2>
+					<ul>
+						<li>Right-to-left support</li>
+						<li><a href="https://github.com/hakimel/reveal.js#api">Extensive JavaScript API</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js#auto-sliding">Auto-progression</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js#parallax-background">Parallax backgrounds</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js#keyboard-bindings">Custom keyboard bindings</a></li>
+					</ul>
+				</section>
+
+				<section style="text-align: left;">
+					<h1>THE END</h1>
+					<p>
+						- <a href="http://slides.com">Try the online editor</a> <br>
+						- <a href="https://github.com/hakimel/reveal.js">Source code &amp; documentation</a>
+					</p>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="lib/js/head.min.js"></script>
+		<script src="js/reveal.js"></script>
+
+		<script>
+
+			// More info https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				transition: 'slide', // none/fade/slide/convex/concave/zoom
+
+				// More info https://github.com/hakimel/reveal.js#dependencies
+				dependencies: [
+					{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: 'plugin/zoom-js/zoom.js', async: true },
+					{ src: 'plugin/notes/notes.js', async: true }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>

+ 14 - 376
index.html

@@ -1,23 +1,15 @@
 <!doctype html>
-<html lang="en">
-
+<html>
 	<head>
 		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 
-		<title>reveal.js – The HTML Presentation Framework</title>
-
-		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
-		<meta name="author" content="Hakim El Hattab">
-
-		<meta name="apple-mobile-web-app-capable" content="yes">
-		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
-
-		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
+		<title>reveal.js</title>
 
 		<link rel="stylesheet" href="css/reveal.css">
-		<link rel="stylesheet" href="css/theme/black.css" id="theme">
+		<link rel="stylesheet" href="css/theme/black.css">
 
-		<!-- Code syntax highlighting -->
+		<!-- Theme used for syntax highlighting of code -->
 		<link rel="stylesheet" href="lib/css/zenburn.css">
 
 		<!-- Printing and PDF exports -->
@@ -28,384 +20,30 @@
 			link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
 			document.getElementsByTagName( 'head' )[0].appendChild( link );
 		</script>
-
-		<!--[if lt IE 9]>
-		<script src="lib/js/html5shiv.js"></script>
-		<![endif]-->
 	</head>
-
 	<body>
-
 		<div class="reveal">
-
-			<!-- Any section element inside of this container is displayed as a slide -->
 			<div class="slides">
-				<section>
-					<h1>Reveal.js</h1>
-					<h3>The HTML Presentation Framework</h3>
-					<p>
-						<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
-					</p>
-				</section>
-
-				<section>
-					<h2>Hello There</h2>
-					<p>
-						reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do.
-					</p>
-				</section>
-
-				<!-- Example of nested vertical slides -->
-				<section>
-					<section>
-						<h2>Vertical Slides</h2>
-						<p>Slides can be nested inside of each other.</p>
-						<p>Use the <em>Space</em> key to navigate through all slides.</p>
-						<br>
-						<a href="#" class="navigate-down">
-							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
-						</a>
-					</section>
-					<section>
-						<h2>Basement Level 1</h2>
-						<p>Nested slides are useful for adding additional detail underneath a high level horizontal slide.</p>
-					</section>
-					<section>
-						<h2>Basement Level 2</h2>
-						<p>That's it, time to go back up.</p>
-						<br>
-						<a href="#/2">
-							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="transform: rotate(180deg); -webkit-transform: rotate(180deg);">
-						</a>
-					</section>
-				</section>
-
-				<section>
-					<h2>Slides</h2>
-					<p>
-						Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slides.com" target="_blank">http://slides.com</a>.
-					</p>
-				</section>
-
-				<section>
-					<h2>Point of View</h2>
-					<p>
-						Press <strong>ESC</strong> to enter the slide overview.
-					</p>
-					<p>
-						Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
-					</p>
-				</section>
-
-				<section>
-					<h2>Touch Optimized</h2>
-					<p>
-						Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides.
-					</p>
-				</section>
-
-				<section data-markdown>
-					<script type="text/template">
-						## Markdown support
-
-						Write content using inline or external Markdown.
-						Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
-
-						```
-						<section data-markdown>
-						  ## Markdown support
-
-						  Write content using inline or external Markdown.
-						  Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
-						</section>
-						```
-					</script>
-				</section>
-
-				<section>
-					<section id="fragments">
-						<h2>Fragments</h2>
-						<p>Hit the next arrow...</p>
-						<p class="fragment">... to step through ...</p>
-						<p><span class="fragment">... a</span> <span class="fragment">fragmented</span> <span class="fragment">slide.</span></p>
-
-						<aside class="notes">
-							This slide has fragments which are also stepped through in the notes window.
-						</aside>
-					</section>
-					<section>
-						<h2>Fragment Styles</h2>
-						<p>There's different types of fragments, like:</p>
-						<p class="fragment grow">grow</p>
-						<p class="fragment shrink">shrink</p>
-						<p class="fragment fade-out">fade-out</p>
-						<p class="fragment current-visible">current-visible</p>
-						<p class="fragment highlight-red">highlight-red</p>
-						<p class="fragment highlight-blue">highlight-blue</p>
-					</section>
-				</section>
-
-				<section id="transitions">
-					<h2>Transition Styles</h2>
-					<p>
-						You can select from different transitions, like: <br>
-						<a href="?transition=none#/transitions">None</a> -
-						<a href="?transition=fade#/transitions">Fade</a> -
-						<a href="?transition=slide#/transitions">Slide</a> -
-						<a href="?transition=convex#/transitions">Convex</a> -
-						<a href="?transition=concave#/transitions">Concave</a> -
-						<a href="?transition=zoom#/transitions">Zoom</a>
-					</p>
-				</section>
-
-				<section id="themes">
-					<h2>Themes</h2>
-					<p>
-						reveal.js comes with a few themes built in: <br>
-						<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/black.css'); return false;">Black (default)</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/white.css'); return false;">White</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/league.css'); return false;">League</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/sky.css'); return false;">Sky</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/beige.css'); return false;">Beige</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/simple.css'); return false;">Simple</a> <br>
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/serif.css'); return false;">Serif</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/blood.css'); return false;">Blood</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/night.css'); return false;">Night</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/moon.css'); return false;">Moon</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/solarized.css'); return false;">Solarized</a>
-					</p>
-				</section>
-
-				<section>
-					<section data-background="#dddddd">
-						<h2>Slide Backgrounds</h2>
-						<p>
-							Set <code>data-background="#dddddd"</code> on a slide to change the background color. All CSS color formats are supported.
-						</p>
-						<a href="#" class="navigate-down">
-							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
-						</a>
-					</section>
-					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png">
-						<h2>Image Backgrounds</h2>
-						<pre><code class="hljs">&lt;section data-background="image.png"&gt;</code></pre>
-					</section>
-					<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px">
-						<h2>Tiled Backgrounds</h2>
-						<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
-					</section>
-					<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-color="#000000">
-						<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
-							<h2>Video Backgrounds</h2>
-							<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre>
-						</div>
-					</section>
-					<section data-background="http://i.giphy.com/90F8aUepslB84.gif">
-						<h2>... and GIFs!</h2>
-					</section>
-				</section>
-
-				<section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom">
-					<h2>Background Transitions</h2>
-					<p>
-						Different background transitions are available via the backgroundTransition option. This one's called "zoom".
-					</p>
-					<pre><code class="hljs">Reveal.configure({ backgroundTransition: 'zoom' })</code></pre>
-				</section>
-
-				<section data-transition="slide" data-background="#b5533c" data-background-transition="zoom">
-					<h2>Background Transitions</h2>
-					<p>
-						You can override background transitions per-slide.
-					</p>
-					<pre><code class="hljs" style="word-wrap: break-word;">&lt;section data-background-transition="zoom"&gt;</code></pre>
-				</section>
-
-				<section>
-					<h2>Pretty Code</h2>
-					<pre><code class="hljs" data-trim contenteditable>
-function linkify( selector ) {
-  if( supports3DTransforms ) {
-
-    var nodes = document.querySelectorAll( selector );
-
-    for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
-      var node = nodes[i];
-
-      if( !node.className ) {
-        node.className += ' roll';
-      }
-    }
-  }
-}
-					</code></pre>
-					<p>Code syntax highlighting courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
-				</section>
-
-				<section>
-					<h2>Marvelous List</h2>
-					<ul>
-						<li>No order here</li>
-						<li>Or here</li>
-						<li>Or here</li>
-						<li>Or here</li>
-					</ul>
-				</section>
-
-				<section>
-					<h2>Fantastic Ordered List</h2>
-					<ol>
-						<li>One is smaller than...</li>
-						<li>Two is smaller than...</li>
-						<li>Three!</li>
-					</ol>
-				</section>
-
-				<section>
-					<h2>Tabular Tables</h2>
-					<table>
-						<thead>
-							<tr>
-								<th>Item</th>
-								<th>Value</th>
-								<th>Quantity</th>
-							</tr>
-						</thead>
-						<tbody>
-							<tr>
-								<td>Apples</td>
-								<td>$1</td>
-								<td>7</td>
-							</tr>
-							<tr>
-								<td>Lemonade</td>
-								<td>$2</td>
-								<td>18</td>
-							</tr>
-							<tr>
-								<td>Bread</td>
-								<td>$3</td>
-								<td>2</td>
-							</tr>
-						</tbody>
-					</table>
-				</section>
-
-				<section>
-					<h2>Clever Quotes</h2>
-					<p>
-						These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
-						&ldquo;The nice thing about standards is that there are so many to choose from&rdquo;</q> and block:
-					</p>
-					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
-						&ldquo;For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
-						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.&rdquo;
-					</blockquote>
-				</section>
-
-				<section>
-					<h2>Intergalactic Interconnections</h2>
-					<p>
-						You can link between slides internally,
-						<a href="#/2/3">like this</a>.
-					</p>
-				</section>
-
-				<section>
-					<h2>Speaker View</h2>
-					<p>There's a <a href="https://github.com/hakimel/reveal.js#speaker-notes">speaker view</a>. It includes a timer, preview of the upcoming slide as well as your speaker notes.</p>
-					<p>Press the <em>S</em> key to try it out.</p>
-
-					<aside class="notes">
-						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
-					</aside>
-				</section>
-
-				<section>
-					<h2>Export to PDF</h2>
-					<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, here's an example:</p>
-					<iframe src="https://www.slideshare.net/slideshow/embed_code/42840540" width="445" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:3px solid #666; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
-				</section>
-
-				<section>
-					<h2>Global State</h2>
-					<p>
-						Set <code>data-state="something"</code> on a slide and <code>"something"</code>
-						will be added as a class to the document element when the slide is open. This lets you
-						apply broader style changes, like switching the page background.
-					</p>
-				</section>
-
-				<section data-state="customevent">
-					<h2>State Events</h2>
-					<p>
-						Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
-					</p>
-					<pre><code class="javascript" data-trim contenteditable style="font-size: 18px;">
-Reveal.addEventListener( 'customevent', function() {
-	console.log( '"customevent" has fired' );
-} );
-					</code></pre>
-				</section>
-
-				<section>
-					<h2>Take a Moment</h2>
-					<p>
-						Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen.
-					</p>
-				</section>
-
-				<section>
-					<h2>Much more</h2>
-					<ul>
-						<li>Right-to-left support</li>
-						<li><a href="https://github.com/hakimel/reveal.js#api">Extensive JavaScript API</a></li>
-						<li><a href="https://github.com/hakimel/reveal.js#auto-sliding">Auto-progression</a></li>
-						<li><a href="https://github.com/hakimel/reveal.js#parallax-background">Parallax backgrounds</a></li>
-						<li><a href="https://github.com/hakimel/reveal.js#keyboard-bindings">Custom keyboard bindings</a></li>
-					</ul>
-				</section>
-
-				<section style="text-align: left;">
-					<h1>THE END</h1>
-					<p>
-						- <a href="http://slides.com">Try the online editor</a> <br>
-						- <a href="https://github.com/hakimel/reveal.js">Source code &amp; documentation</a>
-					</p>
-				</section>
-
+				<section>Slide 1</section>
+				<section>Slide 2</section>
 			</div>
-
 		</div>
 
 		<script src="lib/js/head.min.js"></script>
 		<script src="js/reveal.js"></script>
 
 		<script>
-
-			// Full list of configuration options available at:
-			// https://github.com/hakimel/reveal.js#configuration
+			// More info about config & dependencies:
+			// - https://github.com/hakimel/reveal.js#configuration
+			// - https://github.com/hakimel/reveal.js#dependencies
 			Reveal.initialize({
-				controls: true,
-				progress: true,
-				history: true,
-				center: true,
-
-				transition: 'slide', // none/fade/slide/convex/concave/zoom
-
-				// Optional reveal.js plugins
 				dependencies: [
-					{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
-					{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-					{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
-					{ src: 'plugin/zoom-js/zoom.js', async: true },
-					{ src: 'plugin/notes/notes.js', async: true }
+					{ src: 'plugin/markdown/marked.js' },
+					{ src: 'plugin/markdown/markdown.js' },
+					{ src: 'plugin/notes/notes.js', async: true },
+					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
 				]
 			});
-
 		</script>
-
 	</body>
 </html>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 702 - 277
js/reveal.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 9 - 8
lib/js/head.min.js


+ 17 - 18
package.json

@@ -1,13 +1,14 @@
 {
   "name": "reveal.js",
-  "version": "3.2.0",
+  "version": "3.5.0",
   "description": "The HTML Presentation Framework",
   "homepage": "http://lab.hakim.se/reveal-js",
   "subdomain": "revealjs",
   "main": "js/reveal.js",
   "scripts": {
     "test": "grunt test",
-    "start": "grunt serve"
+    "start": "grunt serve",
+    "build": "grunt"
   },
   "author": {
     "name": "Hakim El Hattab",
@@ -19,27 +20,25 @@
     "url": "git://github.com/hakimel/reveal.js.git"
   },
   "engines": {
-    "node": "~4.1.1"
-  },
-  "dependencies": {
-    "underscore": "~1.8.3",
-    "express": "~4.13.3",
-    "mustache": "~2.1.3",
-    "socket.io": "~1.3.7"
+    "node": ">=4.0.0"
   },
   "devDependencies": {
-    "grunt-contrib-qunit": "~0.7.0",
-    "grunt-contrib-jshint": "~0.11.3",
+    "express": "~4.14.0",
+    "grunt": "~1.0.1",
+    "grunt-autoprefixer": "~3.0.3",
+    "grunt-cli": "~1.2.0",
+    "grunt-contrib-connect": "~0.11.2",
     "grunt-contrib-cssmin": "~0.14.0",
+    "grunt-contrib-jshint": "~0.11.3",
+    "grunt-contrib-qunit": "~1.2.0",
     "grunt-contrib-uglify": "~0.9.2",
-    "grunt-contrib-watch": "~0.6.1",
-    "grunt-sass": "~1.1.0-beta",
-    "grunt-contrib-connect": "~0.11.2",
-    "grunt-autoprefixer": "~3.0.3",
+    "grunt-contrib-watch": "~1.0.0",
+    "grunt-sass": "~1.2.0",
+    "grunt-retire": "~0.3.10",
     "grunt-zip": "~0.17.1",
-    "grunt": "~0.4.5",
-    "node-sass": "~3.3.3"
+    "mustache": "~2.2.1",
+    "node-sass": "~3.13.0",
+    "socket.io": "^1.4.8"
   },
-  
   "license": "MIT"
 }

+ 48 - 1
plugin/highlight/highlight.js

@@ -1,5 +1,52 @@
 // START CUSTOM REVEAL.JS INTEGRATION
 (function() {
+	// Function to perform a better "data-trim" on code snippets
+	// Will slice an indentation amount on each line of the snippet (amount based on the line having the lowest indentation length)
+	function betterTrim(snippetEl) {
+		// Helper functions
+		function trimLeft(val) {
+			// Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
+			return val.replace(/^[\s\uFEFF\xA0]+/g, '');
+		}
+		function trimLineBreaks(input) {
+			var lines = input.split('\n');
+
+			// Trim line-breaks from the beginning
+			for (var i = 0; i < lines.length; i++) {
+				if (lines[i].trim() === '') {
+					lines.splice(i--, 1);
+				} else break;
+			}
+
+			// Trim line-breaks from the end
+			for (var i = lines.length-1; i >= 0; i--) {
+				if (lines[i].trim() === '') {
+					lines.splice(i, 1);
+				} else break;
+			}
+
+			return lines.join('\n');
+		}
+
+		// Main function for betterTrim()
+		return (function(snippetEl) {
+			var content = trimLineBreaks(snippetEl.innerHTML);
+			var lines = content.split('\n');
+			// Calculate the minimum amount to remove on each line start of the snippet (can be 0)
+			var pad = lines.reduce(function(acc, line) {
+				if (line.length > 0 && trimLeft(line).length > 0 && acc > line.length - trimLeft(line).length) {
+					return line.length - trimLeft(line).length;
+				}
+				return acc;
+			}, Number.POSITIVE_INFINITY);
+			// Slice each line with this amount
+			return lines.map(function(line, index) {
+				return line.slice(pad);
+			})
+			.join('\n');
+		})(snippetEl);
+	}
+
 	if( typeof window.addEventListener === 'function' ) {
 		var hljs_nodes = document.querySelectorAll( 'pre code' );
 
@@ -8,7 +55,7 @@
 
 			// trim whitespace if data-trim attribute is present
 			if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) {
-				element.innerHTML = element.innerHTML.trim();
+				element.innerHTML = betterTrim(element);
 			}
 
 			// Now escape html unless prevented by author

+ 28 - 18
plugin/markdown/markdown.js

@@ -4,28 +4,19 @@
  * of external markdown documents.
  */
 (function( root, factory ) {
-	if( typeof exports === 'object' ) {
+	if (typeof define === 'function' && define.amd) {
+		root.marked = require( './marked' );
+		root.RevealMarkdown = factory( root.marked );
+		root.RevealMarkdown.initialize();
+	} else if( typeof exports === 'object' ) {
 		module.exports = factory( require( './marked' ) );
-	}
-	else {
+	} else {
 		// Browser globals (root is window)
 		root.RevealMarkdown = factory( root.marked );
 		root.RevealMarkdown.initialize();
 	}
 }( this, function( marked ) {
 
-	if( typeof marked === 'undefined' ) {
-		throw 'The reveal.js Markdown plugin requires marked to be loaded';
-	}
-
-	if( typeof hljs !== 'undefined' ) {
-		marked.setOptions({
-			highlight: function( lang, code ) {
-				return hljs.highlightAuto( lang, code ).value;
-			}
-		});
-	}
-
 	var DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
 		DEFAULT_NOTES_SEPARATOR = 'note:',
 		DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
@@ -40,7 +31,8 @@
 	 */
 	function getMarkdownFromSlide( section ) {
 
-		var template = section.querySelector( 'script' );
+		// look for a <script> or <textarea data-template> wrapper
+		var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
 
 		// strip leading whitespace so it isn't evaluated as code
 		var text = ( template || section ).textContent;
@@ -117,7 +109,7 @@
 		var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
 
 		if( notesMatch.length === 2 ) {
-			content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
+			content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
 		}
 
 		// prevent script end tags in the content from interfering
@@ -186,7 +178,7 @@
 				markdownSections += '<section '+ options.attributes +'>';
 
 				sectionStack[i].forEach( function( child ) {
-					markdownSections += '<section data-markdown>' +  createMarkdownSlide( child, options ) + '</section>';
+					markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
 				} );
 
 				markdownSections += '</section>';
@@ -388,6 +380,24 @@
 	return {
 
 		initialize: function() {
+			if( typeof marked === 'undefined' ) {
+				throw 'The reveal.js Markdown plugin requires marked to be loaded';
+			}
+
+			if( typeof hljs !== 'undefined' ) {
+				marked.setOptions({
+					highlight: function( code, lang ) {
+						return hljs.highlightAuto( code, [lang] ).value;
+					}
+				});
+			}
+
+			var options = Reveal.getConfig().markdown;
+
+			if ( options ) {
+				marked.setOptions( options );
+			}
+
 			processSlides();
 			convertSlides();
 		},

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
plugin/markdown/marked.js


+ 1 - 1
plugin/math/math.js

@@ -7,7 +7,7 @@
 var RevealMath = window.RevealMath || (function(){
 
 	var options = Reveal.getConfig().math || {};
-	options.mathjax = options.mathjax || 'https://cdn.mathjax.org/mathjax/latest/MathJax.js';
+	options.mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
 	options.config = options.config || 'TeX-AMS_HTML-full';
 
 	loadScript( options.mathjax + '?config=' + options.config, function() {

+ 9 - 1
plugin/multiplex/index.js

@@ -31,7 +31,15 @@ io.on( 'connection', function( socket ) {
 
 app.get("/", function(req, res) {
 	res.writeHead(200, {'Content-Type': 'text/html'});
-	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+
+	var stream = fs.createReadStream(opts.baseDir + '/index.html');
+	stream.on('error', function( error ) {
+		res.write('<style>body{font-family: sans-serif;}</style><h2>reveal.js multiplex server.</h2><a href="/token">Generate token</a>');
+		res.end();
+	});
+	stream.on('readable', function() {
+		stream.pipe(res);
+	});
 });
 
 app.get("/token", function(req,res) {

+ 19 - 0
plugin/multiplex/package.json

@@ -0,0 +1,19 @@
+{
+  "name": "reveal-js-multiplex",
+  "version": "1.0.0",
+  "description": "reveal.js multiplex server",
+  "homepage": "http://lab.hakim.se/reveal-js",
+  "scripts": {
+    "start": "node index.js"
+  },
+  "engines": {
+    "node": "~4.1.1"
+  },
+  "dependencies": {
+    "express": "~4.13.3",
+    "grunt-cli": "~0.1.13",
+    "mustache": "~2.2.1",
+    "socket.io": "~1.3.7"
+  },
+  "license": "MIT"
+}

+ 3 - 2
plugin/notes-server/index.js

@@ -2,7 +2,6 @@ var http      = require('http');
 var express   = require('express');
 var fs        = require('fs');
 var io        = require('socket.io');
-var _         = require('underscore');
 var Mustache  = require('mustache');
 
 var app       = express();
@@ -23,10 +22,12 @@ io.on( 'connection', function( socket ) {
 	});
 
 	socket.on( 'statechanged', function( data ) {
+		delete data.state.overview;
 		socket.broadcast.emit( 'statechanged', data );
 	});
 
 	socket.on( 'statechanged-speaker', function( data ) {
+		delete data.state.overview;
 		socket.broadcast.emit( 'statechanged-speaker', data );
 	});
 
@@ -64,5 +65,5 @@ var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : ''
 
 console.log( brown + 'reveal.js - Speaker Notes' + reset );
 console.log( '1. Open the slides at ' + green + slidesLocation + reset );
-console.log( '2. Click on the link your JS console to go to the notes page' );
+console.log( '2. Click on the link in your JS console to go to the notes page' );
 console.log( '3. Advance through your slides and your notes will advance automatically' );

+ 198 - 20
plugin/notes-server/notes.html

@@ -8,6 +8,7 @@
 		<style>
 			body {
 				font-family: Helvetica;
+				font-size: 18px;
 			}
 
 			#current-slide,
@@ -30,15 +31,26 @@
 				position: absolute;
 				top: 10px;
 				left: 10px;
-				font-weight: bold;
-				font-size: 14px;
 				z-index: 2;
-				color: rgba( 255, 255, 255, 0.9 );
+			}
+
+			.overlay-element {
+				height: 34px;
+				line-height: 34px;
+				padding: 0 10px;
+				text-shadow: none;
+				background: rgba( 220, 220, 220, 0.8 );
+				color: #222;
+				font-size: 14px;
+			}
+
+			.overlay-element.interactive:hover {
+				background: rgba( 220, 220, 220, 1 );
 			}
 
 			#current-slide {
 				position: absolute;
-				width: 65%;
+				width: 60%;
 				height: 100%;
 				top: 0;
 				left: 0;
@@ -47,19 +59,20 @@
 
 			#upcoming-slide {
 				position: absolute;
-				width: 35%;
+				width: 40%;
 				height: 40%;
 				right: 0;
 				top: 0;
 			}
 
+			/* Speaker controls */
 			#speaker-controls {
 				position: absolute;
 				top: 40%;
 				right: 0;
-				width: 35%;
+				width: 40%;
 				height: 60%;
-
+				overflow: auto;
 				font-size: 18px;
 			}
 
@@ -124,26 +137,108 @@
 					font-size: 1.2em;
 				}
 
+			/* Layout selector */
+			#speaker-layout {
+				position: absolute;
+				top: 10px;
+				right: 10px;
+				color: #222;
+				z-index: 10;
+			}
+				#speaker-layout select {
+					position: absolute;
+					width: 100%;
+					height: 100%;
+					top: 0;
+					left: 0;
+					border: 0;
+					box-shadow: 0;
+					cursor: pointer;
+					opacity: 0;
+
+					font-size: 1em;
+					background-color: transparent;
+
+					-moz-appearance: none;
+					-webkit-appearance: none;
+					-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+				}
+
+				#speaker-layout select:focus {
+					outline: none;
+					box-shadow: none;
+				}
+
 			.clear {
 				clear: both;
 			}
 
-			@media screen and (max-width: 1080px) {
-				#speaker-controls {
-					font-size: 16px;
-				}
+			/* Speaker layout: Wide */
+			body[data-speaker-layout="wide"] #current-slide,
+			body[data-speaker-layout="wide"] #upcoming-slide {
+				width: 50%;
+				height: 45%;
+				padding: 6px;
 			}
 
-			@media screen and (max-width: 900px) {
-				#speaker-controls {
-					font-size: 14px;
-				}
+			body[data-speaker-layout="wide"] #current-slide {
+				top: 0;
+				left: 0;
 			}
 
-			@media screen and (max-width: 800px) {
-				#speaker-controls {
-					font-size: 12px;
-				}
+			body[data-speaker-layout="wide"] #upcoming-slide {
+				top: 0;
+				left: 50%;
+			}
+
+			body[data-speaker-layout="wide"] #speaker-controls {
+				top: 45%;
+				left: 0;
+				width: 100%;
+				height: 50%;
+				font-size: 1.25em;
+			}
+
+			/* Speaker layout: Tall */
+			body[data-speaker-layout="tall"] #current-slide,
+			body[data-speaker-layout="tall"] #upcoming-slide {
+				width: 45%;
+				height: 50%;
+				padding: 6px;
+			}
+
+			body[data-speaker-layout="tall"] #current-slide {
+				top: 0;
+				left: 0;
+			}
+
+			body[data-speaker-layout="tall"] #upcoming-slide {
+				top: 50%;
+				left: 0;
+			}
+
+			body[data-speaker-layout="tall"] #speaker-controls {
+				padding-top: 40px;
+				top: 0;
+				left: 45%;
+				width: 55%;
+				height: 100%;
+				font-size: 1.25em;
+			}
+
+			/* Speaker layout: Notes only */
+			body[data-speaker-layout="notes-only"] #current-slide,
+			body[data-speaker-layout="notes-only"] #upcoming-slide {
+				display: none;
+			}
+
+			body[data-speaker-layout="notes-only"] #speaker-controls {
+				padding-top: 40px;
+				top: 0;
+				left: 0;
+				width: 100%;
+				height: 100%;
+				font-size: 1.25em;
 			}
 
 		</style>
@@ -152,7 +247,7 @@
 	<body>
 
 		<div id="current-slide"></div>
-		<div id="upcoming-slide"><span class="label">UPCOMING:</span></div>
+		<div id="upcoming-slide"><span class="overlay-element label">Upcoming</span></div>
 		<div id="speaker-controls">
 			<div class="speaker-controls-time">
 				<h4 class="label">Time <span class="reset-button">Click to Reset</span></h4>
@@ -170,6 +265,10 @@
 				<div class="value"></div>
 			</div>
 		</div>
+		<div id="speaker-layout" class="overlay-element interactive">
+			<span class="speaker-layout-label"></span>
+			<select class="speaker-layout-dropdown"></select>
+		</div>
 
 		<script src="/socket.io/socket.io.js"></script>
 		<script src="/plugin/markdown/marked.js"></script>
@@ -182,11 +281,20 @@
 				currentState,
 				currentSlide,
 				upcomingSlide,
+				layoutLabel,
+				layoutDropdown,
 				connected = false;
 
 			var socket = io.connect( window.location.origin ),
 				socketId = '{{socketId}}';
 
+			var SPEAKER_LAYOUTS = {
+				'default': 'Default',
+				'wide': 'Wide',
+				'tall': 'Tall',
+				'notes-only': 'Notes only'
+			};
+
 			socket.on( 'statechanged', function( data ) {
 
 				// ignore data from sockets that aren't ours
@@ -205,6 +313,8 @@
 
 			} );
 
+			setupLayout();
+
 			// Load our presentation iframes
 			setupIframes();
 
@@ -362,6 +472,74 @@
 
 			}
 
+			/**
+				 * Sets up the speaker view layout and layout selector.
+				 */
+				function setupLayout() {
+
+					layoutDropdown = document.querySelector( '.speaker-layout-dropdown' );
+					layoutLabel = document.querySelector( '.speaker-layout-label' );
+
+					// Render the list of available layouts
+					for( var id in SPEAKER_LAYOUTS ) {
+						var option = document.createElement( 'option' );
+						option.setAttribute( 'value', id );
+						option.textContent = SPEAKER_LAYOUTS[ id ];
+						layoutDropdown.appendChild( option );
+					}
+
+					// Monitor the dropdown for changes
+					layoutDropdown.addEventListener( 'change', function( event ) {
+
+						setLayout( layoutDropdown.value );
+
+					}, false );
+
+					// Restore any currently persisted layout
+					setLayout( getLayout() );
+
+				}
+
+				/**
+				 * Sets a new speaker view layout. The layout is persisted
+				 * in local storage.
+				 */
+				function setLayout( value ) {
+
+					var title = SPEAKER_LAYOUTS[ value ];
+
+					layoutLabel.innerHTML = 'Layout' + ( title ? ( ': ' + title ) : '' );
+					layoutDropdown.value = value;
+
+					document.body.setAttribute( 'data-speaker-layout', value );
+
+					// Persist locally
+					if( window.localStorage ) {
+						window.localStorage.setItem( 'reveal-speaker-layout', value );
+					}
+
+				}
+
+				/**
+				 * Returns the ID of the most recently set speaker layout
+				 * or our default layout if none has been set.
+				 */
+				function getLayout() {
+
+					if( window.localStorage ) {
+						var layout = window.localStorage.getItem( 'reveal-speaker-layout' );
+						if( layout ) {
+							return layout;
+						}
+					}
+
+					// Default to the first record in the layouts hash
+					for( var id in SPEAKER_LAYOUTS ) {
+						return id;
+					}
+
+				}
+
 			function zeroPadInteger( num ) {
 
 				var str = '00' + parseInt( num );

+ 371 - 32
plugin/notes/notes.html

@@ -8,6 +8,7 @@
 		<style>
 			body {
 				font-family: Helvetica;
+				font-size: 18px;
 			}
 
 			#current-slide,
@@ -30,15 +31,26 @@
 				position: absolute;
 				top: 10px;
 				left: 10px;
-				font-weight: bold;
-				font-size: 14px;
 				z-index: 2;
-				color: rgba( 255, 255, 255, 0.9 );
+			}
+
+			.overlay-element {
+				height: 34px;
+				line-height: 34px;
+				padding: 0 10px;
+				text-shadow: none;
+				background: rgba( 220, 220, 220, 0.8 );
+				color: #222;
+				font-size: 14px;
+			}
+
+			.overlay-element.interactive:hover {
+				background: rgba( 220, 220, 220, 1 );
 			}
 
 			#current-slide {
 				position: absolute;
-				width: 65%;
+				width: 60%;
 				height: 100%;
 				top: 0;
 				left: 0;
@@ -47,20 +59,20 @@
 
 			#upcoming-slide {
 				position: absolute;
-				width: 35%;
+				width: 40%;
 				height: 40%;
 				right: 0;
 				top: 0;
 			}
 
+			/* Speaker controls */
 			#speaker-controls {
 				position: absolute;
 				top: 40%;
 				right: 0;
-				width: 35%;
+				width: 40%;
 				height: 60%;
 				overflow: auto;
-
 				font-size: 18px;
 			}
 
@@ -70,6 +82,7 @@
 				}
 
 				.speaker-controls-time .label,
+				.speaker-controls-pace .label,
 				.speaker-controls-notes .label {
 					text-transform: uppercase;
 					font-weight: normal;
@@ -78,7 +91,7 @@
 					margin: 0;
 				}
 
-				.speaker-controls-time {
+				.speaker-controls-time, .speaker-controls-pace {
 					border-bottom: 1px solid rgba( 200, 200, 200, 0.5 );
 					margin-bottom: 10px;
 					padding: 10px 16px;
@@ -99,6 +112,13 @@
 				.speaker-controls-time .timer,
 				.speaker-controls-time .clock {
 					width: 50%;
+				}
+
+				.speaker-controls-time .timer,
+				.speaker-controls-time .clock,
+				.speaker-controls-time .pacing .hours-value,
+				.speaker-controls-time .pacing .minutes-value,
+				.speaker-controls-time .pacing .seconds-value {
 					font-size: 1.9em;
 				}
 
@@ -112,7 +132,23 @@
 				}
 
 				.speaker-controls-time span.mute {
-					color: #bbb;
+					opacity: 0.3;
+				}
+
+				.speaker-controls-time .pacing-title {
+					margin-top: 5px;
+				}
+
+				.speaker-controls-time .pacing.ahead {
+					color: blue;
+				}
+
+				.speaker-controls-time .pacing.on-track {
+					color: green;
+				}
+
+				.speaker-controls-time .pacing.behind {
+					color: red;
 				}
 
 				.speaker-controls-notes {
@@ -125,24 +161,124 @@
 					font-size: 1.2em;
 				}
 
+			/* Layout selector */
+			#speaker-layout {
+				position: absolute;
+				top: 10px;
+				right: 10px;
+				color: #222;
+				z-index: 10;
+			}
+				#speaker-layout select {
+					position: absolute;
+					width: 100%;
+					height: 100%;
+					top: 0;
+					left: 0;
+					border: 0;
+					box-shadow: 0;
+					cursor: pointer;
+					opacity: 0;
+
+					font-size: 1em;
+					background-color: transparent;
+
+					-moz-appearance: none;
+					-webkit-appearance: none;
+					-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+				}
+
+				#speaker-layout select:focus {
+					outline: none;
+					box-shadow: none;
+				}
+
 			.clear {
 				clear: both;
 			}
 
+			/* Speaker layout: Wide */
+			body[data-speaker-layout="wide"] #current-slide,
+			body[data-speaker-layout="wide"] #upcoming-slide {
+				width: 50%;
+				height: 45%;
+				padding: 6px;
+			}
+
+			body[data-speaker-layout="wide"] #current-slide {
+				top: 0;
+				left: 0;
+			}
+
+			body[data-speaker-layout="wide"] #upcoming-slide {
+				top: 0;
+				left: 50%;
+			}
+
+			body[data-speaker-layout="wide"] #speaker-controls {
+				top: 45%;
+				left: 0;
+				width: 100%;
+				height: 50%;
+				font-size: 1.25em;
+			}
+
+			/* Speaker layout: Tall */
+			body[data-speaker-layout="tall"] #current-slide,
+			body[data-speaker-layout="tall"] #upcoming-slide {
+				width: 45%;
+				height: 50%;
+				padding: 6px;
+			}
+
+			body[data-speaker-layout="tall"] #current-slide {
+				top: 0;
+				left: 0;
+			}
+
+			body[data-speaker-layout="tall"] #upcoming-slide {
+				top: 50%;
+				left: 0;
+			}
+
+			body[data-speaker-layout="tall"] #speaker-controls {
+				padding-top: 40px;
+				top: 0;
+				left: 45%;
+				width: 55%;
+				height: 100%;
+				font-size: 1.25em;
+			}
+
+			/* Speaker layout: Notes only */
+			body[data-speaker-layout="notes-only"] #current-slide,
+			body[data-speaker-layout="notes-only"] #upcoming-slide {
+				display: none;
+			}
+
+			body[data-speaker-layout="notes-only"] #speaker-controls {
+				padding-top: 40px;
+				top: 0;
+				left: 0;
+				width: 100%;
+				height: 100%;
+				font-size: 1.25em;
+			}
+
 			@media screen and (max-width: 1080px) {
-				#speaker-controls {
+				body[data-speaker-layout="default"] #speaker-controls {
 					font-size: 16px;
 				}
 			}
 
 			@media screen and (max-width: 900px) {
-				#speaker-controls {
+				body[data-speaker-layout="default"] #speaker-controls {
 					font-size: 14px;
 				}
 			}
 
 			@media screen and (max-width: 800px) {
-				#speaker-controls {
+				body[data-speaker-layout="default"] #speaker-controls {
 					font-size: 12px;
 				}
 			}
@@ -153,7 +289,7 @@
 	<body>
 
 		<div id="current-slide"></div>
-		<div id="upcoming-slide"><span class="label">UPCOMING:</span></div>
+		<div id="upcoming-slide"><span class="overlay-element label">Upcoming</span></div>
 		<div id="speaker-controls">
 			<div class="speaker-controls-time">
 				<h4 class="label">Time <span class="reset-button">Click to Reset</span></h4>
@@ -164,6 +300,11 @@
 					<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
 				</div>
 				<div class="clear"></div>
+
+				<h4 class="label pacing-title" style="display: none">Pacing – Time to finish current slide</h4>
+				<div class="pacing" style="display: none">
+					<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
+				</div>
 			</div>
 
 			<div class="speaker-controls-notes hidden">
@@ -171,6 +312,10 @@
 				<div class="value"></div>
 			</div>
 		</div>
+		<div id="speaker-layout" class="overlay-element interactive">
+			<span class="speaker-layout-label"></span>
+			<select class="speaker-layout-dropdown"></select>
+		</div>
 
 		<script src="../../plugin/markdown/marked.js"></script>
 		<script>
@@ -182,12 +327,27 @@
 					currentState,
 					currentSlide,
 					upcomingSlide,
+					layoutLabel,
+					layoutDropdown,
 					connected = false;
 
+				var SPEAKER_LAYOUTS = {
+					'default': 'Default',
+					'wide': 'Wide',
+					'tall': 'Tall',
+					'notes-only': 'Notes only'
+				};
+
+				setupLayout();
+
 				window.addEventListener( 'message', function( event ) {
 
 					var data = JSON.parse( event.data );
 
+					// The overview mode is only useful to the reveal.js instance
+					// where navigation occurs so we don't sync it
+					if( data.state ) delete data.state.overview;
+
 					// Messages sent by the notes plugin inside of the main window
 					if( data && data.namespace === 'reveal-notes' ) {
 						if( data.type === 'connect' ) {
@@ -203,8 +363,10 @@
 							// Send a message back to notify that the handshake is complete
 							window.opener.postMessage( JSON.stringify({ namespace: 'reveal-notes', type: 'connected'} ), '*' );
 						}
-						else if( /slidechanged|fragmentshown|fragmenthidden|overviewshown|overviewhidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
+						else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
+
 							window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ]} ), '*' );
+
 						}
 					}
 
@@ -288,9 +450,10 @@
 						'backgroundTransition=none'
 					].join( '&' );
 
+					var urlSeparator = /\?/.test(data.url) ? '&' : '?';
 					var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
-					var currentURL = data.url + '?' + params + '&postMessageEvents=true' + hash;
-					var upcomingURL = data.url + '?' + params + '&controls=false' + hash;
+					var currentURL = data.url + urlSeparator + params + '&postMessageEvents=true' + hash;
+					var upcomingURL = data.url + urlSeparator + params + '&controls=false' + hash;
 
 					currentSlide = document.createElement( 'iframe' );
 					currentSlide.setAttribute( 'width', 1280 );
@@ -316,6 +479,47 @@
 
 				}
 
+				function getTimings() {
+
+					var slides = Reveal.getSlides();
+					var defaultTiming = Reveal.getConfig().defaultTiming;
+					if (defaultTiming == null) {
+						return null;
+					}
+					var timings = [];
+					for ( var i in slides ) {
+						var slide = slides[i];
+						var timing = defaultTiming;
+						if( slide.hasAttribute( 'data-timing' )) {
+							var t = slide.getAttribute( 'data-timing' );
+							timing = parseInt(t);
+							if( isNaN(timing) ) {
+								console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
+								timing = defaultTiming;
+							}
+						}
+						timings.push(timing);
+					}
+					return timings;
+
+				}
+
+				/**
+				 * Return the number of seconds allocated for presenting
+				 * all slides up to and including this one.
+				 */
+				function getTimeAllocated(timings) {
+
+					var slides = Reveal.getSlides();
+					var allocated = 0;
+					var currentSlide = Reveal.getSlidePastCount();
+					for (var i in slides.slice(0, currentSlide + 1)) {
+						allocated += timings[i];
+					}
+					return allocated;
+
+				}
+
 				/**
 				 * Create the timer and clock and start updating them
 				 * at an interval.
@@ -323,28 +527,78 @@
 				function setupTimer() {
 
 					var start = new Date(),
-						timeEl = document.querySelector( '.speaker-controls-time' ),
-						clockEl = timeEl.querySelector( '.clock-value' ),
-						hoursEl = timeEl.querySelector( '.hours-value' ),
-						minutesEl = timeEl.querySelector( '.minutes-value' ),
-						secondsEl = timeEl.querySelector( '.seconds-value' );
+					timeEl = document.querySelector( '.speaker-controls-time' ),
+					clockEl = timeEl.querySelector( '.clock-value' ),
+					hoursEl = timeEl.querySelector( '.hours-value' ),
+					minutesEl = timeEl.querySelector( '.minutes-value' ),
+					secondsEl = timeEl.querySelector( '.seconds-value' ),
+					pacingTitleEl = timeEl.querySelector( '.pacing-title' ),
+					pacingEl = timeEl.querySelector( '.pacing' ),
+					pacingHoursEl = pacingEl.querySelector( '.hours-value' ),
+					pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ),
+					pacingSecondsEl = pacingEl.querySelector( '.seconds-value' );
+
+					var timings = getTimings();
+					if (timings !== null) {
+						pacingTitleEl.style.removeProperty('display');
+						pacingEl.style.removeProperty('display');
+					}
+
+					function _displayTime( hrEl, minEl, secEl, time) {
+
+						var sign = Math.sign(time) == -1 ? "-" : "";
+						time = Math.abs(Math.round(time / 1000));
+						var seconds = time % 60;
+						var minutes = Math.floor( time / 60 ) % 60 ;
+						var hours = Math.floor( time / ( 60 * 60 )) ;
+						hrEl.innerHTML = sign + zeroPadInteger( hours );
+						if (hours == 0) {
+							hrEl.classList.add( 'mute' );
+						}
+						else {
+							hrEl.classList.remove( 'mute' );
+						}
+						minEl.innerHTML = ':' + zeroPadInteger( minutes );
+						if (hours == 0 && minutes == 0) {
+							minEl.classList.add( 'mute' );
+						}
+						else {
+							minEl.classList.remove( 'mute' );
+						}
+						secEl.innerHTML = ':' + zeroPadInteger( seconds );
+					}
 
 					function _updateTimer() {
 
 						var diff, hours, minutes, seconds,
-							now = new Date();
+						now = new Date();
 
 						diff = now.getTime() - start.getTime();
-						hours = Math.floor( diff / ( 1000 * 60 * 60 ) );
-						minutes = Math.floor( ( diff / ( 1000 * 60 ) ) % 60 );
-						seconds = Math.floor( ( diff / 1000 ) % 60 );
 
 						clockEl.innerHTML = now.toLocaleTimeString( 'en-US', { hour12: true, hour: '2-digit', minute:'2-digit' } );
-						hoursEl.innerHTML = zeroPadInteger( hours );
-						hoursEl.className = hours > 0 ? '' : 'mute';
-						minutesEl.innerHTML = ':' + zeroPadInteger( minutes );
-						minutesEl.className = minutes > 0 ? '' : 'mute';
-						secondsEl.innerHTML = ':' + zeroPadInteger( seconds );
+						_displayTime( hoursEl, minutesEl, secondsEl, diff );
+						if (timings !== null) {
+							_updatePacing(diff);
+						}
+
+					}
+
+					function _updatePacing(diff) {
+
+						var slideEndTiming = getTimeAllocated(timings) * 1000;
+						var currentSlide = Reveal.getSlidePastCount();
+						var currentSlideTiming = timings[currentSlide] * 1000;
+						var timeLeftCurrentSlide = slideEndTiming - diff;
+						if (timeLeftCurrentSlide < 0) {
+							pacingEl.className = 'pacing behind';
+						}
+						else if (timeLeftCurrentSlide < currentSlideTiming) {
+							pacingEl.className = 'pacing on-track';
+						}
+						else {
+							pacingEl.className = 'pacing ahead';
+						}
+						_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
 
 					}
 
@@ -354,14 +608,99 @@
 					// Then update every second
 					setInterval( _updateTimer, 1000 );
 
-					timeEl.addEventListener( 'click', function() {
-						start = new Date();
+					function _resetTimer() {
+
+						if (timings == null) {
+							start = new Date();
+						}
+						else {
+							// Reset timer to beginning of current slide
+							var slideEndTiming = getTimeAllocated(timings) * 1000;
+							var currentSlide = Reveal.getSlidePastCount();
+							var currentSlideTiming = timings[currentSlide] * 1000;
+							var previousSlidesTiming = slideEndTiming - currentSlideTiming;
+							var now = new Date();
+							start = new Date(now.getTime() - previousSlidesTiming);
+						}
 						_updateTimer();
+
+					}
+
+					timeEl.addEventListener( 'click', function() {
+						_resetTimer();
 						return false;
 					} );
 
 				}
 
+				/**
+				 * Sets up the speaker view layout and layout selector.
+				 */
+				function setupLayout() {
+
+					layoutDropdown = document.querySelector( '.speaker-layout-dropdown' );
+					layoutLabel = document.querySelector( '.speaker-layout-label' );
+
+					// Render the list of available layouts
+					for( var id in SPEAKER_LAYOUTS ) {
+						var option = document.createElement( 'option' );
+						option.setAttribute( 'value', id );
+						option.textContent = SPEAKER_LAYOUTS[ id ];
+						layoutDropdown.appendChild( option );
+					}
+
+					// Monitor the dropdown for changes
+					layoutDropdown.addEventListener( 'change', function( event ) {
+
+						setLayout( layoutDropdown.value );
+
+					}, false );
+
+					// Restore any currently persisted layout
+					setLayout( getLayout() );
+
+				}
+
+				/**
+				 * Sets a new speaker view layout. The layout is persisted
+				 * in local storage.
+				 */
+				function setLayout( value ) {
+
+					var title = SPEAKER_LAYOUTS[ value ];
+
+					layoutLabel.innerHTML = 'Layout' + ( title ? ( ': ' + title ) : '' );
+					layoutDropdown.value = value;
+
+					document.body.setAttribute( 'data-speaker-layout', value );
+
+					// Persist locally
+					if( window.localStorage ) {
+						window.localStorage.setItem( 'reveal-speaker-layout', value );
+					}
+
+				}
+
+				/**
+				 * Returns the ID of the most recently set speaker layout
+				 * or our default layout if none has been set.
+				 */
+				function getLayout() {
+
+					if( window.localStorage ) {
+						var layout = window.localStorage.getItem( 'reveal-speaker-layout' );
+						if( layout ) {
+							return layout;
+						}
+					}
+
+					// Default to the first record in the layouts hash
+					for( var id in SPEAKER_LAYOUTS ) {
+						return id;
+					}
+
+				}
+
 				function zeroPadInteger( num ) {
 
 					var str = '00' + parseInt( num );

+ 34 - 6
plugin/notes/notes.js

@@ -11,10 +11,18 @@
  */
 var RevealNotes = (function() {
 
-	function openNotes() {
-		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
-		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
-		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1100,height=700' );
+	function openNotes( notesFilePath ) {
+
+		if( !notesFilePath ) {
+			var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+			jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+			notesFilePath = jsFileLocation + 'notes.html';
+		}
+
+		var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
+
+		// Allow popup window access to Reveal API
+		notesPopup.Reveal = this.Reveal;
 
 		/**
 		 * Connect to the notes window through a postmessage handshake.
@@ -45,10 +53,11 @@ var RevealNotes = (function() {
 		/**
 		 * Posts the current slide data to the notes window
 		 */
-		function post() {
+		function post( event ) {
 
 			var slideElement = Reveal.getCurrentSlide(),
-				notesElement = slideElement.querySelector( 'aside.notes' );
+				notesElement = slideElement.querySelector( 'aside.notes' ),
+				fragmentElement = slideElement.querySelector( '.current-fragment' );
 
 			var messageData = {
 				namespace: 'reveal-notes',
@@ -65,6 +74,21 @@ var RevealNotes = (function() {
 				messageData.whitespace = 'pre-wrap';
 			}
 
+			// Look for notes defined in a fragment
+			if( fragmentElement ) {
+				var fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
+				if( fragmentNotes ) {
+					notesElement = fragmentNotes;
+				}
+				else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
+					messageData.notes = fragmentElement.getAttribute( 'data-notes' );
+					messageData.whitespace = 'pre-wrap';
+
+					// In case there are slide notes
+					notesElement = null;
+				}
+			}
+
 			// Look for notes defined in an aside element
 			if( notesElement ) {
 				messageData.notes = notesElement.innerHTML;
@@ -96,6 +120,7 @@ var RevealNotes = (function() {
 		}
 
 		connect();
+
 	}
 
 	if( !/receiver/i.test( window.location.search ) ) {
@@ -108,6 +133,9 @@ var RevealNotes = (function() {
 		// Open the notes when the 's' key is hit
 		Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes'}, openNotes);
 
+		// Show our keyboard shortcut in the reveal.js help overlay
+		if( window.Reveal ) Reveal.registerKeyboardShortcut( 'S', 'Speaker notes view' );
+
 	}
 
 	return { open: openNotes };

+ 47 - 26
plugin/print-pdf/print-pdf.js

@@ -4,30 +4,16 @@
  * Example:
  * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
  *
- * By Manuel Bieh (https://github.com/manuelbieh)
+ * @author Manuel Bieh (https://github.com/manuelbieh)
+ * @author Hakim El Hattab (https://github.com/hakimel)
+ * @author Manuel Riezebosch (https://github.com/riezebosch)
  */
 
 // html2pdf.js
-var page = new WebPage();
 var system = require( 'system' );
 
-var slideWidth = system.args[3] ? system.args[3].split( 'x' )[0] : 960;
-var slideHeight = system.args[3] ? system.args[3].split( 'x' )[1] : 700;
-
-page.viewportSize = {
-	width: slideWidth,
-	height: slideHeight
-};
-
-// TODO
-// Something is wrong with these config values. An input
-// paper width of 1920px actually results in a 756px wide
-// PDF.
-page.paperSize = {
-	width: Math.round( slideWidth * 2 ),
-	height: Math.round( slideHeight * 2 ),
-	border: 0
-};
+var probePage = new WebPage();
+var printPage = new WebPage();
 
 var inputFile = system.args[1] || 'index.html?print-pdf';
 var outputFile = system.args[2] || 'slides.pdf';
@@ -36,13 +22,48 @@ if( outputFile.match( /\.pdf$/gi ) === null ) {
 	outputFile += '.pdf';
 }
 
-console.log( 'Printing PDF (Paper size: '+ page.paperSize.width + 'x' + page.paperSize.height +')' );
+console.log( 'Export PDF: Reading reveal.js config [1/4]' );
+
+probePage.open( inputFile, function( status ) {
+
+	console.log( 'Export PDF: Preparing print layout [2/4]' );
+
+	var config = probePage.evaluate( function() {
+		return Reveal.getConfig();
+	} );
+
+	if( config ) {
 
-page.open( inputFile, function( status ) {
-	window.setTimeout( function() {
-		console.log( 'Printed succesfully' );
-		page.render( outputFile );
-		phantom.exit();
-	}, 1000 );
+		printPage.paperSize = {
+			width: Math.floor( config.width * ( 1 + config.margin ) ),
+			height: Math.floor( config.height * ( 1 + config.margin ) ),
+			border: 0
+		};
+
+		printPage.open( inputFile, function( status ) {
+			console.log( 'Export PDF: Preparing pdf [3/4]')
+			printPage.evaluate(function() {
+				Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom );
+			});
+		} );
+
+		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() {
+				console.log( 'Export PDF: Writing file [4/4]' );
+				printPage.render( outputFile );
+				console.log( 'Export PDF: Finished successfully!' );
+				phantom.exit();
+			}, 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);
+
+    }
 } );
 
+

+ 11 - 1
plugin/zoom-js/zoom.js

@@ -11,7 +11,17 @@
 		if( event[ modifier ] && isEnabled ) {
 			event.preventDefault();
 
-			var bounds = event.target.getBoundingClientRect();
+			var bounds;
+			var originalDisplay = event.target.style.display;
+
+			// Get the bounding rect of the contents, not the containing box
+			if( window.getComputedStyle( event.target ).display === 'block' ) {
+				event.target.style.display = 'inline-block';
+				bounds = event.target.getBoundingClientRect();
+				event.target.style.display = originalDisplay;
+			} else {
+				bounds = event.target.getBoundingClientRect();
+			}
 
 			zoom.to({
 				x: ( bounds.left * revealScale ) - zoomPadding,

+ 1 - 1
test/examples/math.html

@@ -169,7 +169,7 @@
 				transition: 'linear',
 
 				math: {
-					// mathjax: 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
+					// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
 					config: 'TeX-AMS_HTML-full'
 				},
 

+ 1 - 1
test/examples/slide-backgrounds.html

@@ -93,7 +93,7 @@
 					<h2>Video background</h2>
 				</section>
 
-				<section data-background-iframe="https://slides.com">
+				<section data-background-iframe="https://slides.com/news/make-better-presentations/embed?style=hidden&autoSlide=4000">
 					<h2>Iframe background</h2>
 				</section>
 

+ 12 - 0
test/simple.md

@@ -0,0 +1,12 @@
+## Slide 1.1
+
+```js
+var a = 1;
+```
+
+
+## Slide 1.2
+
+
+
+## Slide 2

+ 36 - 0
test/test-markdown-external.html

@@ -0,0 +1,36 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown</title>
+
+		<link rel="stylesheet" href="../css/reveal.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+				<section data-markdown="simple.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.js"></script>
+		<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="test-markdown-external.js"></script>
+
+	</body>
+</html>

+ 24 - 0
test/test-markdown-external.js

@@ -0,0 +1,24 @@
+
+
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Vertical separator', function() {
+		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' );
+	});
+
+	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.' );
+	});
+
+
+} );
+
+Reveal.initialize();
+

+ 41 - 0
test/test-markdown-options.html

@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test Markdown Options</title>
+
+		<link rel="stylesheet" href="../css/reveal.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<section data-markdown>
+					<script type="text/template">
+						## Testing Markdown Options
+
+						This "slide" should contain 'smart' quotes.
+					</script>
+				</section>
+
+			</div>
+
+		</div>
+
+		<script src="../lib/js/head.min.js"></script>
+		<script src="../js/reveal.js"></script>
+		<script src="qunit-1.12.0.js"></script>
+
+		<script src="test-markdown-options.js"></script>
+
+	</body>
+</html>

+ 26 - 0
test/test-markdown-options.js

@@ -0,0 +1,26 @@
+Reveal.addEventListener( 'ready', function() {
+
+	QUnit.module( 'Markdown' );
+
+	test( 'Options are set', function() {
+		strictEqual( marked.defaults.smartypants, true );
+	});
+
+	test( 'Smart quotes are activated', function() {
+		var text = document.querySelector( '.reveal .slides>section>p' ).textContent;
+
+		strictEqual( /['"]/.test( text ), false );
+		strictEqual( /[“”‘’]/.test( text ), true );
+	});
+
+} );
+
+Reveal.initialize({
+	dependencies: [
+		{ src: '../plugin/markdown/marked.js' },
+		{ src: '../plugin/markdown/markdown.js' },
+	],
+	markdown: {
+		smartypants: true
+	}
+});

+ 1 - 1
test/test-markdown.html

@@ -13,7 +13,7 @@
 	<body style="overflow: auto;">
 
 		<div id="qunit"></div>
-  		<div id="qunit-fixture"></div>
+		<div id="qunit-fixture"></div>
 
 		<div class="reveal" style="display: none;">