diff options
Diffstat (limited to '')
-rw-r--r-- | public/plugin/notes-server/client.js | 60 | ||||
-rw-r--r-- | public/plugin/notes-server/index.js | 66 | ||||
-rw-r--r-- | public/plugin/notes-server/notes.html | 396 | ||||
-rw-r--r-- | public/plugin/notes/notes.html | 406 | ||||
-rw-r--r-- | public/plugin/notes/notes.js | 122 |
5 files changed, 0 insertions, 1050 deletions
diff --git a/public/plugin/notes-server/client.js b/public/plugin/notes-server/client.js deleted file mode 100644 index 628586ff..00000000 --- a/public/plugin/notes-server/client.js +++ /dev/null @@ -1,60 +0,0 @@ -(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 ), - 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' ); - - var messageData = { - notes: '', - markdown: false, - socketId: socketId, - 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'; - } - - socket.emit( 'statechanged', messageData ); - - } - - // 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(); - -}()); diff --git a/public/plugin/notes-server/index.js b/public/plugin/notes-server/index.js deleted file mode 100644 index df917f11..00000000 --- a/public/plugin/notes-server/index.js +++ /dev/null @@ -1,66 +0,0 @@ -var express = require('express'); -var fs = require('fs'); -var io = require('socket.io'); -var _ = require('underscore'); -var Mustache = require('mustache'); - -var app = express.createServer(); -var staticDir = express.static; - -io = io.listen(app); - -var opts = { - port : 1947, - baseDir : __dirname + '/../../' -}; - -io.sockets.on( 'connection', function( socket ) { - - socket.on( 'connect', function( data ) { - socket.broadcast.emit( 'connect', data ); - }); - - 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.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 ) { - - fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) { - res.send( Mustache.to_html( data.toString(), { - socketId : req.params.socketId - })); - }); - -}); - -// Actually listen -app.listen( opts.port || null ); - -var brown = '\033[33m', - green = '\033[32m', - reset = '\033[0m'; - -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' ); diff --git a/public/plugin/notes-server/notes.html b/public/plugin/notes-server/notes.html deleted file mode 100644 index 72d0317f..00000000 --- a/public/plugin/notes-server/notes.html +++ /dev/null @@ -1,396 +0,0 @@ -<!doctype html> -<html lang="en"> - <head> - <meta charset="utf-8"> - - <title>reveal.js - Slide Notes</title> - - <style> - body { - font-family: Helvetica; - } - - #current-slide, - #upcoming-slide, - #speaker-controls { - padding: 6px; - box-sizing: border-box; - -moz-box-sizing: border-box; - } - - #current-slide iframe, - #upcoming-slide iframe { - width: 100%; - height: 100%; - border: 1px solid #ddd; - } - - #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 ); - } - - #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="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="speaker-controls-notes hidden"> - <h4 class="label">Notes</h4> - <div class="value"></div> - </div> - </div> - - <script src="/socket.io/socket.io.js"></script> - <script src="/plugin/markdown/marked.js"></script> - - <script> - (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 ) { - - 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' }), '*' ); - - } - - // 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 = '/?' + 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 ); - - } - - /** - * 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> -</html> diff --git a/public/plugin/notes/notes.html b/public/plugin/notes/notes.html deleted file mode 100644 index 0cc8cf61..00000000 --- a/public/plugin/notes/notes.html +++ /dev/null @@ -1,406 +0,0 @@ -<!doctype html> -<html lang="en"> - <head> - <meta charset="utf-8"> - - <title>reveal.js - Slide Notes</title> - - <style> - body { - font-family: Helvetica; - } - - #current-slide, - #upcoming-slide, - #speaker-controls { - padding: 6px; - box-sizing: border-box; - -moz-box-sizing: border-box; - } - - #current-slide iframe, - #upcoming-slide iframe { - width: 100%; - height: 100%; - border: 1px solid #ddd; - } - - #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 ); - } - - #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%; - overflow: auto; - - 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="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="speaker-controls-notes hidden"> - <h4 class="label">Notes</h4> - <div class="value"></div> - </div> - </div> - - <script src="../../plugin/markdown/marked.js"></script> - <script> - - (function() { - - var notes, - notesValue, - currentState, - currentSlide, - upcomingSlide, - connected = false; - - window.addEventListener( 'message', function( event ) { - - var data = JSON.parse( event.data ); - - // 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 ]} ), '*' ); - } - } - - } ); - - /** - * Called when the main window is trying to establish a - * connection. - */ - function handleConnectMessage( data ) { - - if( connected === false ) { - connected = true; - - setupIframes( data ); - setupKeyboard(); - setupNotes(); - setupTimer(); - } - - } - - /** - * 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', - 'autoSlide=0', - '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 ); - - } - - /** - * 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> -</html> diff --git a/public/plugin/notes/notes.js b/public/plugin/notes/notes.js deleted file mode 100644 index e42329d2..00000000 --- a/public/plugin/notes/notes.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * 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=1100,height=700' ); - - /** - * 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 + window.location.search, - state: Reveal.getState() - } ), '*' ); - }, 500 ); - - 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(), - notesElement = slideElement.querySelector( 'aside.notes' ); - - 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 ), '*' ); - - } - - /** - * 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(); - - } - - connect(); - } - - if( !/receiver/i.test( window.location.search ) ) { - - // 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 }; - -})(); |