diff options
Diffstat (limited to 'plugin/notes')
-rw-r--r-- | plugin/notes/notes.html | 252 | ||||
-rw-r--r-- | plugin/notes/notes.js | 100 |
2 files changed, 352 insertions, 0 deletions
diff --git a/plugin/notes/notes.html b/plugin/notes/notes.html new file mode 100644 index 0000000..e14c6ac --- /dev/null +++ b/plugin/notes/notes.html @@ -0,0 +1,252 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + + <title>reveal.js - Slide Notes</title> + + <style> + body { + font-family: Helvetica; + } + + #notes { + font-size: 24px; + width: 640px; + margin-top: 5px; + } + + #wrap-current-slide { + width: 640px; + height: 512px; + float: left; + overflow: hidden; + } + + #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 { + position: absolute; + top: 3px; + left: 3px; + font-weight: bold; + font-size: 14px; + color: rgba( 255, 255, 255, 0.9 ); + } + + .error { + font-weight: bold; + color: red; + font-size: 1.5em; + text-align: center; + margin-top: 10%; + } + + .error code { + font-family: monospace; + } + + .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; + } + + .elapsed, + .clock { + color: #333; + font-size: 2em; + text-align: center; + display: inline-block; + padding: 0.5em; + background-color: #eee; + border-radius: 10px; + } + + .elapsed h2, + .clock h2 { + font-size: 0.8em; + line-height: 100%; + margin: 0; + color: #aaa; + } + + .elapsed .mute { + color: #ddd; + } + + </style> + </head> + + <body> + + <div id="wrap-current-slide" class="slides"> + <script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ window.opener.location.href +'"></iframe>' );</script> + </div> + + <div id="wrap-next-slide" class="slides"> + <script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ window.opener.location.href +'"></iframe>' );</script> + <span>UPCOMING:</span> + </div> + + <div class="time"> + <div class="clock"> + <h2>Time</h2> + <span id="clock">0:00:00 AM</span> + </div> + <div class="elapsed"> + <h2>Elapsed</h2> + <span id="hours">00</span><span id="minutes">:00</span><span id="seconds">:00</span> + </div> + </div> + + <div id="notes"></div> + + <script src="../../plugin/markdown/showdown.js"></script> + <script> + + window.addEventListener( 'load', function() { + + if( window.opener && window.opener.location && window.opener.location.href ) { + + var notes = document.getElementById( 'notes' ), + currentSlide = document.getElementById( 'current-slide' ), + nextSlide = document.getElementById( 'next-slide' ); + + window.addEventListener( 'message', function( event ) { + 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 = (new Showdown.converter()).makeHtml( data.notes ); + } + else { + notes.innerHTML = data.notes; + } + } + + // Showing and hiding fragments + if( data.fragment === 'next' ) { + currentSlide.contentWindow.Reveal.nextFragment(); + } + else if( data.fragment === 'prev' ) { + currentSlide.contentWindow.Reveal.prevFragment(); + } + else { + // Update the note slides + currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv ); + nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv ); + } + + }, 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' ); + + setInterval( function() { + + timeEl.style.opacity = 1; + + var diff, hours, minutes, seconds, + now = new Date(); + + diff = now.getTime() - start.getTime(); + hours = parseInt( diff / ( 1000 * 60 * 60 ) ); + minutes = parseInt( ( diff / ( 1000 * 60 ) ) % 60 ); + seconds = parseInt( ( diff / 1000 ) % 60 ); + + clockEl.innerHTML = now.toLocaleTimeString(); + hoursEl.innerHTML = zeroPadInteger( hours ); + hoursEl.className = hours > 0 ? "" : "mute"; + minutesEl.innerHTML = ":" + zeroPadInteger( minutes ); + minutesEl.className = minutes > 0 ? "" : "mute"; + secondsEl.innerHTML = ":" + zeroPadInteger( seconds ); + + }, 1000 ); + + // Navigate the main window when the notes slide changes + currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', function( event ) { + + window.opener.Reveal.slide( event.indexh, event.indexv ); + + } ); + + } + 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>'; + + } + + + }, false ); + + function zeroPadInteger( num ) { + var str = "00" + parseInt( num ); + return str.substring( str.length - 2 ); + } + + </script> + </body> +</html> diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js new file mode 100644 index 0000000..63de05a --- /dev/null +++ b/plugin/notes/notes.js @@ -0,0 +1,100 @@ +/** + * Handles opening of and synchronization with the reveal.js + * 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' ); + + // Fires when slide is changed + Reveal.addEventListener( 'slidechanged', function( event ) { + post('slidechanged'); + } ); + + // Fires when a fragment is shown + Reveal.addEventListener( 'fragmentshown', function( event ) { + post('fragmentshown'); + } ); + + // Fires when a fragment is hidden + Reveal.addEventListener( 'fragmenthidden', function( event ) { + post('fragmenthidden'); + } ); + + /** + * Posts the current slide data to the notes window + * + * @param {String} eventType Expecting 'slidechanged', 'fragmentshown' + * or 'fragmenthidden' set in the events above to define the needed + * slideDate. + */ + function post( eventType ) { + var slideElement = Reveal.getCurrentSlide(), + messageData; + + if( eventType === 'slidechanged' ) { + var notes = slideElement.querySelector( 'aside.notes' ), + indexh = Reveal.getIndices().h, + indexv = Reveal.getIndices().v, + nextindexh, + nextindexv; + + if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) { + nextindexh = indexh; + nextindexv = indexv + 1; + } else { + nextindexh = indexh + 1; + nextindexv = 0; + } + + messageData = { + notes : notes ? notes.innerHTML : '', + indexh : indexh, + indexv : indexv, + nextindexh : nextindexh, + nextindexv : nextindexv, + markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false + }; + } + else if( eventType === 'fragmentshown' ) { + messageData = { + fragment : 'next' + }; + } + else if( eventType === 'fragmenthidden' ) { + messageData = { + fragment : 'prev' + }; + } + + notesPopup.postMessage( JSON.stringify( messageData ), '*' ); + } + + // Navigate to the current slide when the notes are loaded + notesPopup.addEventListener( 'load', function( event ) { + post('slidechanged'); + }, false ); + } + + // If the there's a 'notes' query set, open directly + if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { + openNotes(); + } + + // Open the notes when the 's' key is hit + document.addEventListener( 'keydown', function( event ) { + // Disregard the event if the target is editable or a + // modifier is present + if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; + + if( event.keyCode === 83 ) { + event.preventDefault(); + openNotes(); + } + }, false ); + + return { open: openNotes }; +})(); |