Explorar o código

merged dev branch

Yves Delley %!s(int64=9) %!d(string=hai) anos
pai
achega
9bc5b81292
Modificáronse 53 ficheiros con 4039 adicións e 1855 borrados
  1. 3 1
      .gitignore
  2. 1 1
      .travis.yml
  3. 20 0
      CONTRIBUTING.md
  4. 13 3
      Gruntfile.js
  5. 44 35
      README.md
  6. 193 167
      css/print/paper.css
  7. 18 42
      css/print/pdf.css
  8. 148 274
      css/reveal.bare.css
  9. 161 288
      css/reveal.css
  10. 0 6
      css/reveal.min.css
  11. 159 16
      css/theme/beige.css
  12. 163 19
      css/theme/blood.css
  13. 159 16
      css/theme/default.css
  14. 159 16
      css/theme/moon.css
  15. 160 16
      css/theme/night.css
  16. 159 15
      css/theme/serif.css
  17. 160 16
      css/theme/simple.css
  18. 161 17
      css/theme/sky.css
  19. 159 16
      css/theme/solarized.css
  20. 4 4
      css/theme/source/blood.scss
  21. 1 1
      css/theme/source/serif.scss
  22. 1 1
      css/theme/source/sky.scss
  23. 1 1
      css/theme/template/settings.scss
  24. 181 12
      css/theme/template/theme.scss
  25. 59 33
      index.html
  26. 489 170
      js/reveal.js
  27. 0 7
      js/reveal.min.js
  28. 74 71
      lib/css/zenburn.css
  29. 3 3
      package.json
  30. 1 3
      plugin/highlight/highlight.js
  31. 4 2
      plugin/leap/leap.js
  32. 2 2
      plugin/markdown/example.html
  33. 8 7
      plugin/markdown/markdown.js
  34. 49 46
      plugin/notes-server/client.js
  35. 28 21
      plugin/notes-server/index.js
  36. 351 97
      plugin/notes-server/notes.html
  37. 319 182
      plugin/notes/notes.html
  38. 72 33
      plugin/notes/notes.js
  39. 0 39
      plugin/postmessage/example.html
  40. 0 42
      plugin/postmessage/postmessage.js
  41. 24 20
      plugin/print-pdf/print-pdf.js
  42. 64 56
      plugin/zoom-js/zoom.js
  43. 2 2
      test/examples/barebones.html
  44. 2 2
      test/examples/embedded-media.html
  45. 2 2
      test/examples/math.html
  46. 2 2
      test/examples/slide-backgrounds.html
  47. 6 6
      test/test-markdown-element-attributes.html
  48. 7 7
      test/test-markdown-slide-attributes.html
  49. 4 4
      test/test-markdown.html
  50. 83 0
      test/test-pdf.html
  51. 15 0
      test/test-pdf.js
  52. 5 4
      test/test.html
  53. 136 9
      test/test.js

+ 3 - 1
.gitignore

@@ -3,4 +3,6 @@
 log/*.log
 tmp/**
 node_modules/
-.sass-cache
+.sass-cache
+css/reveal.min.css
+js/reveal.min.js

+ 1 - 1
.travis.yml

@@ -1,5 +1,5 @@
 language: node_js
 node_js:
-  - 0.8
+  - 0.10
 before_script:
   - npm install -g grunt-cli

+ 20 - 0
CONTRIBUTING.md

@@ -0,0 +1,20 @@
+## Contributing
+
+Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**.
+
+
+### Personal Support
+If you have personal support or setup questions the best place to ask those are  [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
+
+
+### Bug Reports
+When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested.
+
+
+### Pull Requests
+- Should follow the coding style of the file you work in, most importantly:
+  - Tabs to indent
+  - Single-quoted strings
+- Should be made towards the **dev branch**
+- Should be submitted from a feature/topic branch (not your master)
+- Should not include the minified **reveal.min.js** or **reveal.min.css** files

+ 13 - 3
Gruntfile.js

@@ -70,7 +70,9 @@ module.exports = function(grunt) {
 					head: false,
 					module: false,
 					console: false,
-					unescape: false
+					unescape: false,
+					define: false,
+					exports: false
 				}
 			},
 			files: [ 'Gruntfile.js', 'js/reveal.js' ]
@@ -96,7 +98,9 @@ module.exports = function(grunt) {
 			server: {
 				options: {
 					port: port,
-					base: '.'
+					base: '.',
+                    livereload: true,
+                    open: true
 				}
 			}
 		},
@@ -113,6 +117,9 @@ module.exports = function(grunt) {
 		},
 
 		watch: {
+            options: {
+                livereload: true
+            },
 			main: {
 				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
 				tasks: 'default'
@@ -124,7 +131,10 @@ module.exports = function(grunt) {
 			css: {
 				files: [ 'css/reveal.bare.css' ],
 				tasks: 'css'
-			}
+			},
+            html: {
+                files: [ 'index.html']
+            }
 		}
 
 	});

+ 44 - 35
README.md

@@ -13,7 +13,7 @@ reveal.js comes with a broad range of features including [nested slides](https:/
 
 ## Online Editor
 
-Presentations are written using HTML or markdown but there's also an online editor for those of you who prefer a graphical interface. Give it a try at [http://slid.es](http://slid.es).
+Presentations are written using HTML or markdown but there's also an online editor for those of you who prefer a graphical interface. Give it a try at [http://slides.com](http://slides.com).
 
 
 ## Instructions
@@ -59,8 +59,8 @@ When used locally, this feature requires that reveal.js [runs from a local web s
 ```html
 <section data-markdown="example.md"  
          data-separator="^\n\n\n"  
-         data-vertical="^\n\n"  
-         data-notes="^Note:"  
+         data-separator-vertical="^\n\n"  
+         data-separator-notes="^Note:"  
          data-charset="iso-8859-15">
 </section>
 ```
@@ -136,6 +136,10 @@ Reveal.initialize({
 	// i.e. contained within a limited portion of the screen
 	embedded: false,
 
+	// Flags if we should show a help overlay when the questionmark
+	// key is pressed
+	help: true,
+
 	// Number of milliseconds between automatically proceeding to the
 	// next slide, disabled when set to 0, this value can be overwritten
 	// by using a data-autoslide attribute on your slides
@@ -154,13 +158,13 @@ Reveal.initialize({
 	previewLinks: false,
 
 	// Transition style
-	transition: 'default', // default/cube/page/concave/zoom/linear/fade/none
+	transition: 'default', // none/fade/slide/convex/concave/zoom
 
 	// Transition speed
 	transitionSpeed: 'default', // default/fast/slow
 
 	// Transition style for full page slide backgrounds
-	backgroundTransition: 'default', // default/none/slide/concave/convex/zoom
+	backgroundTransition: 'default', // none/fade/slide/convex/concave/zoom
 
 	// Number of slides away from the current that are visible
 	viewDistance: 3,
@@ -175,8 +179,6 @@ Reveal.initialize({
 });
 ```
 
-Note that the new default vertical centering option will break compatibility with slides that were using transitions with backgrounds (`cube` and `page`). To restore the previous behavior, set `center` to `false`.
-
 
 The configuration can be updated after initialization using the ```configure``` method:
 
@@ -266,15 +268,20 @@ Reveal.configure({
   autoSlide: 5000
 });
 ```
+When this is turned on a control element will appear that enables users to pause and resume auto-sliding. Alternatively, sliding can be paused or resumed by pressing »a« on the keyboard. Sliding is paused automatically as soon as the user starts navigating. You can disable these controls by specifying ```autoSlideStoppable: false``` in your reveal.js config.
 
-When this is turned on a control element will appear that enables users to pause and resume auto-sliding. Sliding is also paused automatically as soon as the user starts navigating. You can disable these controls by specifying ```autoSlideStoppable: false``` in your reveal.js config.
-
-You can also override the slide duration for individual slides by using the ```data-autoslide``` attribute on individual sections:
+You can also override the slide duration for individual slides and fragments by using the ```data-autoslide``` attribute:
 
 ```html
-<section data-autoslide="10000">This will remain on screen for 10 seconds</section>
+<section data-autoslide="2000">
+	<p>After 2 seconds the first fragment will be shown.</p>
+	<p class="fragment" data-autoslide="10000">After 10 seconds the next fragment will be shown.</p>
+	<p class="fragment">Now, the fragment is displayed for 2 seconds before the next slide is shown.</p>
+</section>
 ```
 
+Whenever the auto-slide mode is resumed or paused the ```autoslideresumed``` and ```autoslidepaused``` events are fired.
+
 
 ### Keyboard Bindings
 
@@ -290,6 +297,23 @@ Reveal.configure({
 });
 ```
 
+### Lazy Loading
+
+When working on presentation with a lot of media or iframe content it's important to load lazily. Lazy loading means that reveal.js will only load content for the few slides nearest to the current slide. The number of slides that are preloaded is determined by the `viewDistance` configuration option.
+
+To enable lazy loading all you need to do is change your "src" attributes to "data-src" as shown below. This is supported for image, video, audio and iframe elements.
+
+```html
+<section>
+  <img data-src="image.png">
+  <iframe data-src="http://slides.com">
+  <video>
+    <source data-src="video.webm" type="video/webm" />
+    <source data-src="video.mp4" type="video/mp4" />
+  </video>
+</section>
+```
+
 
 ### API
 
@@ -308,6 +332,7 @@ Reveal.prevFragment();
 Reveal.nextFragment();
 Reveal.toggleOverview();
 Reveal.togglePause();
+Reveal.toggleAutoSlide();
 
 // Retrieves the previous and current slide elements
 Reveal.getPreviousSlide();
@@ -320,6 +345,7 @@ Reveal.isFirstSlide();
 Reveal.isLastSlide();
 Reveal.isOverview();
 Reveal.isPaused();
+Reveal.isAutoSliding();
 ```
 
 ### Ready Event
@@ -390,7 +416,7 @@ Reveal.initialize({
 	parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px" - currently only pixels are supported (don't use % or auto)
 
 	// This slide transition gives best results:
-	transition: linear
+	transition: 'slide'
 
 });
 ```
@@ -563,7 +589,7 @@ Limitations:
 Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome).
 Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948.
 
-1. Open your presentation with [css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css) included on the page. The default index HTML lets you add *print-pdf* anywhere in the query to include the stylesheet, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf).
+1. Open your presentation with `print-pdf` included anywhere in the query string. This triggers the default index HTML to load the PDF print stylesheet ([css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css)). You can test this with [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf).
 2. Open the in-browser print dialog (CMD+P).
 3. Change the **Destination** setting to **Save as PDF**.
 4. Change the **Layout** to **Landscape**.
@@ -614,7 +640,7 @@ When used locally, this feature requires that reveal.js [runs from a local web s
 If you're using the external Markdown plugin, you can add notes with the help of a special delimiter:
 
 ```html
-<section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n" data-notes="^Note:"></section>
+<section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
 
 # Title
 ## Sub-title
@@ -683,7 +709,7 @@ Reveal.initialize({
 
 	// Don't forget to add the dependencies
 	dependencies: [
-		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js', async: true },
 		{ src: 'plugin/multiplex/master.js', async: true },
 
 		// and if you want speaker notes
@@ -711,7 +737,7 @@ Reveal.initialize({
 
 	// Don't forget to add the dependencies
 	dependencies: [
-		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js', async: true },
 		{ src: 'plugin/multiplex/client.js', async: true }
 
 		// other dependencies...
@@ -749,7 +775,7 @@ Reveal.initialize({
 
 	// Don't forget to add the dependencies
 	dependencies: [
-		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js', async: true },
 		{ src: 'plugin/multiplex/client.js', async: true }
 
 		// other dependencies...
@@ -772,7 +798,7 @@ Reveal.initialize({
 
 	// Don't forget to add the dependencies
 	dependencies: [
-		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js', async: true },
+		{ src: '//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js', async: true },
 		{ src: 'plugin/multiplex/master.js', async: true },
 		{ src: 'plugin/multiplex/client.js', async: true }
 
@@ -909,23 +935,6 @@ Some reveal.js features, like external markdown and speaker notes, require that
 - **lib/** All other third party assets (JavaScript, CSS, fonts)
 
 
-### Contributing
-
-Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. If you are reporting a bug make sure to include information about which browser and operating system you are using as well as the necessary steps to reproduce the issue.
-
-If you have personal support questions use [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
-
-
-#### Pull requests
-
-- Should follow the coding style of the file you work in, most importantly:
-  - Tabs to indent
-  - Single-quoted strings
-- Should be made towards the **dev branch**
-- Should be submitted from a feature/topic branch (not your master)
-- Should not include the minified **reveal.min.js** file
-
-
 ## License
 
 MIT licensed

+ 193 - 167
css/print/paper.css

@@ -6,171 +6,197 @@
    manipulate this file as you see fit. */
 
 
