aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gruntfile.js11
-rw-r--r--LICENSE2
-rw-r--r--README.md42
-rw-r--r--css/reveal.css34
-rw-r--r--css/reveal.scss31
-rw-r--r--index.html7
-rw-r--r--js/reveal.js209
-rw-r--r--package.json15
-rwxr-xr-xplugin/markdown/markdown.js3
-rw-r--r--plugin/notes/notes.js29
-rw-r--r--plugin/print-pdf/print-pdf.js38
11 files changed, 282 insertions, 139 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index 96a4f52..aa04b68 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -15,7 +15,7 @@ module.exports = function(grunt) {
' * http://lab.hakim.se/reveal-js\n' +
' * MIT licensed\n' +
' *\n' +
- ' * Copyright (C) 2016 Hakim El Hattab, http://hakim.se\n' +
+ ' * Copyright (C) 2017 Hakim El Hattab, http://hakim.se\n' +
' */'
},
@@ -44,7 +44,7 @@ module.exports = function(grunt) {
{
expand: true,
cwd: 'css/theme/source',
- src: ['*.scss'],
+ src: ['*.sass', '*.scss'],
dest: 'css/theme',
ext: '.css'
}
@@ -122,7 +122,12 @@ module.exports = function(grunt) {
tasks: 'js'
},
theme: {
- files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
+ files: [
+ 'css/theme/source/*.sass',
+ 'css/theme/source/*.scss',
+ 'css/theme/template/*.sass',
+ 'css/theme/template/*.scss'
+ ],
tasks: 'css-themes'
},
css: {
diff --git a/LICENSE b/LICENSE
index 924cd89..c3e6e5f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2016 Hakim El Hattab, http://hakim.se, and reveal.js contributors
+Copyright (C) 2017 Hakim El Hattab, http://hakim.se, and reveal.js contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 9a76b93..e711dd0 100644
--- a/README.md
+++ b/README.md
@@ -105,17 +105,17 @@ The presentation markup hierarchy needs to be `.reveal > .slides > section` wher
### Markdown
-It's possible to write your slides using Markdown. To enable Markdown, add the `data-markdown` attribute to your `<section>` elements and wrap the contents in a `<script type="text/template">` like the example below.
+It's possible to write your slides using Markdown. To enable Markdown, add the `data-markdown` attribute to your `<section>` elements and wrap the contents in a `<textarea data-template>` like the example below.
This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) modified to use [marked](https://github.com/chjj/marked) to support [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown). Sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks).
```html
<section data-markdown>
- <script type="text/template">
+ <textarea data-template>
## Page title
A paragraph with some text and a [link](http://hakim.se).
- </script>
+ </textarea>
</section>
```
@@ -270,7 +270,10 @@ Reveal.initialize({
// - Calculated automatically unless specified
// - Set to 0 to disable movement along an axis
parallaxBackgroundHorizontal: null,
- parallaxBackgroundVertical: null
+ parallaxBackgroundVertical: null,
+
+ // The display mode that will be used to show slides
+ display: 'block'
});
```
@@ -463,14 +466,15 @@ Reveal.nextFragment();
// Randomize the order of slides
Reveal.shuffle();
-// Shows a help overlay with keyboard shortcuts
-Reveal.showHelp();
-
// Toggle presentation states, optionally pass true/false to force on/off
Reveal.toggleOverview();
Reveal.togglePause();
Reveal.toggleAutoSlide();
+// Shows a help overlay with keyboard shortcuts, optionally pass true/false
+// to force on/off
+Reveal.toggleHelp();
+
// Change a config value at runtime
Reveal.configure({ controls: true });
@@ -578,6 +582,7 @@ Automatically plays a full size video behind the slide.
| data-background-video | | A single video source, or a comma separated list of video sources. |
| data-background-video-loop | false | Flags if the video should play repeatedly. |
| data-background-video-muted | false | Flags if the audio should be muted. |
+| data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. |
```html
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-video-loop data-background-video-muted>
@@ -870,12 +875,13 @@ To enable the PDF print capability in your presentation, the special print style
### Instructions
1. Open your presentation with `print-pdf` included in the query string i.e. http://localhost:8000/?print-pdf. 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 (CTRL/CMD+P).
-3. Change the **Destination** setting to **Save as PDF**.
-4. Change the **Layout** to **Landscape**.
-5. Change the **Margins** to **None**.
-6. Enable the **Background graphics** option.
-7. Click **Save**.
+ * If you want to include [speaker notes](#speaker-notes) in your export, you can append `showNotes=true` to the query string: http://localhost:8000/?print-pdf&showNotes=true
+1. Open the in-browser print dialog (CTRL/CMD+P).
+1. Change the **Destination** setting to **Save as PDF**.
+1. Change the **Layout** to **Landscape**.
+1. Change the **Margins** to **None**.
+1. Enable the **Background graphics** option.
+1. Click **Save**.
![Chrome Print Settings](https://s3.amazonaws.com/hakim-static/reveal-js/pdf-print-settings-2.png)
@@ -944,7 +950,7 @@ This will only display in the notes window.
Notes are only visible to the speaker inside of the speaker view. If you wish to share your notes with others you can initialize reveal.js with the `showNotes` config value set to `true`. Notes will appear along the bottom of the presentations.
-When `showNotes` is enabled notes are also included when you [export to PDF](https://github.com/hakimel/reveal.js#pdf-export). By default, notes are printed in a semi-transparent box on top of slide. If you'd rather print them on a separate page after the slide, set `showNotes: "separate-page"`.
+When `showNotes` is enabled notes are also included when you [export to PDF](https://github.com/hakimel/reveal.js#pdf-export). By default, notes are printed in a semi-transparent box on top of the slide. If you'd rather print them on a separate page after the slide, set `showNotes: "separate-page"`.
## Server Side Speaker Notes
@@ -1046,11 +1052,13 @@ Server that receives the slideChanged events from the master presentation and br
1. ```npm install```
2. ```node plugin/multiplex```
-Or you use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/).
+Or you can use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/).
You'll need to generate a unique secret and token pair for your master and client presentations. To do so, visit ```http://example.com/token```, where ```http://example.com``` is the location of your socket.io server. Or if you're going to use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), visit [https://reveal-js-multiplex-ccjbegmaii.now.sh/token](https://reveal-js-multiplex-ccjbegmaii.now.sh/token).
-You are very welcome to point your presentations at the Socket.io server running at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), but availability and stability are not guaranteed. For anything mission critical I recommend you run your own server. It is simple to deploy to nodejitsu, heroku, your own environment, etc.
+You are very welcome to point your presentations at the Socket.io server running at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), but availability and stability are not guaranteed.
+
+For anything mission critical I recommend you run your own server. The easiest way to do this is by installing [now](https://zeit.co/now). With that installed, deploying your own Multiplex server is as easy running the following command from the reveal.js folder: `now plugin/multiplex`.
##### socket.io server as file static server
@@ -1187,4 +1195,4 @@ Some reveal.js features, like external Markdown and speaker notes, require that
MIT licensed
-Copyright (C) 2016 Hakim El Hattab, http://hakim.se
+Copyright (C) 2017 Hakim El Hattab, http://hakim.se
diff --git a/css/reveal.css b/css/reveal.css
index 430dcde..f675977 100644
--- a/css/reveal.css
+++ b/css/reveal.css
@@ -3,7 +3,7 @@
* http://lab.hakim.se/reveal-js
* MIT licensed
*
- * Copyright (C) 2016 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
*/
/*********************************************
* RESET STYLES
@@ -323,6 +323,7 @@ body {
bottom: 0;
left: 0;
margin: auto;
+ pointer-events: none;
overflow: visible;
z-index: 1;
text-align: center;
@@ -340,6 +341,7 @@ body {
position: absolute;
width: 100%;
padding: 20px 0px;
+ pointer-events: auto;
z-index: 10;
-webkit-transform-style: flat;
transform-style: flat;
@@ -374,6 +376,10 @@ body {
z-index: 11;
opacity: 1; }
+.reveal .slides > section:empty,
+.reveal .slides > section > section:empty {
+ pointer-events: none; }
+
.reveal.center,
.reveal.center .slides,
.reveal.center .slides section {
@@ -589,6 +595,10 @@ body {
/*********************************************
* CUBE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
*********************************************/
.reveal.cube .slides {
-webkit-perspective: 1300px;
@@ -664,6 +674,10 @@ body {
/*********************************************
* PAGE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
*********************************************/
.reveal.page .slides {
-webkit-perspective-origin: 0% 50%;
@@ -839,6 +853,7 @@ body {
height: 100%;
opacity: 0;
visibility: hidden;
+ overflow: hidden;
background-color: transparent;
background-position: 50% 50%;
background-repeat: no-repeat;
@@ -851,7 +866,8 @@ body {
.reveal .slide-background.present {
opacity: 1;
- visibility: visible; }
+ visibility: visible;
+ z-index: 2; }
.print-pdf .reveal .slide-background {
opacity: 1 !important;
@@ -865,7 +881,13 @@ body {
max-width: none;
max-height: none;
top: 0;
- left: 0; }
+ left: 0;
+ -o-object-fit: cover;
+ object-fit: cover; }
+
+.reveal .slide-background[data-background-size="contain"] video {
+ -o-object-fit: contain;
+ object-fit: contain; }
/* Immediate transition style */
.reveal[data-background-transition=none] > .backgrounds .slide-background,
@@ -1037,6 +1059,8 @@ body {
visibility: visible;
outline: 10px solid rgba(150, 150, 150, 0.1);
outline-offset: 10px; }
+ .reveal.overview .backgrounds .slide-background.stack {
+ overflow: visible; }
.reveal.overview .slides section,
.reveal.overview-deactivating .slides section {
@@ -1048,10 +1072,6 @@ body {
-webkit-transition: none;
transition: none; }
-.reveal.overview-animated .slides {
- -webkit-transition: -webkit-transform 0.4s ease;
- transition: transform 0.4s ease; }
-
/*********************************************
* RTL SUPPORT
*********************************************/
diff --git a/css/reveal.scss b/css/reveal.scss
index 22fb3fe..fba248e 100644
--- a/css/reveal.scss
+++ b/css/reveal.scss
@@ -3,7 +3,7 @@
* http://lab.hakim.se/reveal-js
* MIT licensed
*
- * Copyright (C) 2016 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
*/
@@ -388,6 +388,7 @@ body {
bottom: 0;
left: 0;
margin: auto;
+ pointer-events: none;
overflow: visible;
z-index: 1;
@@ -406,6 +407,7 @@ body {
position: absolute;
width: 100%;
padding: 20px 0px;
+ pointer-events: auto;
z-index: 10;
transform-style: flat;
@@ -443,6 +445,11 @@ body {
opacity: 1;
}
+.reveal .slides>section:empty,
+.reveal .slides>section>section:empty {
+ pointer-events: none;
+}
+
.reveal.center,
.reveal.center .slides,
.reveal.center .slides section {
@@ -610,6 +617,10 @@ body {
/*********************************************
* CUBE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
*********************************************/
.reveal.cube .slides {
@@ -682,6 +693,10 @@ body {
/*********************************************
* PAGE TRANSITION
+ *
+ * WARNING:
+ * this is deprecated and will be removed in a
+ * future version.
*********************************************/
.reveal.page .slides {
@@ -866,6 +881,7 @@ body {
height: 100%;
opacity: 0;
visibility: hidden;
+ overflow: hidden;
background-color: rgba( 0, 0, 0, 0 );
background-position: 50% 50%;
@@ -882,6 +898,7 @@ body {
.reveal .slide-background.present {
opacity: 1;
visibility: visible;
+ z-index: 2;
}
.print-pdf .reveal .slide-background {
@@ -898,7 +915,11 @@ body {
max-height: none;
top: 0;
left: 0;
+ object-fit: cover;
}
+ .reveal .slide-background[data-background-size="contain"] video {
+ object-fit: contain;
+ }
/* Immediate transition style */
.reveal[data-background-transition=none]>.backgrounds .slide-background,
@@ -1080,6 +1101,10 @@ body {
outline: 10px solid rgba(150,150,150,0.1);
outline-offset: 10px;
}
+
+ .backgrounds .slide-background.stack {
+ overflow: visible;
+ }
}
// Disable transitions transitions while we're activating
@@ -1094,10 +1119,6 @@ body {
transition: none;
}
-.reveal.overview-animated .slides {
- transition: transform 0.4s ease;
-}
-
/*********************************************
* RTL SUPPORT
diff --git a/index.html b/index.html
index 0c7a672..98accc3 100644
--- a/index.html
+++ b/index.html
@@ -33,11 +33,10 @@
<script src="js/reveal.js"></script>
<script>
- // More info https://github.com/hakimel/reveal.js#configuration
+ // More info about config & dependencies:
+ // - https://github.com/hakimel/reveal.js#configuration
+ // - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
- history: true,
-
- // More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
diff --git a/js/reveal.js b/js/reveal.js
index 574c943..b48620b 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -3,7 +3,7 @@
* http://lab.hakim.se/reveal-js
* MIT licensed
*
- * Copyright (C) 2016 Hakim El Hattab, http://hakim.se
+ * Copyright (C) 2017 Hakim El Hattab, http://hakim.se
*/
(function( root, factory ) {
if( typeof define === 'function' && define.amd ) {
@@ -163,6 +163,9 @@
// Number of slides away from the current that are visible
viewDistance: 3,
+ // The display mode that will be used to show slides
+ display: 'block',
+
// Script dependencies to load
dependencies: []
@@ -862,7 +865,7 @@
if( data.background ) {
// Auto-wrap image urls in url(...)
- if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
+ if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#]|$)/gi.test( data.background ) ) {
slide.setAttribute( 'data-background-image', data.background );
}
else {
@@ -887,6 +890,7 @@
// Additional and optional background properties
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
+ if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
@@ -1044,10 +1048,11 @@
// Iframe link previews
if( config.previewLinks ) {
enablePreviewLinks();
+ disablePreviewLinks( '[data-preview-link=false]' );
}
else {
disablePreviewLinks();
- enablePreviewLinks( '[data-preview-link]' );
+ enablePreviewLinks( '[data-preview-link]:not([data-preview-link=false])' );
}
// Remove existing auto-slide controls
@@ -1239,7 +1244,7 @@
if( value === 'null' ) return null;
else if( value === 'true' ) return true;
else if( value === 'false' ) return false;
- else if( value.match( /^\d+$/ ) ) return parseFloat( value );
+ else if( value.match( /^[\d\.]+$/ ) ) return parseFloat( value );
}
return value;
@@ -1583,9 +1588,9 @@
/**
* Unbind preview frame links.
*/
- function disablePreviewLinks() {
+ function disablePreviewLinks( selector ) {
- var anchors = toArray( document.querySelectorAll( 'a' ) );
+ var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) );
anchors.forEach( function( element ) {
if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) {
@@ -1643,6 +1648,28 @@
}
/**
+ * Open or close help overlay window.
+ *
+ * @param {Boolean} [override] Flag which overrides the
+ * toggle logic and forcibly sets the desired state. True means
+ * help is open, false means it's closed.
+ */
+ function toggleHelp( override ){
+
+ if( typeof override === 'boolean' ) {
+ override ? showHelp() : closeOverlay();
+ }
+ else {
+ if( dom.overlay ) {
+ closeOverlay();
+ }
+ else {
+ showHelp();
+ }
+ }
+ }
+
+ /**
* Opens an overlay window with help material.
*/
function showHelp() {
@@ -1784,6 +1811,10 @@
updateProgress();
updateParallax();
+ if( isOverview() ) {
+ updateOverview();
+ }
+
}
}
@@ -1999,11 +2030,14 @@
*/
function updateOverview() {
+ var vmin = Math.min( window.innerWidth, window.innerHeight );
+ var scale = Math.max( vmin / 5, 150 ) / vmin;
+
transformSlides( {
overview: [
+ 'scale('+ scale +')',
'translateX('+ ( -indexh * overviewSlideWidth ) +'px)',
- 'translateY('+ ( -indexv * overviewSlideHeight ) +'px)',
- 'translateZ('+ ( window.innerWidth < 400 ? -1000 : -2500 ) +'px)'
+ 'translateY('+ ( -indexv * overviewSlideHeight ) +'px)'
].join( ' ' )
} );
@@ -2409,9 +2443,9 @@
updateControls();
updateProgress();
- updateBackground( true );
updateSlideNumber();
updateSlidesVisibility();
+ updateBackground( true );
updateNotes();
formatEmbeddedContent();
@@ -2887,34 +2921,17 @@
} );
- // Stop any currently playing video background
+ // Stop content inside of previous backgrounds
if( previousBackground ) {
- var previousVideo = previousBackground.querySelector( 'video' );
- if( previousVideo ) previousVideo.pause();
+ stopEmbeddedContent( previousBackground );
}
+ // Start content in the current background
if( currentBackground ) {
- // Start video playback
- var currentVideo = currentBackground.querySelector( 'video' );
- if( currentVideo ) {
-
- var startVideo = function() {
- currentVideo.currentTime = 0;
- currentVideo.play();
- currentVideo.removeEventListener( 'loadeddata', startVideo );
- };
-
- if( currentVideo.readyState > 1 ) {
- startVideo();
- }
- else {
- currentVideo.addEventListener( 'loadeddata', startVideo );
- }
-
- }
+ startEmbeddedContent( currentBackground );
var backgroundImageURL = currentBackground.style.backgroundImage || '';
@@ -3023,7 +3040,7 @@
function showSlide( slide ) {
// Show the slide element
- slide.style.display = 'block';
+ slide.style.display = config.display;
// Media elements with data-src attributes
toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src]' ) ).forEach( function( element ) {
@@ -3091,11 +3108,20 @@
// Iframes
else if( backgroundIframe ) {
var iframe = document.createElement( 'iframe' );
+
+ // Only load autoplaying content when the slide is shown to
+ // avoid having it play in the background
+ if( /autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {
+ iframe.setAttribute( 'data-src', backgroundIframe );
+ }
+ else {
iframe.setAttribute( 'src', backgroundIframe );
- iframe.style.width = '100%';
- iframe.style.height = '100%';
- iframe.style.maxHeight = '100%';
- iframe.style.maxWidth = '100%';
+ }
+
+ iframe.style.width = '100%';
+ iframe.style.height = '100%';
+ iframe.style.maxHeight = '100%';
+ iframe.style.maxWidth = '100%';
background.appendChild( iframe );
}
@@ -3203,11 +3229,12 @@
* Start playback of any embedded content inside of
* the given element.
*
- * @param {HTMLElement} slide
+ * @param {HTMLElement} element
*/
function startEmbeddedContent( element ) {
if( element && !isSpeakerNotes() ) {
+
// Restart GIFs
toArray( element.querySelectorAll( 'img[src$=".gif"]' ) ).forEach( function( el ) {
// Setting the same unchanged source like this was confirmed
@@ -3221,8 +3248,26 @@
return;
}
- if( el.hasAttribute( 'data-autoplay' ) && typeof el.play === 'function' ) {
- el.play();
+ // Autoplay is always on for slide backgrounds
+ var autoplay = el.hasAttribute( 'data-autoplay' ) ||
+ el.hasAttribute( 'data-paused-by-reveal' ) ||
+ !!closestParent( el, '.slide-background' );
+
+ if( autoplay && typeof el.play === 'function' ) {
+
+ el.removeAttribute( 'data-paused-by-reveal' );
+
+ if( el.readyState > 1 ) {
+ startEmbeddedMedia( { target: el } );
+ }
+ else {
+ el.removeEventListener( 'loadeddata', startEmbeddedMedia ); // remove first to avoid dupes
+ el.addEventListener( 'loadeddata', startEmbeddedMedia );
+
+ // `loadeddata` never fires unless we start playing on iPad
+ if( /ipad/gi.test( UA ) ) el.play();
+ }
+
}
} );
@@ -3247,15 +3292,36 @@
el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
}
} );
+
}
}
/**
+ * Starts playing an embedded video/audio element after
+ * it has finished loading.
+ *
+ * @param {object} event
+ */
+ function startEmbeddedMedia( event ) {
+
+ var isAttachedToDOM = !!closestParent( event.target, 'html' ),
+ isVisible = !!closestParent( event.target, '.present' );
+
+ if( isAttachedToDOM && isVisible ) {
+ event.target.currentTime = 0;
+ event.target.play();
+ }
+
+ event.target.removeEventListener( 'loadeddata', startEmbeddedMedia );
+
+ }
+
+ /**
* "Starts" the content of an embedded iframe using the
* postMessage API.
*
- * @param {object} event - postMessage API event
+ * @param {object} event
*/
function startEmbeddedIframe( event ) {
@@ -3263,17 +3329,26 @@
if( iframe && iframe.contentWindow ) {
- // YouTube postMessage API
- if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && iframe.hasAttribute( 'data-autoplay' ) ) {
- iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
- }
- // Vimeo postMessage API
- else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && iframe.hasAttribute( 'data-autoplay' ) ) {
- iframe.contentWindow.postMessage( '{"method":"play"}', '*' );
- }
- // Generic postMessage API
- else {
- iframe.contentWindow.postMessage( 'slide:start', '*' );
+ var isAttachedToDOM = !!closestParent( event.target, 'html' ),
+ isVisible = !!closestParent( event.target, '.present' );
+
+ if( isAttachedToDOM && isVisible ) {
+
+ var autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closestParent( iframe, '.slide-background' );
+
+ // YouTube postMessage API
+ if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {
+ iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
+ }
+ // Vimeo postMessage API
+ else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {
+ iframe.contentWindow.postMessage( '{"method":"play"}', '*' );
+ }
+ // Generic postMessage API
+ else {
+ iframe.contentWindow.postMessage( 'slide:start', '*' );
+ }
+
}
}
@@ -3284,40 +3359,43 @@
* Stop playback of any embedded content inside of
* the targeted slide.
*
- * @param {HTMLElement} slide
+ * @param {HTMLElement} element
+ * @param {boolean} autoplay Optionally override the
+ * autoplay setting of media elements
*/
- function stopEmbeddedContent( slide ) {
+ function stopEmbeddedContent( element, autoplay ) {
- if( slide && slide.parentNode ) {
+ if( element && element.parentNode ) {
// HTML5 media elements
- toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+ toArray( element.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
+ el.setAttribute('data-paused-by-reveal', '');
el.pause();
}
} );
// Generic postMessage API for non-lazy loaded iframes
- toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+ toArray( element.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
el.contentWindow.postMessage( 'slide:stop', '*' );
el.removeEventListener( 'load', startEmbeddedIframe );
});
// YouTube postMessage API
- toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
+ toArray( element.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
}
});
// Vimeo postMessage API
- toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
+ toArray( element.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
el.contentWindow.postMessage( '{"method":"pause"}', '*' );
}
});
// Lazy loading iframes
- toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) {
+ toArray( element.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) {
// Only removing the src doesn't actually unload the frame
// in all browsers (Firefox) so we set it to blank first
el.setAttribute( 'src', 'about:blank' );
@@ -3914,7 +3992,7 @@
// If there are media elements with data-autoplay,
// automatically set the autoSlide duration to the
// length of that media. Not applicable if the slide
- // is divided up into fragments.
+ // is divided up into fragments.
// playbackRate is accounted for in the duration.
if( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {
toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
@@ -4127,12 +4205,7 @@
// Check if the pressed key is question mark
if( event.shiftKey && event.charCode === 63 ) {
- if( dom.overlay ) {
- closeOverlay();
- }
- else {
- showHelp( true );
- }
+ toggleHelp();
}
}
@@ -4830,9 +4903,6 @@
navigatePrev: navigatePrev,
navigateNext: navigateNext,
- // Shows a help overlay with keyboard shortcuts
- showHelp: showHelp,
-
// Forces an update in slide layout
layout: layout,
@@ -4845,6 +4915,9 @@
// Returns an object with the available fragments as booleans (prev/next)
availableFragments: availableFragments,
+ // Toggles a help overlay with keyboard shortcuts
+ toggleHelp: toggleHelp,
+
// Toggles the overview mode on/off
toggleOverview: toggleOverview,
diff --git a/package.json b/package.json
index 1f866ea..37ffde2 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"main": "js/reveal.js",
"scripts": {
"test": "grunt test",
- "start": "grunt serve"
+ "start": "grunt serve",
+ "build": "grunt"
},
"author": {
"name": "Hakim El Hattab",
@@ -21,15 +22,11 @@
"engines": {
"node": ">=4.0.0"
},
- "dependencies": {
- "express": "~4.14.0",
- "grunt-cli": "~1.2.0",
- "mustache": "~2.2.1",
- "socket.io": "^1.4.8"
- },
"devDependencies": {
+ "express": "~4.14.0",
"grunt": "~1.0.1",
"grunt-autoprefixer": "~3.0.3",
+ "grunt-cli": "~1.2.0",
"grunt-contrib-connect": "~0.11.2",
"grunt-contrib-cssmin": "~0.14.0",
"grunt-contrib-jshint": "~0.11.3",
@@ -39,7 +36,9 @@
"grunt-sass": "~1.2.0",
"grunt-retire": "~0.3.10",
"grunt-zip": "~0.17.1",
- "node-sass": "~3.13.0"
+ "mustache": "~2.2.1",
+ "node-sass": "~3.13.0",
+ "socket.io": "^1.4.8"
},
"license": "MIT"
}
diff --git a/plugin/markdown/markdown.js b/plugin/markdown/markdown.js
index 29aabf5..d9ff1ba 100755
--- a/plugin/markdown/markdown.js
+++ b/plugin/markdown/markdown.js
@@ -31,7 +31,8 @@
*/
function getMarkdownFromSlide( section ) {
- var template = section.querySelector( 'script' );
+ // look for a <script> or <textarea data-template> wrapper
+ var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
// strip leading whitespace so it isn't evaluated as code
var text = ( template || section ).textContent;
diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js
index 46bf5de..44efe15 100644
--- a/plugin/notes/notes.js
+++ b/plugin/notes/notes.js
@@ -50,10 +50,11 @@ var RevealNotes = (function() {
/**
* Posts the current slide data to the notes window
*/
- function post(event) {
+ function post( event ) {
var slideElement = Reveal.getCurrentSlide(),
- notesElement = slideElement.querySelector( 'aside.notes' );
+ notesElement = slideElement.querySelector( 'aside.notes' ),
+ fragmentElement = slideElement.querySelector( '.current-fragment' );
var messageData = {
namespace: 'reveal-notes',
@@ -64,21 +65,27 @@ var RevealNotes = (function() {
state: Reveal.getState()
};
- // Look for notes defined in a fragment, if it is a fragmentshown event
- if (event && event.hasOwnProperty('fragment')) {
- var innerNotes = event.fragment.querySelector( 'aside.notes' );
-
- if ( innerNotes) {
- notesElement = innerNotes;
- }
- }
-
// Look for notes defined in a slide attribute
if( slideElement.hasAttribute( 'data-notes' ) ) {
messageData.notes = slideElement.getAttribute( 'data-notes' );
messageData.whitespace = 'pre-wrap';
}
+ // Look for notes defined in a fragment
+ if( fragmentElement ) {
+ var fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
+ if( fragmentNotes ) {
+ notesElement = fragmentNotes;
+ }
+ else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
+ messageData.notes = fragmentElement.getAttribute( 'data-notes' );
+ messageData.whitespace = 'pre-wrap';
+
+ // In case there are slide notes
+ notesElement = null;
+ }
+ }
+
// Look for notes defined in an aside element
if( notesElement ) {
messageData.notes = notesElement.innerHTML;
diff --git a/plugin/print-pdf/print-pdf.js b/plugin/print-pdf/print-pdf.js
index c3c5d94..d1c3251 100644
--- a/plugin/print-pdf/print-pdf.js
+++ b/plugin/print-pdf/print-pdf.js
@@ -31,20 +31,30 @@ probePage.open( inputFile, function( status ) {
return Reveal.getConfig();
} );
- printPage.paperSize = {
- width: config.width * ( 1 + config.margin ),
- height: config.height * ( 1 + config.margin ),
- border: 0
- };
-
- printPage.open( inputFile, function( status ) {
- window.setTimeout( function() {
- console.log( 'Export PDF: Writing file [3/3]' );
- printPage.render( outputFile );
- console.log( 'Export PDF: Finished successfully!' );
- phantom.exit();
- }, 1000 );
- } );
+ if( config ) {
+
+ printPage.paperSize = {
+ width: Math.floor( config.width * ( 1 + config.margin ) ),
+ height: Math.floor( config.height * ( 1 + config.margin ) ),
+ border: 0
+ };
+
+ printPage.open( inputFile, function( status ) {
+ window.setTimeout( function() {
+ console.log( 'Export PDF: Writing file [3/3]' );
+ printPage.render( outputFile );
+ console.log( 'Export PDF: Finished successfully!' );
+ phantom.exit();
+ }, 1000 );
+ } );
+
+ }
+ else {
+
+ console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
+ phantom.exit(1);
+
+ }
} );