-/* SECTION 1: Set default width, margin, float, and
-   background. This prevents elements from extending
-   beyond the edge of the printed page, and prevents
-   unnecessary background images from printing */
-body {
-	background: #fff;
-	font-size: 13pt;
-	width: auto;
-	height: auto;
-	border: 0;
-	margin: 0 5%;
-	padding: 0;
-	float: none !important;
-	overflow: visible;
-}
-html {
-	background: #fff;
-	width: auto;
-	height: auto;
-	overflow: visible;
-}
-
-/* SECTION 2: Remove any elements not needed in print.
-   This would include navigation, ads, sidebars, etc. */
-.nestedarrow,
-.controls,
-.reveal .progress,
-.reveal.overview,
-.fork-reveal,
-.share-reveal,
-.state-background {
-	display: none !important;
-}
-
-/* SECTION 3: Set body font face, size, and color.
-   Consider using a serif font for readability. */
-body, p, td, li, div, a {
-	font-size: 16pt!important;
-	font-family: Georgia, "Times New Roman", Times, serif !important;
-	color: #000;
-}
-
-/* SECTION 4: Set heading font face, sizes, and color.
-   Differentiate your headings from your body text.
-   Perhaps use a large sans-serif for distinction. */
-h1,h2,h3,h4,h5,h6 {
-	color: #000!important;
-	height: auto;
-	line-height: normal;
-	font-family: Georgia, "Times New Roman", Times, serif !important;
-	text-shadow: 0 0 0 #000 !important;
-	text-align: left;
-	letter-spacing: normal;
-}
-/* Need to reduce the size of the fonts for printing */
-h1 { font-size: 26pt !important;  }
-h2 { font-size: 22pt !important; }
-h3 { font-size: 20pt !important; }
-h4 { font-size: 20pt !important; font-variant: small-caps; }
-h5 { font-size: 19pt !important; }
-h6 { font-size: 18pt !important; font-style: italic; }
-
-/* SECTION 5: Make hyperlinks more usable.
-   Ensure links are underlined, and consider appending
-   the URL to the end of the link for usability. */
-a:link,
-a:visited {
-	color: #000 !important;
-	font-weight: bold;
-	text-decoration: underline;
-}
-/*
-.reveal a:link:after,
-.reveal a:visited:after {
-	content: " (" attr(href) ") ";
-	color: #222 !important;
-	font-size: 90%;
-}
-*/
-
-
-/* SECTION 6: more reveal.js specific additions by @skypanther */
-ul, ol, div, p {
-	visibility: visible;
-	position: static;
-	width: auto;
-	height: auto;
-	display: block;
-	overflow: visible;
-	margin: auto;
-	text-align: left !important;
-}
-.reveal .slides {
-	position: static;
-	width: auto;
-	height: auto;
-
-	left: auto;
-	top: auto;
-	margin-left: auto;
-	margin-top: auto;
-	padding: auto;
-
-	overflow: visible;
-	display: block;
-
-	text-align: center;
-	-webkit-perspective: none;
-	   -moz-perspective: none;
-	    -ms-perspective: none;
-	        perspective: none;
-
-	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
-	   -moz-perspective-origin: 50% 50%;
-	    -ms-perspective-origin: 50% 50%;
-	        perspective-origin: 50% 50%;
-}
-.reveal .slides>section,
-.reveal .slides>section>section {
-
-	visibility: visible !important;
-	position: static !important;
-	width: 90% !important;
-	height: auto !important;
-	display: block !important;
-	overflow: visible !important;
-
-	left: 0% !important;
-	top: 0% !important;
-	margin-left: 0px !important;
-	margin-top: 0px !important;
-	padding: 20px 0px !important;
-
-	opacity: 1 !important;
-
-	-webkit-transform-style: flat !important;
-	   -moz-transform-style: flat !important;
-	    -ms-transform-style: flat !important;
-	        transform-style: flat !important;
-
-	-webkit-transform: none !important;
-	   -moz-transform: none !important;
-	    -ms-transform: none !important;
-	        transform: none !important;
-}
-.reveal section {
-	page-break-after: always !important;
-	display: block !important;
-}
-.reveal section .fragment {
-	opacity: 1 !important;
-	visibility: visible !important;
-
-	-webkit-transform: none !important;
-	   -moz-transform: none !important;
-	    -ms-transform: none !important;
-	        transform: none !important;
-}
-.reveal section:last-of-type {
-	page-break-after: avoid !important;
-}
-.reveal section img {
-	display: block;
-	margin: 15px 0px;
-	background: rgba(255,255,255,1);
-	border: 1px solid #666;
-	box-shadow: none;
+@media print {
+
+	/* SECTION 1: Set default width, margin, float, and
+	   background. This prevents elements from extending
+	   beyond the edge of the printed page, and prevents
+	   unnecessary background images from printing */
+	html {
+		background: #fff;
+		width: auto;
+		height: auto;
+		overflow: visible;
+	}
+	body {
+		background: #fff;
+		font-size: 20pt;
+		width: auto;
+		height: auto;
+		border: 0;
+		margin: 0 5%;
+		padding: 0;
+		overflow: visible;
+		float: none !important;
+	}
+
+	/* SECTION 2: Remove any elements not needed in print.
+	   This would include navigation, ads, sidebars, etc. */
+	.nestedarrow,
+	.controls,
+	.fork-reveal,
+	.share-reveal,
+	.state-background,
+	.reveal .progress,
+	.reveal .backgrounds {
+		display: none !important;
+	}
+
+	/* SECTION 3: Set body font face, size, and color.
+	   Consider using a serif font for readability. */
+	body, p, td, li, div {
+		font-size: 20pt!important;
+		font-family: Georgia, "Times New Roman", Times, serif !important;
+		color: #000;
+	}
+
+	/* SECTION 4: Set heading font face, sizes, and color.
+	   Differentiate your headings from your body text.
+	   Perhaps use a large sans-serif for distinction. */
+	h1,h2,h3,h4,h5,h6 {
+		color: #000!important;
+		height: auto;
+		line-height: normal;
+		font-family: Georgia, "Times New Roman", Times, serif !important;
+		text-shadow: 0 0 0 #000 !important;
+		text-align: left;
+		letter-spacing: normal;
+	}
+	/* Need to reduce the size of the fonts for printing */
+	h1 { font-size: 28pt !important;  }
+	h2 { font-size: 24pt !important; }
+	h3 { font-size: 22pt !important; }
+	h4 { font-size: 22pt !important; font-variant: small-caps; }
+	h5 { font-size: 21pt !important; }
+	h6 { font-size: 20pt !important; font-style: italic; }
+
+	/* SECTION 5: Make hyperlinks more usable.
+	   Ensure links are underlined, and consider appending
+	   the URL to the end of the link for usability. */
+	a:link,
+	a:visited {
+		color: #000 !important;
+		font-weight: bold;
+		text-decoration: underline;
+	}
+	/*
+	.reveal a:link:after,
+	.reveal a:visited:after {
+		content: " (" attr(href) ") ";
+		color: #222 !important;
+		font-size: 90%;
+	}
+	*/
+
+
+	/* SECTION 6: more reveal.js specific additions by @skypanther */
+	ul, ol, div, p {
+		visibility: visible;
+		position: static;
+		width: auto;
+		height: auto;
+		display: block;
+		overflow: visible;
+		margin: 0;
+		text-align: left !important;
+	}
+	.reveal pre,
+	.reveal table {
+		margin-left: 0;
+		margin-right: 0;
+	}
+	.reveal pre code {
+		padding: 20px;
+		border: 1px solid #ddd;
+	}
+	.reveal blockquote {
+		margin: 20px 0;
+	}
+	.reveal .slides {
+		position: static !important;
+		width: auto !important;
+		height: auto !important;
+
+		left: 0 !important;
+		top: 0 !important;
+		margin-left: 0 !important;
+		margin-top: 0 !important;
+		padding: 0 !important;
+		zoom: 1 !important;
+
+		overflow: visible !important;
+		display: block !important;
+
+		text-align: left !important;
+		-webkit-perspective: none;
+		   -moz-perspective: none;
+		    -ms-perspective: none;
+		        perspective: none;
+
+		-webkit-perspective-origin: 50% 50%;
+		   -moz-perspective-origin: 50% 50%;
+		    -ms-perspective-origin: 50% 50%;
+		        perspective-origin: 50% 50%;
+	}
+	.reveal .slides section {
+		visibility: visible !important;
+		position: static !important;
+		width: 100% !important;
+		height: auto !important;
+		display: block !important;
+		overflow: visible !important;
+
+		left: 0 !important;
+		top: 0 !important;
+		margin-left: 0 !important;
+		margin-top: 0 !important;
+		padding: 60px 20px !important;
+		z-index: auto !important;
+
+		opacity: 1 !important;
+
+		page-break-after: always !important;
+
+		-webkit-transform-style: flat !important;
+		   -moz-transform-style: flat !important;
+		    -ms-transform-style: flat !important;
+		        transform-style: flat !important;
+
+		-webkit-transform: none !important;
+		   -moz-transform: none !important;
+		    -ms-transform: none !important;
+		        transform: none !important;
+
+		-webkit-transition: none !important;
+		   -moz-transition: none !important;
+		    -ms-transition: none !important;
+		        transition: none !important;
+	}
+	.reveal .slides section.stack {
+		padding: 0 !important;
+	}
+	.reveal section:last-of-type {
+		page-break-after: avoid !important;
+	}
+	.reveal section .fragment {
+		opacity: 1 !important;
+		visibility: visible !important;
+
+		-webkit-transform: none !important;
+		   -moz-transform: none !important;
+		    -ms-transform: none !important;
+		        transform: none !important;
+	}
+	.reveal section img {
+		display: block;
+		margin: 15px 0px;
+		background: rgba(255,255,255,1);
+		border: 1px solid #666;
+		box-shadow: none;
+	}
+
+	.reveal section small {
+		font-size: 0.8em;
+	}
+
 }

+ 18 - 42
css/print/pdf.css

@@ -16,9 +16,6 @@
 }
 
 body {
-	font-size: 18pt;
-	width: 297mm;
-	height: 229mm;
 	margin: 0 auto !important;
 	border: 0;
 	padding: 0;
@@ -32,16 +29,13 @@ html {
 	overflow: visible;
 }
 
-@page {
-	size: letter landscape;
-	margin: 0;
-}
-
 /* SECTION 2: Remove any elements not needed in print.
    This would include navigation, ads, sidebars, etc. */
 .nestedarrow,
-.controls,
+.reveal .controls,
 .reveal .progress,
+.reveal .slide-number,
+.reveal .playback,
 .reveal.overview,
 .fork-reveal,
 .share-reveal,
@@ -52,7 +46,7 @@ html {
 /* SECTION 3: Set body font face, size, and color.
    Consider using a serif font for readability. */
 body, p, td, li, div {
-	font-size: 18pt;
+
 }
 
 /* SECTION 4: Set heading font face, sizes, and color.
@@ -73,7 +67,7 @@ a:visited {
 
 .reveal pre code {
 	overflow: hidden !important;
-	font-family: monospace !important;
+	font-family: Courier, 'Courier New', monospace !important;
 }
 
 
@@ -105,8 +99,6 @@ ul, ol, div, p {
 	overflow: visible;
 	display: block;
 
-	text-align: center;
-
 	-webkit-perspective: none;
 	   -moz-perspective: none;
 	    -ms-perspective: none;
@@ -118,22 +110,17 @@ ul, ol, div, p {
 	        perspective-origin: 50% 50%;
 }
 .reveal .slides section {
-
 	page-break-after: always !important;
 
 	visibility: visible !important;
 	position: relative !important;
-	width: 100% !important;
-	height: 229mm !important;
-	min-height: 229mm !important;
 	display: block !important;
-	overflow: hidden !important;
+	position: relative !important;
 
-	left: 0 !important;
-	top: 0 !important;
 	margin: 0 !important;
-	padding: 2cm 2cm 0 2cm !important;
+	padding: 0 !important;
 	box-sizing: border-box !important;
+	min-height: 1px;
 
 	opacity: 1 !important;
 
@@ -154,37 +141,26 @@ ul, ol, div, p {
 	height: auto !important;
 	min-height: auto !important;
 }
-.reveal .absolute-element {
-	margin-left: 2.2cm;
-	margin-top: 1.8cm;
+.reveal img {
+	box-shadow: none;
 }
-.reveal section .fragment {
-	opacity: 1 !important;
-	visibility: visible !important;
-
-	-webkit-transform: none !important;
-	   -moz-transform: none !important;
-	    -ms-transform: none !important;
-	        transform: none !important;
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
 }
+
+/* Slide backgrounds are placed inside of their slide when exporting to PDF */
 .reveal section .slide-background {
+	display: block !important;
 	position: absolute;
 	top: 0;
 	left: 0;
 	width: 100%;
 	z-index: 0;
 }
+/* All elements should be above the slide-background */
 .reveal section>* {
 	position: relative;
 	z-index: 1;
 }
-.reveal img {
-	box-shadow: none;
-}
-.reveal .roll {
-	overflow: visible;
-	line-height: 1em;
-}
-.reveal small a {
-	font-size: 16pt !important;
-}
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 148 - 274
css/reveal.bare.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 161 - 288
css/reveal.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 6
css/reveal.min.css


+ 159 - 16
css/theme/beige.css

@@ -1,16 +1,15 @@
-@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 /**
  * Beige theme for reveal.js.
  *
  * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
  */
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 @font-face {
   font-family: 'League Gothic';
   src: url("../../lib/font/league_gothic-webfont.eot");
   src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
   font-weight: normal;
   font-style: normal; }
-
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -36,6 +35,11 @@ body {
   background: rgba(79, 64, 28, 0.99);
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -48,27 +52,168 @@ body {
   margin: 0 0 20px 0;
   color: #333333;
   font-family: "League Gothic", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: uppercase;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #8b743d;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #c0a86e;
   text-shadow: none;
   border: none; }
@@ -84,12 +229,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #333333;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -137,8 +282,6 @@ body {
   background: #8b743d;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 163 - 19
css/theme/blood.css

@@ -1,4 +1,3 @@
-@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
 /**
  * Blood theme for reveal.js
  * Author: Walther http://github.com/Walther
@@ -10,6 +9,7 @@
  * For other themes, change $codeBackground accordingly.
  *
  */
+@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -35,6 +35,11 @@ body {
   background: #aa2233;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -47,27 +52,168 @@ body {
   margin: 0 0 20px 0;
   color: #eeeeee;
   font-family: Ubuntu, "sans-serif";
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: uppercase;
-  text-shadow: 2px 2px 2px #222222; }
+  text-shadow: 2px 2px 2px #222222;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #aa2233;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #dd5566;
   text-shadow: none;
   border: none; }
@@ -83,12 +229,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #eeeeee;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -136,8 +282,6 @@ body {
   background: #aa2233;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************
@@ -158,12 +302,12 @@ body {
 .reveal h6 {
   font-weight: 700; }
 
-.reveal a:not(.image),
-.reveal a:not(.image):hover {
+.reveal a,
+.reveal a:hover {
   text-shadow: 2px 2px 2px #000; }
 
-.reveal small a:not(.image),
-.reveal small a:not(.image):hover {
+.reveal small a,
+.reveal small a:hover {
   text-shadow: 1px 1px 1px #000; }
 
 .reveal p code {

+ 159 - 16
css/theme/default.css

@@ -1,16 +1,15 @@
-@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 /**
  * Default theme for reveal.js.
  *
  * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
  */
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 @font-face {
   font-family: 'League Gothic';
   src: url("../../lib/font/league_gothic-webfont.eot");
   src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
   font-weight: normal;
   font-style: normal; }
-
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -36,6 +35,11 @@ body {
   background: #ff5e99;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -48,27 +52,168 @@ body {
   margin: 0 0 20px 0;
   color: #eeeeee;
   font-family: "League Gothic", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: uppercase;
-  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #13daec;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #71e9f4;
   text-shadow: none;
   border: none; }
@@ -84,12 +229,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #eeeeee;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -137,8 +282,6 @@ body {
   background: #13daec;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 159 - 16
css/theme/moon.css

@@ -1,15 +1,14 @@
-@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 /**
  * Solarized Dark theme for reveal.js.
  * Author: Achim Staebler
  */
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 @font-face {
   font-family: 'League Gothic';
   src: url("../../lib/font/league_gothic-webfont.eot");
   src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
   font-weight: normal;
   font-style: normal; }
-
 /**
  * Solarized colors by Ethan Schoonover
  */
@@ -36,6 +35,11 @@ body {
   background: #d33682;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -48,27 +52,168 @@ body {
   margin: 0 0 20px 0;
   color: #eee8d5;
   font-family: "League Gothic", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: uppercase;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #268bd2;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #78b9e6;
   text-shadow: none;
   border: none; }
@@ -84,12 +229,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #93a1a1;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -137,8 +282,6 @@ body {
   background: #268bd2;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 160 - 16
css/theme/night.css

@@ -1,10 +1,10 @@
-@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
-@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
 /**
  * Black theme for reveal.js.
  *
  * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
  */
+@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -24,6 +24,11 @@ body {
   background: #e7ad52;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -36,27 +41,168 @@ body {
   margin: 0 0 20px 0;
   color: #eeeeee;
   font-family: "Montserrat", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: -0.03em;
   text-transform: none;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #e7ad52;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #f3d7ac;
   text-shadow: none;
   border: none; }
@@ -72,12 +218,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #eeeeee;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -125,8 +271,6 @@ body {
   background: #e7ad52;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 159 - 15
css/theme/serif.css

@@ -4,7 +4,7 @@
  *
  * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
  */
-.reveal a:not(.image) {
+.reveal a {
   line-height: 1.3em; }
 
 /*********************************************
@@ -26,6 +26,11 @@ body {
   background: #26351c;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -38,27 +43,168 @@ body {
   margin: 0 0 20px 0;
   color: #383d3d;
   font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: none;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #51483d;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #8b7c69;
   text-shadow: none;
   border: none; }
@@ -74,12 +220,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid black;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -127,8 +273,6 @@ body {
   background: #51483d;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 160 - 16
css/theme/simple.css

@@ -1,5 +1,3 @@
-@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);
 /**
  * A simple theme for reveal.js presentations, similar
  * to the default theme. The accent color is darkblue.
@@ -7,6 +5,8 @@
  * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
  * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
  */
+@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);
 /*********************************************
  * GLOBAL STYLES
  *********************************************/
@@ -26,6 +26,11 @@ body {
   background: rgba(0, 0, 0, 0.99);
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -38,27 +43,168 @@ body {
   margin: 0 0 20px 0;
   color: black;
   font-family: "News Cycle", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: none;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: darkblue;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #0000f1;
   text-shadow: none;
   border: none; }
@@ -74,12 +220,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid black;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -127,8 +273,6 @@ body {
   background: darkblue;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 161 - 17
css/theme/sky.css

@@ -1,11 +1,11 @@
-@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
-@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
 /**
  * Sky theme for reveal.js.
  *
  * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
  */
-.reveal a:not(.image) {
+@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+.reveal a {
   line-height: 1.3em; }
 
 /*********************************************
@@ -33,6 +33,11 @@ body {
   background: #134674;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -45,27 +50,168 @@ body {
   margin: 0 0 20px 0;
   color: #333333;
   font-family: "Quicksand", sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: -0.08em;
   text-transform: uppercase;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #3b759e;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #74a7cb;
   text-shadow: none;
   border: none; }
@@ -81,12 +227,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #333333;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -134,8 +280,6 @@ body {
   background: #3b759e;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 159 - 16
css/theme/solarized.css

@@ -1,15 +1,14 @@
-@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 /**
  * Solarized Light theme for reveal.js.
  * Author: Achim Staebler
  */
+@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
 @font-face {
   font-family: 'League Gothic';
   src: url("../../lib/font/league_gothic-webfont.eot");
   src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
   font-weight: normal;
   font-style: normal; }
-
 /**
  * Solarized colors by Ethan Schoonover
  */
@@ -36,6 +35,11 @@ body {
   background: #d33682;
   text-shadow: none; }
 
+.reveal .slides > section,
+.reveal .slides > section > section {
+  line-height: 1.2em;
+  font-weight: inherit; }
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -48,27 +52,168 @@ body {
   margin: 0 0 20px 0;
   color: #586e75;
   font-family: "League Gothic", Impact, sans-serif;
-  line-height: 0.9em;
+  line-height: 1em;
   letter-spacing: 0.02em;
   text-transform: uppercase;
-  text-shadow: none; }
+  text-shadow: none;
+  word-wrap: break-word; }
+
+.reveal h1 {
+  font-size: 3.77em; }
+
+.reveal h2 {
+  font-size: 2.11em; }
+
+.reveal h3 {
+  font-size: 1.55em; }
+
+.reveal h4 {
+  font-size: 1em; }
 
 .reveal h1 {
   text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
 
 /*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+  margin-bottom: 10px;
+  line-height: 1.2em; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+  max-width: 95%;
+  max-height: 95%; }
+
+.reveal strong,
+.reveal b {
+  font-weight: bold; }
+
+.reveal em {
+  font-style: italic; }
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+  display: inline-block;
+  text-align: left;
+  margin: 0 0 0 1em; }
+
+.reveal ol {
+  list-style-type: decimal; }
+
+.reveal ul {
+  list-style-type: disc; }
+
+.reveal ul ul {
+  list-style-type: square; }
+
+.reveal ul ul ul {
+  list-style-type: circle; }
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+  display: block;
+  margin-left: 40px; }
+
+.reveal dt {
+  font-weight: bold; }
+
+.reveal dd {
+  margin-left: 40px; }
+
+.reveal q,
+.reveal blockquote {
+  quotes: none; }
+
+.reveal blockquote {
+  display: block;
+  position: relative;
+  width: 70%;
+  margin: 5px auto;
+  padding: 5px;
+  font-style: italic;
+  background: rgba(255, 255, 255, 0.05);
+  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child,
+.reveal blockquote p:last-child {
+  display: inline-block; }
+
+.reveal q {
+  font-style: italic; }
+
+.reveal pre {
+  display: block;
+  position: relative;
+  width: 90%;
+  margin: 15px auto;
+  text-align: left;
+  font-size: 0.55em;
+  font-family: monospace;
+  line-height: 1.2em;
+  word-wrap: break-word;
+  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+  font-family: monospace; }
+
+.reveal pre code {
+  display: block;
+  padding: 5px;
+  overflow: auto;
+  max-height: 400px;
+  word-wrap: normal;
+  background: #3F3F3F;
+  color: #DCDCDC; }
+
+.reveal table {
+  margin: auto;
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+.reveal table th {
+  font-weight: bold; }
+
+.reveal table th,
+.reveal table td {
+  text-align: left;
+  padding: 0.2em 0.5em 0.2em 0.5em;
+  border-bottom: 1px solid; }
+
+.reveal table tr:last-child td {
+  border-bottom: none; }
+
+.reveal sup {
+  vertical-align: super; }
+
+.reveal sub {
+  vertical-align: sub; }
+
+.reveal small {
+  display: inline-block;
+  font-size: 0.6em;
+  line-height: 1.2em;
+  vertical-align: top; }
+
+.reveal small * {
+  vertical-align: top; }
+
+/*********************************************
  * LINKS
  *********************************************/
-.reveal a:not(.image) {
+.reveal a {
   color: #268bd2;
   text-decoration: none;
   -webkit-transition: color .15s ease;
   -moz-transition: color .15s ease;
-  -ms-transition: color .15s ease;
-  -o-transition: color .15s ease;
   transition: color .15s ease; }
 
-.reveal a:not(.image):hover {
+.reveal a:hover {
   color: #78b9e6;
   text-shadow: none;
   border: none; }
@@ -84,12 +229,12 @@ body {
   margin: 15px 0px;
   background: rgba(255, 255, 255, 0.12);
   border: 4px solid #657b83;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-  -webkit-transition: all .2s linear;
-  -moz-transition: all .2s linear;
-  -ms-transition: all .2s linear;
-  -o-transition: all .2s linear;
-  transition: all .2s linear; }
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
+
+.reveal a img {
+  -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);
@@ -137,8 +282,6 @@ body {
   background: #268bd2;
   -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
   transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
 
 /*********************************************

+ 4 - 4
css/theme/source/blood.scss

@@ -70,13 +70,13 @@ $selectionColor: #fff;
     font-weight: 700;
 }
 
-.reveal a:not(.image),
-.reveal a:not(.image):hover {
+.reveal a,
+.reveal a:hover {
     text-shadow: 2px 2px 2px #000;
 }
 
-.reveal small a:not(.image),
-.reveal small a:not(.image):hover {
+.reveal small a,
+.reveal small a:hover {
     text-shadow: 1px 1px 1px #000;
 }
 

+ 1 - 1
css/theme/source/serif.scss

@@ -25,7 +25,7 @@ $linkColor: #51483D;
 $linkColorHover: lighten( $linkColor, 20% );
 $selectionBackgroundColor: #26351C;
 
-.reveal a:not(.image) {
+.reveal a {
   line-height: 1.3em;
 }
 

+ 1 - 1
css/theme/source/sky.scss

@@ -30,7 +30,7 @@ $linkColorHover: lighten( $linkColor, 20% );
 $selectionBackgroundColor: #134674;
 
 // Fix links so they are not cut off
-.reveal a:not(.image) {
+.reveal a {
 	line-height: 1.3em;
 }
 

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

@@ -13,7 +13,7 @@ $mainColor: #eee;
 $headingMargin: 0 0 20px 0;
 $headingFont: 'League Gothic', Impact, sans-serif;
 $headingColor: #eee;
-$headingLineHeight: 0.9em;
+$headingLineHeight: 1em;
 $headingLetterSpacing: 0.02em;
 $headingTextTransform: uppercase;
 $headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);

+ 181 - 12
css/theme/template/theme.scss

@@ -23,6 +23,12 @@ body {
 	text-shadow: none;
 }
 
+.reveal .slides>section,
+.reveal .slides>section>section {
+	line-height: 1.2em;
+	font-weight: inherit;
+}
+
 /*********************************************
  * HEADERS
  *********************************************/
@@ -42,28 +48,193 @@ body {
 
 	text-transform: $headingTextTransform;
 	text-shadow: $headingTextShadow;
+
+	word-wrap: break-word;
 }
 
+.reveal h1 { font-size: 3.77em;	}
+.reveal h2 { font-size: 2.11em;	}
+.reveal h3 { font-size: 1.55em;	}
+.reveal h4 { font-size: 1em;	}
+
 .reveal h1 {
 	text-shadow: $heading1TextShadow;
 }
 
 
 /*********************************************
+ * OTHER
+ *********************************************/
+
+.reveal p {
+	margin-bottom: 10px;
+	line-height: 1.2em;
+}
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img,
+.reveal video,
+.reveal iframe {
+	max-width: 95%;
+	max-height: 95%;
+}
+.reveal strong,
+.reveal b {
+	font-weight: bold;
+}
+
+.reveal em {
+	font-style: italic;
+}
+
+.reveal ol,
+.reveal dl,
+.reveal ul {
+	display: inline-block;
+
+	text-align: left;
+	margin: 0 0 0 1em;
+}
+
+.reveal ol {
+	list-style-type: decimal;
+}
+
+.reveal ul {
+	list-style-type: disc;
+}
+
+.reveal ul ul {
+	list-style-type: square;
+}
+
+.reveal ul ul ul {
+	list-style-type: circle;
+}
+
+.reveal ul ul,
+.reveal ul ol,
+.reveal ol ol,
+.reveal ol ul {
+	display: block;
+	margin-left: 40px;
+}
+
+.reveal dt {
+	font-weight: bold;
+}
+
+.reveal dd {
+	margin-left: 40px;
+}
+
+.reveal q,
+.reveal blockquote {
+	quotes: none;
+}
+
+.reveal blockquote {
+	display: block;
+	position: relative;
+	width: 70%;
+	margin: 5px auto;
+	padding: 5px;
+
+	font-style: italic;
+	background: rgba(255, 255, 255, 0.05);
+	box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
+}
+	.reveal blockquote p:first-child,
+	.reveal blockquote p:last-child {
+		display: inline-block;
+	}
+
+.reveal q {
+	font-style: italic;
+}
+
+.reveal pre {
+	display: block;
+	position: relative;
+	width: 90%;
+	margin: 15px auto;
+
+	text-align: left;
+	font-size: 0.55em;
+	font-family: monospace;
+	line-height: 1.2em;
+
+	word-wrap: break-word;
+
+	box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
+}
+.reveal code {
+	font-family: monospace;
+}
+
+.reveal pre code {
+	display: block;
+	padding: 5px;
+	overflow: auto;
+	max-height: 400px;
+	word-wrap: normal;
+	background: #3F3F3F;
+	color: #DCDCDC;
+}
+
+.reveal table {
+	margin: auto;
+	border-collapse: collapse;
+	border-spacing: 0;
+}
+
+.reveal table th {
+	font-weight: bold;
+}
+
+.reveal table th,
+.reveal table td {
+	text-align: left;
+	padding: 0.2em 0.5em 0.2em 0.5em;
+	border-bottom: 1px solid;
+}
+
+.reveal table tr:last-child td {
+    border-bottom: none;
+}
+
+.reveal sup {
+	vertical-align: super;
+}
+.reveal sub {
+	vertical-align: sub;
+}
+
+.reveal small {
+	display: inline-block;
+	font-size: 0.6em;
+	line-height: 1.2em;
+	vertical-align: top;
+}
+
+.reveal small * {
+	vertical-align: top;
+}
+
+
+/*********************************************
  * LINKS
  *********************************************/
 
-.reveal a:not(.image) {
+.reveal a {
 	color: $linkColor;
 	text-decoration: none;
 
 	-webkit-transition: color .15s ease;
 	   -moz-transition: color .15s ease;
-	    -ms-transition: color .15s ease;
-	     -o-transition: color .15s ease;
 	        transition: color .15s ease;
 }
-	.reveal a:not(.image):hover {
+	.reveal a:hover {
 		color: $linkColorHover;
 
 		text-shadow: none;
@@ -86,14 +257,14 @@ body {
 	border: 4px solid $mainColor;
 
 	box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-
-	-webkit-transition: all .2s linear;
-	   -moz-transition: all .2s linear;
-	    -ms-transition: all .2s linear;
-	     -o-transition: all .2s linear;
-	        transition: all .2s linear;
 }
 
+	.reveal a img {
+		-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);
 		border-color: $linkColor;
@@ -155,8 +326,6 @@ body {
 
 		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
-		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 	}
 

+ 59 - 33
index.html

@@ -12,23 +12,21 @@
 		<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">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
 
-		<link rel="stylesheet" href="css/reveal.min.css">
+		<link rel="stylesheet" href="css/reveal.css">
 		<link rel="stylesheet" href="css/theme/default.css" id="theme">
 
 		<!-- For syntax highlighting -->
 		<link rel="stylesheet" href="lib/css/zenburn.css">
 
-		<!-- If the query includes 'print-pdf', include the PDF print sheet -->
+		<!-- Include the appropriate print stylesheet -->
 		<script>
-			if( window.location.search.match( /print-pdf/gi ) ) {
-				var link = document.createElement( 'link' );
-				link.rel = 'stylesheet';
-				link.type = 'text/css';
-				link.href = 'css/print/pdf.css';
-				document.getElementsByTagName( 'head' )[0].appendChild( link );
-			}
+			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]>
@@ -70,8 +68,8 @@
 							Slides can be nested inside of other slides,
 							try pressing <a href="#" class="navigate-down">down</a>.
 						</p>
-						<a href="#" class="image navigate-down">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						<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>
@@ -82,14 +80,14 @@
 						<h2>Basement Level 2</h2>
 						<p>Cornify</p>
 						<a class="test" href="http://cornify.com">
-							<img width="280" height="326" src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif" alt="Unicorn">
+							<img width="280" height="326" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif" alt="Unicorn">
 						</a>
 					</section>
 					<section>
 						<h2>Basement Level 3</h2>
 						<p>That's it, time to go back up.</p>
-						<a href="#/2" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(180deg);">
+						<a href="#/2">
+							<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(180deg);">
 						</a>
 					</section>
 				</section>
@@ -97,7 +95,7 @@
 				<section>
 					<h2>Slides</h2>
 					<p>
-						Not a coder? No problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slid.es" target="_blank">http://slid.es</a>.
+						Not a coder? No 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>
 
@@ -137,6 +135,36 @@
 					</ol>
 				</section>
 
+				<section>
+					<h2>Superb 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 data-markdown>
 					<script type="text/template">
 						## Markdown support
@@ -158,14 +186,12 @@
 					<h2>Transition Styles</h2>
 					<p>
 						You can select from different transitions, like: <br>
-						<a href="?transition=cube#/transitions">Cube</a> -
-						<a href="?transition=page#/transitions">Page</a> -
-						<a href="?transition=concave#/transitions">Concave</a> -
-						<a href="?transition=zoom#/transitions">Zoom</a> -
-						<a href="?transition=linear#/transitions">Linear</a> -
-						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?#/transitions">Default</a> -
 						<a href="?transition=none#/transitions">None</a> -
-						<a href="?#/transitions">Default</a>
+						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?transition=slide#/transitions">Slide</a> -
+						<a href="?transition=concave#/transitions">Concave</a> -
+						<a href="?transition=zoom#/transitions">Zoom</a>
 					</p>
 				</section>
 
@@ -203,7 +229,7 @@
 					<p>
 						Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
 					</p>
-					<pre><code data-trim contenteditable style="font-size: 18px; margin-top: 20px;">
+					<pre><code class="javascript" data-trim contenteditable style="font-size: 18px;">
 Reveal.addEventListener( 'customevent', function() {
 	console.log( '"customevent" has fired' );
 } );
@@ -216,8 +242,8 @@ Reveal.addEventListener( 'customevent', function() {
 						<p>
 							Set <code>data-background="#007777"</code> on a slide to change the full page background to the given color. All CSS color formats are supported.
 						</p>
-						<a href="#" class="image navigate-down">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
+						<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/arrow.png">
@@ -230,14 +256,14 @@ Reveal.addEventListener( 'customevent', function() {
 					</section>
 				</section>
 
-				<section data-transition="linear" data-background="#4d7e65" data-background-transition="slide">
+				<section data-transition="slide" data-background="#4d7e65" data-background-transition="slide">
 					<h2>Background Transitions</h2>
 					<p>
 						Pass reveal.js the <code>backgroundTransition: 'slide'</code> config argument to make backgrounds slide rather than fade.
 					</p>
 				</section>
 
-				<section data-transition="linear" data-background="#8c4738" data-background-transition="slide">
+				<section data-transition="slide" data-background="#8c4738" data-background-transition="slide">
 					<h2>Background Transition Override</h2>
 					<p>
 						You can override background transitions per slide by using <code>data-background-transition="slide"</code>.
@@ -317,8 +343,8 @@ function linkify( selector ) {
 
 				<section>
 					<h2>Spectacular image!</h2>
-					<a class="image" href="http://lab.hakim.se/meny/" target="_blank">
-						<img width="320" height="299" src="http://s3.amazonaws.com/hakim-static/portfolio/images/meny.png" alt="Meny">
+					<a href="http://lab.hakim.se/meny/" target="_blank">
+						<img width="320" height="299" data-src="http://s3.amazonaws.com/hakim-static/portfolio/images/meny.png" alt="Meny">
 					</a>
 				</section>
 
@@ -358,7 +384,7 @@ function linkify( selector ) {
 		</div>
 
 		<script src="lib/js/head.min.js"></script>
-		<script src="js/reveal.min.js"></script>
+		<script src="js/reveal.js"></script>
 
 		<script>
 
@@ -371,7 +397,7 @@ function linkify( selector ) {
 				center: true,
 
 				theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
-				transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
+				transition: Reveal.getQueryHash().transition || 'default', // none/fade/slide/convex/concave/zoom
 
 				// Parallax scrolling
 				// parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
@@ -382,7 +408,7 @@ function linkify( selector ) {
 					{ 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/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
 					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
 					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
 				]

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 489 - 170
js/reveal.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 7
js/reveal.min.js


+ 74 - 71
lib/css/zenburn.css

@@ -5,110 +5,113 @@ based on dark.css by Ivan Sagalaev
 
 */
 
-pre code {
+.hljs {
   display: block; padding: 0.5em;
   background: #3F3F3F;
   color: #DCDCDC;
 }
 
-pre .keyword,
-pre .tag,
-pre .css .class,
-pre .css .id,
-pre .lisp .title,
-pre .nginx .title,
-pre .request,
-pre .status,
-pre .clojure .attribute {
+.hljs-keyword,
+.hljs-tag,
+.css .hljs-class,
+.css .hljs-id,
+.lisp .hljs-title,
+.nginx .hljs-title,
+.hljs-request,
+.hljs-status,
+.clojure .hljs-attribute {
   color: #E3CEAB;
 }
 
-pre .django .template_tag,
-pre .django .variable,
-pre .django .filter .argument {
+.django .hljs-template_tag,
+.django .hljs-variable,
+.django .hljs-filter .hljs-argument {
   color: #DCDCDC;
 }
 
-pre .number,
-pre .date {
+.hljs-number,
+.hljs-date {
   color: #8CD0D3;
 }
 
-pre .dos .envvar,
-pre .dos .stream,
-pre .variable,
-pre .apache .sqbracket {
+.dos .hljs-envvar,
+.dos .hljs-stream,
+.hljs-variable,
+.apache .hljs-sqbracket {
   color: #EFDCBC;
 }
 
-pre .dos .flow,
-pre .diff .change,
-pre .python .exception,
-pre .python .built_in,
-pre .literal,
-pre .tex .special {
+.dos .hljs-flow,
+.diff .hljs-change,
+.python .exception,
+.python .hljs-built_in,
+.hljs-literal,
+.tex .hljs-special {
   color: #EFEFAF;
 }
 
-pre .diff .chunk,
-pre .subst {
+.diff .hljs-chunk,
+.hljs-subst {
   color: #8F8F8F;
 }
 
-pre .dos .keyword,
-pre .python .decorator,
-pre .title,
-pre .haskell .type,
-pre .diff .header,
-pre .ruby .class .parent,
-pre .apache .tag,
-pre .nginx .built_in,
-pre .tex .command,
-pre .prompt {
+.dos .hljs-keyword,
+.python .hljs-decorator,
+.hljs-title,
+.haskell .hljs-type,
+.diff .hljs-header,
+.ruby .hljs-class .hljs-parent,
+.apache .hljs-tag,
+.nginx .hljs-built_in,
+.tex .hljs-command,
+.hljs-prompt {
     color: #efef8f;
 }
 
-pre .dos .winutils,
-pre .ruby .symbol,
-pre .ruby .symbol .string,
-pre .ruby .string {
+.dos .hljs-winutils,
+.ruby .hljs-symbol,
+.ruby .hljs-symbol .hljs-string,
+.ruby .hljs-string {
   color: #DCA3A3;
 }
 
-pre .diff .deletion,
-pre .string,
-pre .tag .value,
-pre .preprocessor,
-pre .built_in,
-pre .sql .aggregate,
-pre .javadoc,
-pre .smalltalk .class,
-pre .smalltalk .localvars,
-pre .smalltalk .array,
-pre .css .rules .value,
-pre .attr_selector,
-pre .pseudo,
-pre .apache .cbracket,
-pre .tex .formula {
+.diff .hljs-deletion,
+.hljs-string,
+.hljs-tag .hljs-value,
+.hljs-preprocessor,
+.hljs-pragma,
+.hljs-built_in,
+.sql .hljs-aggregate,
+.hljs-javadoc,
+.smalltalk .hljs-class,
+.smalltalk .hljs-localvars,
+.smalltalk .hljs-array,
+.css .hljs-rules .hljs-value,
+.hljs-attr_selector,
+.hljs-pseudo,
+.apache .hljs-cbracket,
+.tex .hljs-formula,
+.coffeescript .hljs-attribute {
   color: #CC9393;
 }
 
-pre .shebang,
-pre .diff .addition,
-pre .comment,
-pre .java .annotation,
-pre .template_comment,
-pre .pi,
-pre .doctype {
+.hljs-shebang,
+.diff .hljs-addition,
+.hljs-comment,
+.java .hljs-annotation,
+.hljs-template_comment,
+.hljs-pi,
+.hljs-doctype {
   color: #7F9F7F;
 }
 
-pre .coffeescript .javascript,
-pre .javascript .xml,
-pre .tex .formula,
-pre .xml .javascript,
-pre .xml .vbscript,
-pre .xml .css,
-pre .xml .cdata {
+.coffeescript .javascript,
+.javascript .xml,
+.tex .hljs-formula,
+.xml .javascript,
+.xml .vbscript,
+.xml .css,
+.xml .hljs-cdata {
   opacity: 0.5;
-}
+}
+

+ 3 - 3
package.json

@@ -1,6 +1,6 @@
 {
   "name": "reveal.js",
-  "version": "2.6.2",
+  "version": "3.0.0-dev",
   "description": "The HTML Presentation Framework",
   "homepage": "http://lab.hakim.se/reveal-js",
   "subdomain": "revealjs",
@@ -18,13 +18,13 @@
     "url": "git://github.com/hakimel/reveal.js.git"
   },
   "engines": {
-    "node": "~0.8.0"
+    "node": "~0.10.0"
   },
   "dependencies": {
     "underscore": "~1.5.1",
     "express": "~2.5.9",
     "mustache": "~0.7.2",
-    "socket.io": "~0.9.13"
+    "socket.io": "~0.9.16"
   },
   "devDependencies": {
     "grunt-contrib-qunit": "~0.2.2",

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 3
plugin/highlight/highlight.js


+ 4 - 2
plugin/leap/leap.js

@@ -76,8 +76,10 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re
       pointer.style.borderRadius = size - 5 + 'px';
       pointer.style.visibility   = 'visible';
 
+      tipPosition = frame.fingers[0].tipPosition;
+
       if( config.autoCenter ) {
-        tipPosition = frame.fingers[0].tipPosition;
+        
 
         // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option.
         if( !entered ) {
@@ -144,7 +146,7 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re
       // Two hand gestures
       else if( frame.hands.length === 2 ) {
         // Upward two hand swipe gesture
-        if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
+        if( gesture.type === 'swipe' && gesture.direction[1] > 0 ) {
           Reveal.toggleOverview();
         }
 

+ 2 - 2
plugin/markdown/example.html

@@ -19,7 +19,7 @@
 			<div class="slides">
 
                 <!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
-                <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section>
+                <section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
 
                 <!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
                 <section data-markdown data-separator="---">
@@ -36,7 +36,7 @@
                 </section>
 
                 <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
-                <section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+                <section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
                     <script type="text/template">
                         ## Demo 2
                         Slide 1.1

+ 8 - 7
plugin/markdown/markdown.js

@@ -50,7 +50,7 @@
 			text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
 		}
 		else if( leadingWs > 1 ) {
-			text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+			text = text.replace( new RegExp('\\n? {' + leadingWs + '}'), '\n' );
 		}
 
 		return text;
@@ -219,12 +219,13 @@
 
 				xhr.onreadystatechange = function() {
 					if( xhr.readyState === 4 ) {
-						if ( xhr.status >= 200 && xhr.status < 300 ) {
+						// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
+						if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
 
 							section.outerHTML = slidify( xhr.responseText, {
 								separator: section.getAttribute( 'data-separator' ),
-								verticalSeparator: section.getAttribute( 'data-vertical' ),
-								notesSeparator: section.getAttribute( 'data-notes' ),
+								verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+								notesSeparator: section.getAttribute( 'data-separator-notes' ),
 								attributes: getForwardedAttributes( section )
 							});
 
@@ -251,12 +252,12 @@
 				}
 
 			}
-			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
+			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
 
 				section.outerHTML = slidify( getMarkdownFromSlide( section ), {
 					separator: section.getAttribute( 'data-separator' ),
-					verticalSeparator: section.getAttribute( 'data-vertical' ),
-					notesSeparator: section.getAttribute( 'data-notes' ),
+					verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
+					notesSeparator: section.getAttribute( 'data-separator-notes' ),
 					attributes: getForwardedAttributes( section )
 				});
 

+ 49 - 46
plugin/notes-server/client.js

@@ -1,57 +1,60 @@
 (function() {
+
 	// don't emit events from inside the previews themselves
-	if ( window.location.search.match( /receiver/gi ) ) { return; }
-
-	var socket = io.connect(window.location.origin);
-	var socketId = Math.random().toString().slice(2);
-	
-	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
-	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
-
-	// Fires when a fragment is shown
-	Reveal.addEventListener( 'fragmentshown', function( event ) {
-		var fragmentData = {
-			fragment : 'next',
-			socketId : socketId
-		};
-		socket.emit('fragmentchanged', fragmentData);
-	} );
+	if( window.location.search.match( /receiver/gi ) ) { return; }
+
+	var socket = io.connect( window.location.origin ),
+		socketId = Math.random().toString().slice( 2 );
+
+	console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId );
+
+	window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId );
+
+	/**
+	 * Posts the current slide data to the notes window
+	 */
+	function post() {
+
+		var slideElement = Reveal.getCurrentSlide(),
+			notesElement = slideElement.querySelector( 'aside.notes' );
 
-	// Fires when a fragment is hidden
-	Reveal.addEventListener( 'fragmenthidden', function( event ) {
-		var fragmentData = {
-			fragment : 'previous',
-			socketId : socketId
+		var messageData = {
+			notes: '',
+			markdown: false,
+			socketId: socketId,
+			state: Reveal.getState()
 		};
-		socket.emit('fragmentchanged', fragmentData);
-	} );
 
-	// Fires when slide is changed
-	Reveal.addEventListener( 'slidechanged', function( event ) {
-		var nextindexh;
-		var nextindexv;
-		var slideElement = event.currentSlide;
-
-		if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
-			nextindexh = event.indexh;
-			nextindexv = event.indexv + 1;
-		} else {
-			nextindexh = event.indexh + 1;
-			nextindexv = 0;
+		// Look for notes defined in a slide attribute
+		if( slideElement.hasAttribute( 'data-notes' ) ) {
+			messageData.notes = slideElement.getAttribute( 'data-notes' );
+		}
+
+		// Look for notes defined in an aside element
+		if( notesElement ) {
+			messageData.notes = notesElement.innerHTML;
+			messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
 		}
 
-		var notes = slideElement.querySelector('aside.notes');
-		var slideData = {
-			notes : notes ? notes.innerHTML : '',
-			indexh : event.indexh,
-			indexv : event.indexv,
-			nextindexh : nextindexh,
-			nextindexv : nextindexv,
-			socketId : socketId,
-			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+		socket.emit( 'statechanged', messageData );
 
-		};
+	}
 
-		socket.emit('slidechanged', slideData);
+	// When a new notes window connects, post our current state
+	socket.on( 'connect', function( data ) {
+		post();
 	} );
+
+	// Monitor events that trigger a change in state
+	Reveal.addEventListener( 'slidechanged', post );
+	Reveal.addEventListener( 'fragmentshown', post );
+	Reveal.addEventListener( 'fragmenthidden', post );
+	Reveal.addEventListener( 'overviewhidden', post );
+	Reveal.addEventListener( 'overviewshown', post );
+	Reveal.addEventListener( 'paused', post );
+	Reveal.addEventListener( 'resumed', post );
+
+	// Post the initial state
+	post();
+
 }());

+ 28 - 21
plugin/notes-server/index.js

@@ -14,46 +14,53 @@ var opts = {
 	baseDir :   __dirname + '/../../'
 };
 
-io.sockets.on('connection', function(socket) {
-	socket.on('slidechanged', function(slideData) {
-		socket.broadcast.emit('slidedata', slideData);
+io.sockets.on( 'connection', function( socket ) {
+
+	socket.on( 'connect', function( data ) {
+		socket.broadcast.emit( 'connect', data );
 	});
-	socket.on('fragmentchanged', function(fragmentData) {
-		socket.broadcast.emit('fragmentdata', fragmentData);
+
+	socket.on( 'statechanged', function( data ) {
+		socket.broadcast.emit( 'statechanged', data );
 	});
+
 });
 
-app.configure(function() {
-	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
-		app.use('/' + dir, staticDir(opts.baseDir + dir));
+app.configure( function() {
+
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) {
+		app.use( '/' + dir, staticDir( opts.baseDir + dir ) );
 	});
+
 });
 
-app.get("/", function(req, res) {
-	res.writeHead(200, {'Content-Type': 'text/html'});
-	fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
+app.get('/', function( req, res ) {
+
+	res.writeHead( 200, { 'Content-Type': 'text/html' } );
+	fs.createReadStream( opts.baseDir + '/index.html' ).pipe( res );
+
 });
 
-app.get("/notes/:socketId", function(req, res) {
+app.get( '/notes/:socketId', function( req, res ) {
 
-	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
-		res.send(Mustache.to_html(data.toString(), {
+	fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) {
+		res.send( Mustache.to_html( data.toString(), {
 			socketId : req.params.socketId
 		}));
 	});
-	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
+
 });
 
 // Actually listen
-app.listen(opts.port || null);
+app.listen( opts.port || null );
 
 var brown = '\033[33m',
 	green = '\033[32m',
 	reset = '\033[0m';
 
-var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
+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( "3. Advance through your slides and your notes will advance automatically" );
+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( '3. Advance through your slides and your notes will advance automatically' );

+ 351 - 97
plugin/notes-server/notes.html

@@ -3,8 +3,6 @@
 	<head>
 		<meta charset="utf-8">
 
-		<meta name="viewport" content="width=1150">
-
 		<title>reveal.js - Slide Notes</title>
 
 		<style>
@@ -12,130 +10,386 @@
 				font-family: Helvetica;
 			}
 
-			#notes {
-				font-size: 24px;
-				width: 640px;
-				margin-top: 5px;
-				clear: left;
+			#current-slide,
+			#upcoming-slide,
+			#speaker-controls {
+				padding: 6px;
+				box-sizing: border-box;
+				-moz-box-sizing: border-box;
 			}
 
-			#wrap-current-slide {
-				width: 640px;
-				height: 512px;
-				float: left;
-				overflow: hidden;
+			#current-slide iframe,
+			#upcoming-slide iframe {
+				width: 100%;
+				height: 100%;
+				border: 1px solid #ddd;
 			}
 
-			#current-slide {
-				width: 1280px;
-				height: 1024px;
-				border: none;
-
-				-webkit-transform-origin: 0 0;
-				   -moz-transform-origin: 0 0;
-				    -ms-transform-origin: 0 0;
-				     -o-transform-origin: 0 0;
-				        transform-origin: 0 0;
-
-				-webkit-transform: scale(0.5);
-				   -moz-transform: scale(0.5);
-				    -ms-transform: scale(0.5);
-				     -o-transform: scale(0.5);
-				        transform: scale(0.5);
-			}
-
-			#wrap-next-slide {
-				width: 448px;
-				height: 358px;
-				float: left;
-				margin: 0 0 0 10px;
-				overflow: hidden;
-			}
-
-			#next-slide {
-				width: 1280px;
-				height: 1024px;
-				border: none;
-
-				-webkit-transform-origin: 0 0;
-				   -moz-transform-origin: 0 0;
-				    -ms-transform-origin: 0 0;
-				     -o-transform-origin: 0 0;
-				        transform-origin: 0 0;
-
-				-webkit-transform: scale(0.35);
-				   -moz-transform: scale(0.35);
-				    -ms-transform: scale(0.35);
-				     -o-transform: scale(0.35);
-				        transform: scale(0.35);
-			}
-
-			.slides {
-				position: relative;
-				margin-bottom: 10px;
-				border: 1px solid black;
-				border-radius: 2px;
-				background: rgb(28, 30, 32);
-			}
-
-			.slides span {
+			#current-slide .label,
+			#upcoming-slide .label {
 				position: absolute;
-				top: 3px;
-				left: 3px;
+				top: 10px;
+				left: 10px;
 				font-weight: bold;
 				font-size: 14px;
+				z-index: 2;
 				color: rgba( 255, 255, 255, 0.9 );
 			}
+
+			#current-slide {
+				position: absolute;
+				width: 65%;
+				height: 100%;
+				top: 0;
+				left: 0;
+				padding-right: 0;
+			}
+
+			#upcoming-slide {
+				position: absolute;
+				width: 35%;
+				height: 40%;
+				right: 0;
+				top: 0;
+			}
+
+			#speaker-controls {
+				position: absolute;
+				top: 40%;
+				right: 0;
+				width: 35%;
+				height: 60%;
+
+				font-size: 18px;
+			}
+
+				.speaker-controls-time.hidden,
+				.speaker-controls-notes.hidden {
+					display: none;
+				}
+
+				.speaker-controls-time .label,
+				.speaker-controls-notes .label {
+					text-transform: uppercase;
+					font-weight: normal;
+					font-size: 0.66em;
+					color: #666;
+					margin: 0;
+				}
+
+				.speaker-controls-time {
+					border-bottom: 1px solid rgba( 200, 200, 200, 0.5 );
+					margin-bottom: 10px;
+					padding: 10px 16px;
+					padding-bottom: 20px;
+					cursor: pointer;
+				}
+
+				.speaker-controls-time .reset-button {
+					opacity: 0;
+					float: right;
+					color: #666;
+					text-decoration: none;
+				}
+				.speaker-controls-time:hover .reset-button {
+					opacity: 1;
+				}
+
+				.speaker-controls-time .timer,
+				.speaker-controls-time .clock {
+					width: 50%;
+					font-size: 1.9em;
+				}
+
+				.speaker-controls-time .timer {
+					float: left;
+				}
+
+				.speaker-controls-time .clock {
+					float: right;
+					text-align: right;
+				}
+
+				.speaker-controls-time span.mute {
+					color: #bbb;
+				}
+
+				.speaker-controls-notes {
+					padding: 10px 16px;
+				}
+
+				.speaker-controls-notes .value {
+					margin-top: 5px;
+					line-height: 1.4;
+					font-size: 1.2em;
+				}
+
+			.clear {
+				clear: both;
+			}
+
+			@media screen and (max-width: 1080px) {
+				#speaker-controls {
+					font-size: 16px;
+				}
+			}
+
+			@media screen and (max-width: 900px) {
+				#speaker-controls {
+					font-size: 14px;
+				}
+			}
+
+			@media screen and (max-width: 800px) {
+				#speaker-controls {
+					font-size: 12px;
+				}
+			}
+
 		</style>
 	</head>
 
 	<body>
 
-		<div id="wrap-current-slide" class="slides">
-			<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe>
-		</div>
+		<div id="current-slide"></div>
+		<div id="upcoming-slide"><span class="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>
+				<div class="clock">
+					<span class="clock-value">0:00 AM</span>
+				</div>
+				<div class="timer">
+					<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
+				</div>
+				<div class="clear"></div>
+			</div>
 
-		<div id="wrap-next-slide" class="slides">
-			<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
-			<span>UPCOMING:</span>
+			<div class="speaker-controls-notes hidden">
+				<h4 class="label">Notes</h4>
+				<div class="value"></div>
+			</div>
 		</div>
-		<div id="notes"></div>
 
 		<script src="/socket.io/socket.io.js"></script>
 		<script src="/plugin/markdown/marked.js"></script>
 
 		<script>
-		var socketId = '{{socketId}}';
-		var socket = io.connect(window.location.origin);
-		var notes = document.getElementById('notes');
-		var currentSlide = document.getElementById('current-slide');
-		var nextSlide = document.getElementById('next-slide');
+		(function() {
+
+			var notes,
+				notesValue,
+				currentState,
+				currentSlide,
+				upcomingSlide,
+				connected = false;
+
+			var socket = io.connect( window.location.origin ),
+				socketId = '{{socketId}}';
+
+			socket.on( 'statechanged', function( data ) {
+
+				// ignore data from sockets that aren't ours
+				if( data.socketId !== socketId ) { return; }
+
+				if( connected === false ) {
+					connected = true;
+
+					setupIframes( data );
+					setupKeyboard();
+					setupNotes();
+					setupTimer();
+
+				}
+
+				handleStateMessage( data );
+
+			} );
+
+			window.addEventListener( 'message', function( event ) {
 
-		socket.on('slidedata', function(data) {
-			// ignore data from sockets that aren't ours
-			if (data.socketId !== socketId) { return; }
+				var data = JSON.parse( event.data );
+
+				if( data && data.namespace === 'reveal' ) {
+					if( /ready/.test( data.eventName ) ) {
+						socket.emit( 'connect', { socketId: socketId } );
+					}
+				}
+
+			} );
+
+			/**
+			 * Called when the main window sends an updated state.
+			 */
+			function handleStateMessage( data ) {
+
+				// Store the most recently set state to avoid circular loops
+				// applying the same state
+				currentState = JSON.stringify( data.state );
+
+				// No need for updating the notes in case of fragment changes
+				if ( data.notes ) {
+					notes.classList.remove( 'hidden' );
+					if( data.markdown ) {
+						notesValue.innerHTML = marked( data.notes );
+					}
+					else {
+						notesValue.innerHTML = data.notes;
+					}
+				}
+				else {
+					notes.classList.add( 'hidden' );
+				}
+
+				// Update the note slides
+				currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
+				upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
+				upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'next' }), '*' );
 
-			if (data.markdown) {
-				notes.innerHTML = marked(data.notes);
 			}
-			else {
-				notes.innerHTML = data.notes;
+
+			// Limit to max one state update per X ms
+			handleStateMessage = debounce( handleStateMessage, 200 );
+
+			/**
+			 * Forward keyboard events to the current slide window.
+			 * This enables keyboard events to work even if focus
+			 * isn't set on the current slide iframe.
+			 */
+			function setupKeyboard() {
+
+				document.addEventListener( 'keydown', function( event ) {
+					currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'triggerKey', args: [ event.keyCode ] }), '*' );
+				} );
+
 			}
 
-			currentSlide.contentWindow.Reveal.slide(data.indexh, data.indexv);
-			nextSlide.contentWindow.Reveal.slide(data.nextindexh, data.nextindexv);
-		});
-		socket.on('fragmentdata', function(data) {
-			// ignore data from sockets that aren't ours
-			if (data.socketId !== socketId) { return; }
+			/**
+			 * Creates the preview iframes.
+			 */
+			function setupIframes( data ) {
+
+				var params = [
+					'receiver',
+					'progress=false',
+					'history=false',
+					'transition=none',
+					'backgroundTransition=none'
+				].join( '&' );
+
+				var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
+				var currentURL = '/?' + params + '&postMessageEvents=true' + hash;
+				var upcomingURL = '/?' + params + '&controls=false' + hash;
+
+				currentSlide = document.createElement( 'iframe' );
+				currentSlide.setAttribute( 'width', 1280 );
+				currentSlide.setAttribute( 'height', 1024 );
+				currentSlide.setAttribute( 'src', currentURL );
+				document.querySelector( '#current-slide' ).appendChild( currentSlide );
+
+				upcomingSlide = document.createElement( 'iframe' );
+				upcomingSlide.setAttribute( 'width', 640 );
+				upcomingSlide.setAttribute( 'height', 512 );
+				upcomingSlide.setAttribute( 'src', upcomingURL );
+				document.querySelector( '#upcoming-slide' ).appendChild( upcomingSlide );
 
-			if (data.fragment === 'next') {
-				currentSlide.contentWindow.Reveal.nextFragment();
 			}
-			else if (data.fragment === 'previous') {
-				currentSlide.contentWindow.Reveal.prevFragment();
+
+			/**
+			 * Setup the notes UI.
+			 */
+			function setupNotes() {
+
+				notes = document.querySelector( '.speaker-controls-notes' );
+				notesValue = document.querySelector( '.speaker-controls-notes .value' );
+
 			}
-		});
+
+			/**
+			 * Create the timer and clock and start updating them
+			 * at an interval.
+			 */
+			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' );
+
+				function _updateTimer() {
+
+					var diff, hours, minutes, seconds,
+						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 );
+
+				}
+
+				// Update once directly
+				_updateTimer();
+
+				// Then update every second
+				setInterval( _updateTimer, 1000 );
+
+				timeEl.addEventListener( 'click', function() {
+					start = new Date();
+					_updateTimer();
+					return false;
+				} );
+
+			}
+
+			function zeroPadInteger( num ) {
+
+				var str = '00' + parseInt( num );
+				return str.substring( str.length - 2 );
+
+			}
+
+			/**
+			 * Limits the frequency at which a function can be called.
+			 */
+			function debounce( fn, ms ) {
+
+				var lastTime = 0,
+					timeout;
+
+				return function() {
+
+					var args = arguments;
+					var context = this;
+
+					clearTimeout( timeout );
+
+					var timeSinceLastCall = Date.now() - lastTime;
+					if( timeSinceLastCall > ms ) {
+						fn.apply( context, args );
+						lastTime = Date.now();
+					}
+					else {
+						timeout = setTimeout( function() {
+							fn.apply( context, args );
+							lastTime = Date.now();
+						}, ms - timeSinceLastCall );
+					}
+
+				}
+
+			}
+
+		})();
 		</script>
 
 	</body>

+ 319 - 182
plugin/notes/notes.html

@@ -10,127 +10,140 @@
 				font-family: Helvetica;
 			}
 
-			#notes {
-				font-size: 24px;
-				width: 640px;
-				margin-top: 5px;
-				clear: left;
+			#current-slide,
+			#upcoming-slide,
+			#speaker-controls {
+				padding: 6px;
+				box-sizing: border-box;
+				-moz-box-sizing: border-box;
 			}
 
-			#wrap-current-slide {
-				width: 640px;
-				height: 512px;
-				float: left;
-				overflow: hidden;
+			#current-slide iframe,
+			#upcoming-slide iframe {
+				width: 100%;
+				height: 100%;
+				border: 1px solid #ddd;
 			}
 
-			#current-slide {
-				width: 1280px;
-				height: 1024px;
-				border: none;
-
-				-webkit-transform-origin: 0 0;
-				   -moz-transform-origin: 0 0;
-					-ms-transform-origin: 0 0;
-					 -o-transform-origin: 0 0;
-						transform-origin: 0 0;
-
-				-webkit-transform: scale(0.5);
-				   -moz-transform: scale(0.5);
-					-ms-transform: scale(0.5);
-					 -o-transform: scale(0.5);
-						transform: scale(0.5);
-			}
-
-			#wrap-next-slide {
-				width: 448px;
-				height: 358px;
-				float: left;
-				margin: 0 0 0 10px;
-				overflow: hidden;
+			#current-slide .label,
+			#upcoming-slide .label {
+				position: absolute;
+				top: 10px;
+				left: 10px;
+				font-weight: bold;
+				font-size: 14px;
+				z-index: 2;
+				color: rgba( 255, 255, 255, 0.9 );
 			}
 
-			#next-slide {
-				width: 1280px;
-				height: 1024px;
-				border: none;
-
-				-webkit-transform-origin: 0 0;
-				   -moz-transform-origin: 0 0;
-					-ms-transform-origin: 0 0;
-					 -o-transform-origin: 0 0;
-						transform-origin: 0 0;
-
-				-webkit-transform: scale(0.35);
-				   -moz-transform: scale(0.35);
-					-ms-transform: scale(0.35);
-					 -o-transform: scale(0.35);
-						transform: scale(0.35);
+			#current-slide {
+				position: absolute;
+				width: 65%;
+				height: 100%;
+				top: 0;
+				left: 0;
+				padding-right: 0;
 			}
 
-			.slides {
-				position: relative;
-				margin-bottom: 10px;
-				border: 1px solid black;
-				border-radius: 2px;
-				background: rgb(28, 30, 32);
+			#upcoming-slide {
+				position: absolute;
+				width: 35%;
+				height: 40%;
+				right: 0;
+				top: 0;
 			}
 
-			.slides span {
+			#speaker-controls {
 				position: absolute;
-				top: 3px;
-				left: 3px;
-				font-weight: bold;
-				font-size: 14px;
-				color: rgba( 255, 255, 255, 0.9 );
-			}
+				top: 40%;
+				right: 0;
+				width: 35%;
+				height: 60%;
 
-			.error {
-				font-weight: bold;
-				color: red;
-				font-size: 1.5em;
-				text-align: center;
-				margin-top: 10%;
+				font-size: 18px;
 			}
 
-			.error code {
-				font-family: monospace;
-			}
+				.speaker-controls-time.hidden,
+				.speaker-controls-notes.hidden {
+					display: none;
+				}
+
+				.speaker-controls-time .label,
+				.speaker-controls-notes .label {
+					text-transform: uppercase;
+					font-weight: normal;
+					font-size: 0.66em;
+					color: #666;
+					margin: 0;
+				}
 
-			.time {
-				width: 448px;
-				margin: 30px 0 0 10px;
-				float: left;
-				text-align: center;
-				opacity: 0;
-
-				-webkit-transition: opacity 0.4s;
-				   -moz-transition: opacity 0.4s;
-				     -o-transition: opacity 0.4s;
-				        transition: opacity 0.4s;
+				.speaker-controls-time {
+					border-bottom: 1px solid rgba( 200, 200, 200, 0.5 );
+					margin-bottom: 10px;
+					padding: 10px 16px;
+					padding-bottom: 20px;
+					cursor: pointer;
+				}
+
+				.speaker-controls-time .reset-button {
+					opacity: 0;
+					float: right;
+					color: #666;
+					text-decoration: none;
+				}
+				.speaker-controls-time:hover .reset-button {
+					opacity: 1;
+				}
+
+				.speaker-controls-time .timer,
+				.speaker-controls-time .clock {
+					width: 50%;
+					font-size: 1.9em;
+				}
+
+				.speaker-controls-time .timer {
+					float: left;
+				}
+
+				.speaker-controls-time .clock {
+					float: right;
+					text-align: right;
+				}
+
+				.speaker-controls-time span.mute {
+					color: #bbb;
+				}
+
+				.speaker-controls-notes {
+					padding: 10px 16px;
+				}
+
+				.speaker-controls-notes .value {
+					margin-top: 5px;
+					line-height: 1.4;
+					font-size: 1.2em;
+				}
+
+			.clear {
+				clear: both;
 			}
 
-			.elapsed,
-			.clock {
-				color: #333;
-				font-size: 2em;
-				text-align: center;
-				display: inline-block;
-				padding: 0.5em;
-				background-color: #eee;
-				border-radius: 10px;
+			@media screen and (max-width: 1080px) {
+				#speaker-controls {
+					font-size: 16px;
+				}
 			}
 
-			.elapsed h2,
-			.clock h2 {
-				font-size: 0.8em;
-				line-height: 100%;
-				margin: 0;
-				color: #aaa;
+			@media screen and (max-width: 900px) {
+				#speaker-controls {
+					font-size: 14px;
+				}
 			}
 
-			.elapsed .mute {
-				color: #ddd;
+			@media screen and (max-width: 800px) {
+				#speaker-controls {
+					font-size: 12px;
+				}
 			}
 
 		</style>
@@ -138,81 +151,182 @@
 
 	<body>
 
-		<script>
-			function getNotesURL( controls ) {
-				return window.opener.location.protocol + '//' + window.opener.location.host + window.opener.location.pathname + '?receiver&controls='+ ( controls || 'false' ) +'&progress=false&overview=false' + window.opener.location.hash;
-			}
-			var notesCurrentSlideURL = getNotesURL( true );
-			var notesNextSlideURL = getNotesURL( false );
-		</script>
-
-		<div id="wrap-current-slide" class="slides">
-			<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ notesCurrentSlideURL +'"></iframe>' );</script>
-		</div>
-
-		<div id="wrap-next-slide" class="slides">
-			<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ notesNextSlideURL +'"></iframe>' );</script>
-			<span>UPCOMING:</span>
-		</div>
-
-		<div class="time">
-			<div class="clock">
-				<h2>Time</h2>
-				<span id="clock">0:00:00 AM</span>
+		<div id="current-slide"></div>
+		<div id="upcoming-slide"><span class="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>
+				<div class="clock">
+					<span class="clock-value">0:00 AM</span>
+				</div>
+				<div class="timer">
+					<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
+				</div>
+				<div class="clear"></div>
 			</div>
-			<div class="elapsed">
-				<h2>Elapsed</h2>
-				<span id="hours">00</span><span id="minutes">:00</span><span id="seconds">:00</span>
+
+			<div class="speaker-controls-notes hidden">
+				<h4 class="label">Notes</h4>
+				<div class="value"></div>
 			</div>
 		</div>
 
-		<div id="notes"></div>
-
 		<script src="../../plugin/markdown/marked.js"></script>
 		<script>
 
-			window.addEventListener( 'load', function() {
+			(function() {
 
-				if( window.opener && window.opener.location && window.opener.location.href ) {
+				var notes,
+					notesValue,
+					currentState,
+					currentSlide,
+					upcomingSlide,
+					connected = false;
 
-					var notes = document.getElementById( 'notes' ),
-						currentSlide = document.getElementById( 'current-slide' ),
-						nextSlide = document.getElementById( 'next-slide' ),
-						silenced = false;
+				window.addEventListener( 'message', function( event ) {
 
-					window.addEventListener( 'message', function( event ) {
-						var data = JSON.parse( event.data );
+					var data = JSON.parse( event.data );
 
-						// No need for updating the notes in case of fragment changes
-						if ( data.notes !== undefined) {
-							if( data.markdown ) {
-								notes.innerHTML = marked( data.notes );
-							}
-							else {
-								notes.innerHTML = data.notes;
-							}
+					// Messages sent by the notes plugin inside of the main window
+					if( data && data.namespace === 'reveal-notes' ) {
+						if( data.type === 'connect' ) {
+							handleConnectMessage( data );
 						}
+						else if( data.type === 'state' ) {
+							handleStateMessage( data );
+						}
+					}
+					// Messages sent by the reveal.js inside of the current slide preview
+					else if( data && data.namespace === 'reveal' ) {
+						if( /ready/.test( data.eventName ) ) {
+							// 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 ) ) {
+							window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ]} ), '*' );
+						}
+					}
+
+				} );
 
-						silenced = true;
+				/**
+				 * Called when the main window is trying to establish a
+				 * connection.
+				 */
+				function handleConnectMessage( data ) {
 
-						// Update the note slides
-						currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv, data.indexf );
-						nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv );
+					if( connected === false ) {
+						connected = true;
 
-						silenced = false;
+						setupIframes( data );
+						setupKeyboard();
+						setupNotes();
+						setupTimer();
+					}
 
-					}, false );
+				}
 
-					var start = new Date(),
-						timeEl = document.querySelector( '.time' ),
-						clockEl = document.getElementById( 'clock' ),
-						hoursEl = document.getElementById( 'hours' ),
-						minutesEl = document.getElementById( 'minutes' ),
-						secondsEl = document.getElementById( 'seconds' );
+				/**
+				 * Called when the main window sends an updated state.
+				 */
+				function handleStateMessage( data ) {
+
+					// Store the most recently set state to avoid circular loops
+					// applying the same state
+					currentState = JSON.stringify( data.state );
+
+					// No need for updating the notes in case of fragment changes
+					if ( data.notes ) {
+						notes.classList.remove( 'hidden' );
+						if( data.markdown ) {
+							notesValue.innerHTML = marked( data.notes );
+						}
+						else {
+							notesValue.innerHTML = data.notes;
+						}
+					}
+					else {
+						notes.classList.add( 'hidden' );
+					}
+
+					// Update the note slides
+					currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
+					upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
+					upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'next' }), '*' );
+
+				}
+
+				// Limit to max one state update per X ms
+				handleStateMessage = debounce( handleStateMessage, 200 );
+
+				/**
+				 * Forward keyboard events to the current slide window.
+				 * This enables keyboard events to work even if focus
+				 * isn't set on the current slide iframe.
+				 */
+				function setupKeyboard() {
+
+					document.addEventListener( 'keydown', function( event ) {
+						currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'triggerKey', args: [ event.keyCode ] }), '*' );
+					} );
+
+				}
+
+				/**
+				 * Creates the preview iframes.
+				 */
+				function setupIframes( data ) {
+
+					var params = [
+						'receiver',
+						'progress=false',
+						'history=false',
+						'transition=none',
+						'backgroundTransition=none'
+					].join( '&' );
+
+					var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
+					var currentURL = data.url + '?' + params + '&postMessageEvents=true' + hash;
+					var upcomingURL = data.url + '?' + params + '&controls=false' + hash;
+
+					currentSlide = document.createElement( 'iframe' );
+					currentSlide.setAttribute( 'width', 1280 );
+					currentSlide.setAttribute( 'height', 1024 );
+					currentSlide.setAttribute( 'src', currentURL );
+					document.querySelector( '#current-slide' ).appendChild( currentSlide );
+
+					upcomingSlide = document.createElement( 'iframe' );
+					upcomingSlide.setAttribute( 'width', 640 );
+					upcomingSlide.setAttribute( 'height', 512 );
+					upcomingSlide.setAttribute( 'src', upcomingURL );
+					document.querySelector( '#upcoming-slide' ).appendChild( upcomingSlide );
 
-					setInterval( function() {
+				}
+
+				/**
+				 * Setup the notes UI.
+				 */
+				function setupNotes() {
+
+					notes = document.querySelector( '.speaker-controls-notes' );
+					notesValue = document.querySelector( '.speaker-controls-notes .value' );
+
+				}
+
+				/**
+				 * Create the timer and clock and start updating them
+				 * at an interval.
+				 */
+				function setupTimer() {
 
-						timeEl.style.opacity = 1;
+					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' );
+
+					function _updateTimer() {
 
 						var diff, hours, minutes, seconds,
 							now = new Date();
@@ -222,45 +336,68 @@
 						minutes = Math.floor( ( diff / ( 1000 * 60 ) ) % 60 );
 						seconds = Math.floor( ( diff / 1000 ) % 60 );
 
-						clockEl.innerHTML = now.toLocaleTimeString();
+						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 );
-
-					}, 1000 );
+						hoursEl.className = hours > 0 ? '' : 'mute';
+						minutesEl.innerHTML = ':' + zeroPadInteger( minutes );
+						minutesEl.className = minutes > 0 ? '' : 'mute';
+						secondsEl.innerHTML = ':' + zeroPadInteger( seconds );
 
-					// Broadcasts the state of the notes window to synchronize
-					// the main window
-					function synchronizeMainWindow() {
+					}
 
-						if( !silenced ) {
-							var indices = currentSlide.contentWindow.Reveal.getIndices();
-							window.opener.Reveal.slide( indices.h, indices.v, indices.f );
-						}
+					// Update once directly
+					_updateTimer();
 
-					}
+					// Then update every second
+					setInterval( _updateTimer, 1000 );
 
-					// Navigate the main window when the notes slide changes
-					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', synchronizeMainWindow );
-					currentSlide.contentWindow.Reveal.addEventListener( 'fragmentshown', synchronizeMainWindow );
-					currentSlide.contentWindow.Reveal.addEventListener( 'fragmenthidden', synchronizeMainWindow );
+					timeEl.addEventListener( 'click', function() {
+						start = new Date();
+						_updateTimer();
+						return false;
+					} );
 
 				}
-				else {
 
-					document.body.innerHTML =  '<p class="error">Unable to access <code>window.opener.location</code>.<br>Make sure the presentation is running on a web server.</p>';
+				function zeroPadInteger( num ) {
+
+					var str = '00' + parseInt( num );
+					return str.substring( str.length - 2 );
 
 				}
 
+				/**
+				 * Limits the frequency at which a function can be called.
+				 */
+				function debounce( fn, ms ) {
 
-			}, false );
+					var lastTime = 0,
+						timeout;
 
-			function zeroPadInteger( num ) {
-				var str = "00" + parseInt( num );
-				return str.substring( str.length - 2 );
-			}
+					return function() {
+
+						var args = arguments;
+						var context = this;
+
+						clearTimeout( timeout );
+
+						var timeSinceLastCall = Date.now() - lastTime;
+						if( timeSinceLastCall > ms ) {
+							fn.apply( context, args );
+							lastTime = Date.now();
+						}
+						else {
+							timeout = setTimeout( function() {
+								fn.apply( context, args );
+								lastTime = Date.now();
+							}, ms - timeSinceLastCall );
+						}
+
+					}
+
+				}
+
+			})();
 
 		</script>
 	</body>

+ 72 - 33
plugin/notes/notes.js

@@ -1,60 +1,99 @@
 /**
  * Handles opening of and synchronization with the reveal.js
  * notes window.
+ *
+ * Handshake process:
+ * 1. This window posts 'connect' to notes window
+ *    - Includes URL of presentation to show
+ * 2. Notes window responds with 'connected' when it is available
+ * 3. This window proceeds to send the current presentation state
+ *    to the notes window
  */
 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=1120,height=850' );
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1100,height=700' );
 
-		// Fires when slide is changed
-		Reveal.addEventListener( 'slidechanged', post );
-
-		// Fires when a fragment is shown
-		Reveal.addEventListener( 'fragmentshown', post );
+		/**
+		 * Connect to the notes window through a postmessage handshake.
+		 * Using postmessage enables us to work in situations where the
+		 * origins differ, such as a presentation being opened from the
+		 * file system.
+		 */
+		function connect() {
+			// Keep trying to connect until we get a 'connected' message back
+			var connectInterval = setInterval( function() {
+				notesPopup.postMessage( JSON.stringify( {
+					namespace: 'reveal-notes',
+					type: 'connect',
+					url: window.location.protocol + '//' + window.location.host + window.location.pathname,
+					state: Reveal.getState()
+				} ), '*' );
+			}, 500 );
 
-		// Fires when a fragment is hidden
-		Reveal.addEventListener( 'fragmenthidden', post );
+			window.addEventListener( 'message', function( event ) {
+				var data = JSON.parse( event.data );
+				if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
+					clearInterval( connectInterval );
+					onConnected();
+				}
+			} );
+		}
 
 		/**
 		 * Posts the current slide data to the notes window
 		 */
 		function post() {
+
 			var slideElement = Reveal.getCurrentSlide(),
-				slideIndices = Reveal.getIndices(),
-				messageData;
-
-			var notes = slideElement.querySelector( 'aside.notes' ),
-				nextindexh,
-				nextindexv;
-
-			if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
-				nextindexh = slideIndices.h;
-				nextindexv = slideIndices.v + 1;
-			} else {
-				nextindexh = slideIndices.h + 1;
-				nextindexv = 0;
-			}
+				notesElement = slideElement.querySelector( 'aside.notes' );
 
-			messageData = {
-				notes : notes ? notes.innerHTML : '',
-				indexh : slideIndices.h,
-				indexv : slideIndices.v,
-				indexf : slideIndices.f,
-				nextindexh : nextindexh,
-				nextindexv : nextindexv,
-				markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+			var messageData = {
+				namespace: 'reveal-notes',
+				type: 'state',
+				notes: '',
+				markdown: false,
+				state: Reveal.getState()
 			};
 
+			// Look for notes defined in a slide attribute
+			if( slideElement.hasAttribute( 'data-notes' ) ) {
+				messageData.notes = slideElement.getAttribute( 'data-notes' );
+			}
+
+			// Look for notes defined in an aside element
+			if( notesElement ) {
+				messageData.notes = notesElement.innerHTML;
+				messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
+			}
+
 			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+
 		}
 
-		// Navigate to the current slide when the notes are loaded
-		notesPopup.addEventListener( 'load', function( event ) {
+		/**
+		 * Called once we have established a connection to the notes
+		 * window.
+		 */
+		function onConnected() {
+
+			// Monitor events that trigger a change in state
+			Reveal.addEventListener( 'slidechanged', post );
+			Reveal.addEventListener( 'fragmentshown', post );
+			Reveal.addEventListener( 'fragmenthidden', post );
+			Reveal.addEventListener( 'overviewhidden', post );
+			Reveal.addEventListener( 'overviewshown', post );
+			Reveal.addEventListener( 'paused', post );
+			Reveal.addEventListener( 'resumed', post );
+
+			// Post the initial state
 			post();
-		}, false );
+
+		}
+
+		connect();
 	}
 
 	// If the there's a 'notes' query set, open directly

+ 0 - 39
plugin/postmessage/example.html

@@ -1,39 +0,0 @@
-<html>
-	<body>
-
-		<iframe id="reveal" src="../../index.html" style="border: 0;" width="500" height="500"></iframe>
-
-		<div>
-			<input id="back" type="button" value="go back"/>
-			<input id="ahead" type="button" value="go ahead"/>
-			<input id="slideto" type="button" value="slideto 2-2"/>
-		</div>
-
-		<script>
-
-			(function (){
-
-				var back = document.getElementById( 'back' ),
-						ahead = document.getElementById( 'ahead' ),
-						slideto = document.getElementById( 'slideto' ),
-						reveal =  window.frames[0];
-
-					back.addEventListener( 'click', function () {
-						
-					reveal.postMessage( JSON.stringify({method: 'prev', args: []}), '*' );
-				}, false );
-
-				ahead.addEventListener( 'click', function (){
-					reveal.postMessage( JSON.stringify({method: 'next', args: []}), '*' );
-				}, false );
-
-				slideto.addEventListener( 'click', function (){
-					reveal.postMessage( JSON.stringify({method: 'slide', args: [2,2]}), '*' );
-				}, false );
-
-			}());
-
-		</script>
-
-	</body>
-</html>

+ 0 - 42
plugin/postmessage/postmessage.js

@@ -1,42 +0,0 @@
-/*
-
-	simple postmessage plugin
-
-	Useful when a reveal slideshow is inside an iframe.
-	It allows to call reveal methods from outside.
-
-	Example:
-		 var reveal =  window.frames[0];
-
-		 // Reveal.prev(); 
-		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
-		 // Reveal.next(); 
-		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
-		 // Reveal.slide(2, 2); 
-		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
-
-	Add to the slideshow:
-
-		dependencies: [
-			...
-			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
-		]
-
-*/
-
-(function (){
-
-	window.addEventListener( "message", function ( event ) {
-		var data = JSON.parse( event.data ),
-				method = data.method,
-				args = data.args;
-
-		if( typeof Reveal[method] === 'function' ) {
-			Reveal[method].apply( Reveal, data.args );
-		}
-	}, false);
-
-}());
-
-
-

+ 24 - 20
plugin/print-pdf/print-pdf.js

@@ -11,34 +11,38 @@
 var page = new WebPage();
 var system = require( 'system' );
 
-page.viewportSize  = {
-	width: 1024,
-	height: 768
+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 = {
-	format: 'letter',
-	orientation: 'landscape',
-	margin: {
-		left: '0',
-		right: '0',
-		top: '0',
-		bottom: '0'
-	}
+	width: Math.round( slideWidth * 2 ),
+	height: Math.round( slideHeight * 2 ),
+	border: 0
 };
 
-var revealFile = system.args[1] || 'index.html?print-pdf';
-var slideFile = system.args[2] || 'slides.pdf';
+var inputFile = system.args[1] || 'index.html?print-pdf';
+var outputFile = system.args[2] || 'slides.pdf';
 
-if( slideFile.match( /\.pdf$/gi ) === null ) {
-	slideFile += '.pdf';
+if( outputFile.match( /\.pdf$/gi ) === null ) {
+	outputFile += '.pdf';
 }
 
-console.log( 'Printing PDF...' );
+console.log( 'Printing PDF (Paper size: '+ page.paperSize.width + 'x' + page.paperSize.height +')' );
 
-page.open( revealFile, function( status ) {
-	console.log( 'Printed succesfully' );
-	page.render( slideFile );
-	phantom.exit();
+page.open( inputFile, function( status ) {
+	window.setTimeout( function() {
+		console.log( 'Printed succesfully' );
+		page.render( outputFile );
+		phantom.exit();
+	}, 1000 );
 } );
 

+ 64 - 56
plugin/zoom-js/zoom.js

@@ -16,11 +16,11 @@
 })();
 
 /*!
- * zoom.js 0.2 (modified version for use with reveal.js)
+ * zoom.js 0.3 (modified for use with reveal.js)
  * http://lab.hakim.se/zoom-js
  * MIT licensed
  *
- * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
  */
 var zoom = (function(){
 
@@ -35,8 +35,6 @@ var zoom = (function(){
 	var panEngageTimeout = -1,
 		panUpdateInterval = -1;
 
-	var currentOptions = null;
-
 	// Check for transform support so that we can fallback otherwise
 	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
 								'MozTransform' in document.body.style ||
@@ -58,7 +56,7 @@ var zoom = (function(){
 		if( level !== 1 && event.keyCode === 27 ) {
 			zoom.out();
 		}
-	}, false );
+	} );
 
 	// Monitor mouse movement for panning
 	document.addEventListener( 'mousemove', function( event ) {
@@ -66,38 +64,56 @@ var zoom = (function(){
 			mouseX = event.clientX;
 			mouseY = event.clientY;
 		}
-	}, false );
+	} );
 
 	/**
-	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * Applies the CSS required to zoom in, prefers the use of CSS3
 	 * transforms but falls back on zoom for IE.
 	 *
-	 * @param {Number} pageOffsetX
-	 * @param {Number} pageOffsetY
-	 * @param {Number} elementOffsetX
-	 * @param {Number} elementOffsetY
+	 * @param {Object} rect
 	 * @param {Number} scale
 	 */
-	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+	function magnify( rect, scale ) {
+
+		var scrollOffset = getScrollOffset();
+
+		// Ensure a width/height is set
+		rect.width = rect.width || 1;
+		rect.height = rect.height || 1;
+
+		// Center the rect within the zoomed viewport
+		rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
+		rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
 
 		if( supportsTransforms ) {
-			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
-				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
-
-			document.body.style.transformOrigin = origin;
-			document.body.style.OTransformOrigin = origin;
-			document.body.style.msTransformOrigin = origin;
-			document.body.style.MozTransformOrigin = origin;
-			document.body.style.WebkitTransformOrigin = origin;
-
-			document.body.style.transform = transform;
-			document.body.style.OTransform = transform;
-			document.body.style.msTransform = transform;
-			document.body.style.MozTransform = transform;
-			document.body.style.WebkitTransform = transform;
+			// Reset
+			if( scale === 1 ) {
+				document.body.style.transform = '';
+				document.body.style.OTransform = '';
+				document.body.style.msTransform = '';
+				document.body.style.MozTransform = '';
+				document.body.style.WebkitTransform = '';
+			}
+			// Scale
+			else {
+				var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
+					transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
+
+				document.body.style.transformOrigin = origin;
+				document.body.style.OTransformOrigin = origin;
+				document.body.style.msTransformOrigin = origin;
+				document.body.style.MozTransformOrigin = origin;
+				document.body.style.WebkitTransformOrigin = origin;
+
+				document.body.style.transform = transform;
+				document.body.style.OTransform = transform;
+				document.body.style.msTransform = transform;
+				document.body.style.MozTransform = transform;
+				document.body.style.WebkitTransform = transform;
+			}
 		}
 		else {
-			// Reset all values
+			// Reset
 			if( scale === 1 ) {
 				document.body.style.position = '';
 				document.body.style.left = '';
@@ -106,11 +122,11 @@ var zoom = (function(){
 				document.body.style.height = '';
 				document.body.style.zoom = '';
 			}
-			// Apply scale
+			// Scale
 			else {
 				document.body.style.position = 'relative';
-				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
-				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
+				document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
 				document.body.style.width = ( scale * 100 ) + '%';
 				document.body.style.height = ( scale * 100 ) + '%';
 				document.body.style.zoom = scale;
@@ -119,11 +135,13 @@ var zoom = (function(){
 
 		level = scale;
 
-		if( level !== 1 && document.documentElement.classList ) {
-			document.documentElement.classList.add( 'zoomed' );
-		}
-		else {
-			document.documentElement.classList.remove( 'zoomed' );
+		if( document.documentElement.classList ) {
+			if( level !== 1 ) {
+				document.documentElement.classList.add( 'zoomed' );
+			}
+			else {
+				document.documentElement.classList.remove( 'zoomed' );
+			}
 		}
 	}
 
@@ -159,7 +177,7 @@ var zoom = (function(){
 	function getScrollOffset() {
 		return {
 			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
-			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+			y: window.scrollY !== undefined ? window.scrollY : window.pageYOffset
 		}
 	}
 
@@ -175,6 +193,7 @@ var zoom = (function(){
 		 *   - scale: can be used instead of width/height to explicitly set scale
 		 */
 		to: function( options ) {
+
 			// Due to an implementation limitation we can't zoom in
 			// to another element without zooming out first
 			if( level !== 1 ) {
@@ -188,11 +207,12 @@ var zoom = (function(){
 				if( !!options.element ) {
 					// Space around the zoomed in element to leave on screen
 					var padding = 20;
+					var bounds = options.element.getBoundingClientRect();
 
-					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
-					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
-					options.x = options.element.getBoundingClientRect().left - padding;
-					options.y = options.element.getBoundingClientRect().top - padding;
+					options.x = bounds.left - padding;
+					options.y = bounds.top - padding;
+					options.width = bounds.width + ( padding * 2 );
+					options.height = bounds.height + ( padding * 2 );
 				}
 
 				// If width/height values are set, calculate scale from those values
@@ -204,13 +224,7 @@ var zoom = (function(){
 					options.x *= options.scale;
 					options.y *= options.scale;
 
-					var scrollOffset = getScrollOffset();
-
-					if( options.element ) {
-						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
-					}
-
-					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+					magnify( options, options.scale );
 
 					if( options.pan !== false ) {
 
@@ -222,8 +236,6 @@ var zoom = (function(){
 
 					}
 				}
-
-				currentOptions = options;
 			}
 		},
 
@@ -234,13 +246,7 @@ var zoom = (function(){
 			clearTimeout( panEngageTimeout );
 			clearInterval( panUpdateInterval );
 
-			var scrollOffset = getScrollOffset();
-
-			if( currentOptions && currentOptions.element ) {
-				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
-			}
-
-			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+			magnify( { x: 0, y: 0 }, 1 );
 
 			level = 1;
 		},
@@ -256,3 +262,5 @@ var zoom = (function(){
 
 })();
 
+
+

+ 2 - 2
test/examples/barebones.html

@@ -6,7 +6,7 @@
 
 		<title>reveal.js - Barebones</title>
 
-		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/reveal.css">
 	</head>
 
 	<body>
@@ -29,7 +29,7 @@
 
 		</div>
 
-		<script src="../../js/reveal.min.js"></script>
+		<script src="../../js/reveal.js"></script>
 
 		<script>
 

+ 2 - 2
test/examples/embedded-media.html

@@ -8,7 +8,7 @@
 
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 
-		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/reveal.css">
 		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
 	</head>
 
@@ -35,7 +35,7 @@
 		</div>
 
 		<script src="../../lib/js/head.min.js"></script>
-		<script src="../../js/reveal.min.js"></script>
+		<script src="../../js/reveal.js"></script>
 
 		<script>
 

+ 2 - 2
test/examples/math.html

@@ -8,7 +8,7 @@
 
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 
-		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/reveal.css">
 		<link rel="stylesheet" href="../../css/theme/night.css" id="theme">
 	</head>
 
@@ -160,7 +160,7 @@
 		</div>
 
 		<script src="../../lib/js/head.min.js"></script>
-		<script src="../../js/reveal.min.js"></script>
+		<script src="../../js/reveal.js"></script>
 
 		<script>
 

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

@@ -8,7 +8,7 @@
 
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 
-		<link rel="stylesheet" href="../../css/reveal.min.css">
+		<link rel="stylesheet" href="../../css/reveal.css">
 		<link rel="stylesheet" href="../../css/theme/serif.css" id="theme">
 	</head>
 
@@ -101,7 +101,7 @@
 		</div>
 
 		<script src="../../lib/js/head.min.js"></script>
-		<script src="../../js/reveal.min.js"></script>
+		<script src="../../js/reveal.js"></script>
 
 		<script>
 

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

@@ -6,7 +6,7 @@
 
 		<title>reveal.js - Test Markdown Element Attributes</title>
 
-		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="../css/reveal.css">
 		<link rel="stylesheet" href="qunit-1.12.0.css">
 	</head>
 
@@ -19,10 +19,10 @@
 
 			<div class="slides">
 
-				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section> -->
 
 				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
-				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$" data-element-attributes="{_\s*?([^}]+?)}">>
+				<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$" data-element-attributes="{_\s*?([^}]+?)}">>
 					<script type="text/template">
 						## Slide 1.1
 						<!-- {_class="fragment fade-out" data-fragment-index="1"} -->
@@ -75,8 +75,8 @@
 
 
 				<section 	data-markdown data-separator="^\n\n\n"
-									data-vertical="^\n\n"
-									data-notes="^Note:"
+									data-separator-vertical="^\n\n"
+									data-separator-notes="^Note:"
 									data-charset="utf-8">
 					<script type="text/template">
 						# Test attributes in Markdown with default separator
@@ -123,7 +123,7 @@
 		</div>
 
 		<script src="../lib/js/head.min.js"></script>
-		<script src="../js/reveal.min.js"></script>
+		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
 		<script src="qunit-1.12.0.js"></script>

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

@@ -6,7 +6,7 @@
 
 		<title>reveal.js - Test Markdown Attributes</title>
 
-		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="../css/reveal.css">
 		<link rel="stylesheet" href="qunit-1.12.0.css">
 	</head>
 
@@ -19,12 +19,12 @@
 
 			<div class="slides">
 
-				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section> -->
 
 				<!-- Slides are separated by three lines, vertical slides by two lines, attributes are one any line starting with (spaces and) two dashes -->
 				<section 	data-markdown data-separator="^\n\n\n"
-									data-vertical="^\n\n"
-									data-notes="^Note:"
+									data-separator-vertical="^\n\n"
+									data-separator-notes="^Note:"
 									data-attributes="--\s(.*?)$"
 									data-charset="utf-8">
 					<script type="text/template">
@@ -56,8 +56,8 @@
 				</section>
 
 				<section 	data-markdown data-separator="^\n\n\n"
-									data-vertical="^\n\n"
-									data-notes="^Note:"
+									data-separator-vertical="^\n\n"
+									data-separator-notes="^Note:"
 									data-charset="utf-8">
 					<script type="text/template">
 						# Test attributes in Markdown with default separator
@@ -117,7 +117,7 @@
 		</div>
 
 		<script src="../lib/js/head.min.js"></script>
-		<script src="../js/reveal.min.js"></script>
+		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
 		<script src="qunit-1.12.0.js"></script>

+ 4 - 4
test/test-markdown.html

@@ -6,7 +6,7 @@
 
 		<title>reveal.js - Test Markdown</title>
 
-		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="../css/reveal.css">
 		<link rel="stylesheet" href="qunit-1.12.0.css">
 	</head>
 
@@ -19,10 +19,10 @@
 
 			<div class="slides">
 
-				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section> -->
+				<!-- <section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section> -->
 
 				<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
-				<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+				<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
 					<script type="text/template">
 						## Slide 1.1
 
@@ -41,7 +41,7 @@
 		</div>
 
 		<script src="../lib/js/head.min.js"></script>
-		<script src="../js/reveal.min.js"></script>
+		<script src="../js/reveal.js"></script>
 		<script src="../plugin/markdown/marked.js"></script>
 		<script src="../plugin/markdown/markdown.js"></script>
 		<script src="qunit-1.12.0.js"></script>

+ 83 - 0
test/test-pdf.html

@@ -0,0 +1,83 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Test PDF exports</title>
+
+		<link rel="stylesheet" href="../css/reveal.css">
+		<link rel="stylesheet" href="../css/print/pdf.css">
+		<link rel="stylesheet" href="qunit-1.12.0.css">
+	</head>
+
+	<body style="overflow: auto;">
+
+		<div id="qunit"></div>
+  		<div id="qunit-fixture"></div>
+
+		<div class="reveal" style="display: none;">
+
+			<div class="slides">
+
+				<section>
+					<h1>1</h1>
+					<img data-src="fake-url.png">
+				</section>
+
+				<section>
+					<section>
+						<h1>2.1</h1>
+					</section>
+					<section>
+						<h1>2.2</h1>
+					</section>
+					<section>
+						<h1>2.3</h1>
+					</section>
+				</section>
+
+				<section id="fragment-slides">
+					<section>
+						<h1>3.1</h1>
+						<ul>
+							<li class="fragment">4.1</li>
+							<li class="fragment">4.2</li>
+							<li class="fragment">4.3</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.2</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="0">4.1</li>
+							<li class="fragment" data-fragment-index="0">4.2</li>
+						</ul>
+					</section>
+
+					<section>
+						<h1>3.3</h1>
+						<ul>
+							<li class="fragment" data-fragment-index="1">3.3.1</li>
+							<li class="fragment" data-fragment-index="4">3.3.2</li>
+							<li class="fragment" data-fragment-index="4">3.3.3</li>
+						</ul>
+					</section>
+				</section>
+
+				<section>
+					<h1>4</h1>
+				</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-pdf.js"></script>
+
+	</body>
+</html>

+ 15 - 0
test/test-pdf.js

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

+ 5 - 4
test/test.html

@@ -6,7 +6,7 @@
 
 		<title>reveal.js - Tests</title>
 
-		<link rel="stylesheet" href="../css/reveal.min.css">
+		<link rel="stylesheet" href="../css/reveal.css">
 		<link rel="stylesheet" href="qunit-1.12.0.css">
 	</head>
 
@@ -19,12 +19,13 @@
 
 			<div class="slides">
 
-				<section>
+				<section data-background-image="examples/assets/image1.png">
 					<h1>1</h1>
+					<img data-src="fake-url.png">
 				</section>
 
 				<section>
-					<section>
+					<section data-background="examples/assets/image2.png">
 						<h1>2.1</h1>
 					</section>
 					<section>
@@ -72,7 +73,7 @@
 		</div>
 
 		<script src="../lib/js/head.min.js"></script>
-		<script src="../js/reveal.min.js"></script>
+		<script src="../js/reveal.js"></script>
 		<script src="qunit-1.12.0.js"></script>
 
 		<script src="test.js"></script>

+ 136 - 9
test/test.js

@@ -68,6 +68,12 @@ Reveal.addEventListener( 'ready', function() {
 		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
 	});
 
+	test( 'Reveal.isFirstSlide after vertical slide', function() {
+		Reveal.slide( 1, 1 );
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.isFirstSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( 0, 0 )' );
+	});
+
 	test( 'Reveal.isLastSlide', function() {
 		Reveal.slide( 0, 0 );
 		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
@@ -75,34 +81,62 @@ Reveal.addEventListener( 'ready', function() {
 		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
 
 		Reveal.slide( lastSlideIndex, 0 );
-		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( ', 0+ lastSlideIndex +' )' );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( '+ lastSlideIndex +', 0 )' );
 
 		Reveal.slide( 0, 0 );
 		strictEqual( Reveal.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
 	});
 
+	test( 'Reveal.isLastSlide after vertical slide', function() {
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+		
+		Reveal.slide( 1, 1 );
+		Reveal.slide( lastSlideIndex );
+		strictEqual( Reveal.isLastSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( '+ lastSlideIndex +', 0 )' );
+	});
+
+	test( 'Reveal.getTotalSlides', function() {
+		strictEqual( Reveal.getTotalSlides(), 8, 'eight slides in total' );
+	});
+
 	test( 'Reveal.getIndices', function() {
 		var indices = Reveal.getIndices();
 
-		ok( typeof indices.hasOwnProperty( 'h' ), 'h exists' );
-		ok( typeof indices.hasOwnProperty( 'v' ), 'v exists' );
-		ok( typeof indices.hasOwnProperty( 'f' ), 'f exists' );
+		ok( indices.hasOwnProperty( 'h' ), 'h exists' );
+		ok( indices.hasOwnProperty( 'v' ), 'v exists' );
+		ok( indices.hasOwnProperty( 'f' ), 'f exists' );
 
 		Reveal.slide( 1, 0 );
-		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 0, 'h 1, v 0' );
+		strictEqual( Reveal.getIndices().h, 1, 'h 1' );
+		strictEqual( Reveal.getIndices().v, 0, 'v 0' );
 
 		Reveal.slide( 1, 2 );
-		ok( Reveal.getIndices().h === 1 && Reveal.getIndices().v === 2, 'h 1, v 2' );
+		strictEqual( Reveal.getIndices().h, 1, 'h 1' );
+		strictEqual( Reveal.getIndices().v, 2, 'v 2' );
 
 		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.getIndices().h, 0, 'h 0' );
+		strictEqual( Reveal.getIndices().v, 0, 'v 0' );
 	});
 
 	test( 'Reveal.getSlide', function() {
-		var firstSlide = document.querySelector( '.reveal .slides>section:first-child' );
+		equal( Reveal.getSlide( 0 ), document.querySelector( '.reveal .slides>section:first-child' ), 'gets correct first slide' );
+		equal( Reveal.getSlide( 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)' ), 'no v index returns stack' );
+		equal( Reveal.getSlide( 1, 0 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(1)' ), 'v index 0 returns first vertical child' );
+		equal( Reveal.getSlide( 1, 1 ), document.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(2)' ), 'v index 1 returns second vertical child' );
+
+		strictEqual( Reveal.getSlide( 100 ), undefined, 'undefined when out of horizontal bounds' );
+		strictEqual( Reveal.getSlide( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
+	});
 
-		equal( Reveal.getSlide( 0 ), firstSlide, 'gets correct first slide' );
+	test( 'Reveal.getSlideBackground', function() {
+		equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' );
+		equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' );
+		equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(1)' ), 'v index 0 returns first vertical child' );
+		equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 1 returns second vertical child' );
 
-		strictEqual( Reveal.getSlide( 100 ), undefined, 'returns undefined when slide can\'t be found' );
+		strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' );
+		strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
 	});
 
 	test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
@@ -116,6 +150,16 @@ Reveal.addEventListener( 'ready', function() {
 		equal( Reveal.getCurrentSlide(), secondSlide, 'current is slide #1' );
 	});
 
+	test( 'Reveal.getProgress', function() {
+		Reveal.slide( 0, 0 );
+		strictEqual( Reveal.getProgress(), 0, 'progress is 0 on first slide' );
+
+		var lastSlideIndex = document.querySelectorAll( '.reveal .slides>section' ).length - 1;
+
+		Reveal.slide( lastSlideIndex, 0 );
+		strictEqual( Reveal.getProgress(), 1, 'progress is 1 on last slide' );
+	});
+
 	test( 'Reveal.getScale', function() {
 		ok( typeof Reveal.getScale() === 'number', 'has scale' );
 	});
@@ -332,6 +376,70 @@ Reveal.addEventListener( 'ready', function() {
 
 
 	// ---------------------------------------------------------------
+	// AUTO-SLIDE TESTS
+
+	QUnit.module( 'Auto Sliding' );
+
+	test( 'Reveal.isAutoSliding', function() {
+		strictEqual( Reveal.isAutoSliding(), false, 'false by default' );
+
+		Reveal.configure({ autoSlide: 10000 });
+		strictEqual( Reveal.isAutoSliding(), true, 'true after starting' );
+
+		Reveal.configure({ autoSlide: 0 });
+		strictEqual( Reveal.isAutoSliding(), false, 'false after setting to 0' );
+	});
+
+	test( 'Reveal.toggleAutoSlide', function() {
+		Reveal.configure({ autoSlide: 10000 });
+
+		Reveal.toggleAutoSlide();
+		strictEqual( Reveal.isAutoSliding(), false, 'false after first toggle' );
+		Reveal.toggleAutoSlide();
+		strictEqual( Reveal.isAutoSliding(), true, 'true after second toggle' );
+
+		Reveal.configure({ autoSlide: 0 });
+	});
+
+	asyncTest( 'autoslidepaused', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'autoslidepaused', _onEvent );
+		Reveal.configure({ autoSlide: 10000 });
+		Reveal.toggleAutoSlide();
+
+		start();
+
+		// cleanup
+		Reveal.configure({ autoSlide: 0 });
+		Reveal.removeEventListener( 'autoslidepaused', _onEvent );
+	});
+
+	asyncTest( 'autoslideresumed', function() {
+		expect( 1 );
+
+		var _onEvent = function( event ) {
+			ok( true, 'event fired' );
+		}
+
+		Reveal.addEventListener( 'autoslideresumed', _onEvent );
+		Reveal.configure({ autoSlide: 10000 });
+		Reveal.toggleAutoSlide();
+		Reveal.toggleAutoSlide();
+
+		start();
+
+		// cleanup
+		Reveal.configure({ autoSlide: 0 });
+		Reveal.removeEventListener( 'autoslideresumed', _onEvent );
+	});
+
+
+	// ---------------------------------------------------------------
 	// CONFIGURATION VALUES
 
 	QUnit.module( 'Configuration' );
@@ -372,6 +480,25 @@ Reveal.addEventListener( 'ready', function() {
 
 
 	// ---------------------------------------------------------------
+	// LAZY-LOADING TESTS
+
+	QUnit.module( 'Lazy-Loading' );
+
+	test( 'img with data-src', function() {
+		strictEqual( document.querySelectorAll( '.reveal section img[src]' ).length, 1, 'Image source has been set' );
+	});
+
+	test( 'background images', function() {
+		var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' );
+		var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
+
+		// check that the images are applied to the background elements
+		ok( Reveal.getSlideBackground( 0 ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' );
+		ok( Reveal.getSlideBackground( 1, 0 ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
+	});
+
+
+	// ---------------------------------------------------------------
 	// EVENT TESTS
 
 	QUnit.module( 'Events' );

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio