aboutsummaryrefslogtreecommitdiff
path: root/plugin/notes
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/notes')
-rw-r--r--plugin/notes/notes.html194
-rw-r--r--plugin/notes/notes.js61
2 files changed, 164 insertions, 91 deletions
diff --git a/plugin/notes/notes.html b/plugin/notes/notes.html
index 0c4eca5..9e0b230 100644
--- a/plugin/notes/notes.html
+++ b/plugin/notes/notes.html
@@ -347,6 +347,8 @@
upcomingSlide,
layoutLabel,
layoutDropdown,
+ pendingCalls = {},
+ lastRevealApiCallId = 0,
connected = false;
var SPEAKER_LAYOUTS = {
@@ -382,6 +384,10 @@
else if( data.type === 'state' ) {
handleStateMessage( data );
}
+ else if( data.type === 'return' ) {
+ pendingCalls[data.callId](data.result);
+ delete pendingCalls[data.callId];
+ }
}
// Messages sent by the reveal.js inside of the current slide preview
else if( data && data.namespace === 'reveal' ) {
@@ -399,6 +405,23 @@
} );
/**
+ * Asynchronously calls the Reveal.js API of the main frame.
+ */
+ function callRevealApi( methodName, methodArguments, callback ) {
+
+ var callId = ++lastRevealApiCallId;
+ pendingCalls[callId] = callback;
+ window.opener.postMessage( JSON.stringify( {
+ namespace: 'reveal-notes',
+ type: 'call',
+ callId: callId,
+ methodName: methodName,
+ arguments: methodArguments
+ } ), '*' );
+
+ }
+
+ /**
* Called when the main window is trying to establish a
* connection.
*/
@@ -512,28 +535,34 @@
}
- function getTimings() {
+ function getTimings( callback ) {
- var slides = Reveal.getSlides();
- var defaultTiming = Reveal.getConfig().defaultTiming;
- if (defaultTiming == null) {
- return null;
- }
- var timings = [];
- for ( var i in slides ) {
- var slide = slides[i];
- var timing = defaultTiming;
- if( slide.hasAttribute( 'data-timing' )) {
- var t = slide.getAttribute( 'data-timing' );
- timing = parseInt(t);
- if( isNaN(timing) ) {
- console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
- timing = defaultTiming;
+ callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {
+ callRevealApi( 'getConfig', [], function ( config ) {
+ var defaultTiming = config.defaultTiming;
+ if (defaultTiming == null) {
+ callback(null);
+ return;
+ }
+
+ var timings = [];
+ for ( var i in slideAttributes ) {
+ var slide = slideAttributes[ i ];
+ var timing = defaultTiming;
+ if( slide.hasOwnProperty( 'data-timing' )) {
+ var t = slide[ 'data-timing' ];
+ timing = parseInt(t);
+ if( isNaN(timing) ) {
+ console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
+ timing = defaultTiming;
+ }
+ }
+ timings.push(timing);
}
- }
- timings.push(timing);
- }
- return timings;
+
+ callback( timings );
+ } );
+ } );
}
@@ -541,15 +570,15 @@
* Return the number of seconds allocated for presenting
* all slides up to and including this one.
*/
- function getTimeAllocated(timings) {
+ function getTimeAllocated( timings, callback ) {
- var slides = Reveal.getSlides();
- var allocated = 0;
- var currentSlide = Reveal.getSlidePastCount();
- for (var i in slides.slice(0, currentSlide + 1)) {
- allocated += timings[i];
- }
- return allocated;
+ callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
+ var allocated = 0;
+ for (var i in timings.slice(0, currentSlide + 1)) {
+ allocated += timings[i];
+ }
+ callback( allocated );
+ } );
}
@@ -571,12 +600,51 @@
pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ),
pacingSecondsEl = pacingEl.querySelector( '.seconds-value' );
- var timings = getTimings();
- if (timings !== null) {
- pacingTitleEl.style.removeProperty('display');
- pacingEl.style.removeProperty('display');
+ var timings = null;
+ getTimings( function ( _timings ) {
+
+ timings = _timings;
+ if (_timings !== null) {
+ pacingTitleEl.style.removeProperty('display');
+ pacingEl.style.removeProperty('display');
+ }
+
+ // Update once directly
+ _updateTimer();
+
+ // Then update every second
+ setInterval( _updateTimer, 1000 );
+
+ } );
+
+
+ function _resetTimer() {
+
+ if (timings == null) {
+ start = new Date();
+ _updateTimer();
+ }
+ else {
+ // Reset timer to beginning of current slide
+ getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
+ var slideEndTiming = slideEndTimingSeconds * 1000;
+ callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
+ var currentSlideTiming = timings[currentSlide] * 1000;
+ var previousSlidesTiming = slideEndTiming - currentSlideTiming;
+ var now = new Date();
+ start = new Date(now.getTime() - previousSlidesTiming);
+ _updateTimer();
+ } );
+ } );
+ }
+
}
+ timeEl.addEventListener( 'click', function() {
+ _resetTimer();
+ return false;
+ } );
+
function _displayTime( hrEl, minEl, secEl, time) {
var sign = Math.sign(time) == -1 ? "-" : "";
@@ -618,52 +686,26 @@
function _updatePacing(diff) {
- var slideEndTiming = getTimeAllocated(timings) * 1000;
- var currentSlide = Reveal.getSlidePastCount();
- var currentSlideTiming = timings[currentSlide] * 1000;
- var timeLeftCurrentSlide = slideEndTiming - diff;
- if (timeLeftCurrentSlide < 0) {
- pacingEl.className = 'pacing behind';
- }
- else if (timeLeftCurrentSlide < currentSlideTiming) {
- pacingEl.className = 'pacing on-track';
- }
- else {
- pacingEl.className = 'pacing ahead';
- }
- _displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
-
- }
-
- // Update once directly
- _updateTimer();
-
- // Then update every second
- setInterval( _updateTimer, 1000 );
-
- function _resetTimer() {
-
- if (timings == null) {
- start = new Date();
- }
- else {
- // Reset timer to beginning of current slide
- var slideEndTiming = getTimeAllocated(timings) * 1000;
- var currentSlide = Reveal.getSlidePastCount();
- var currentSlideTiming = timings[currentSlide] * 1000;
- var previousSlidesTiming = slideEndTiming - currentSlideTiming;
- var now = new Date();
- start = new Date(now.getTime() - previousSlidesTiming);
- }
- _updateTimer();
-
+ getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
+ var slideEndTiming = slideEndTimingSeconds * 1000;
+
+ callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
+ var currentSlideTiming = timings[currentSlide] * 1000;
+ var timeLeftCurrentSlide = slideEndTiming - diff;
+ if (timeLeftCurrentSlide < 0) {
+ pacingEl.className = 'pacing behind';
+ }
+ else if (timeLeftCurrentSlide < currentSlideTiming) {
+ pacingEl.className = 'pacing on-track';
+ }
+ else {
+ pacingEl.className = 'pacing ahead';
+ }
+ _displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
+ } );
+ } );
}
- timeEl.addEventListener( 'click', function() {
- _resetTimer();
- return false;
- } );
-
}
/**
diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js
index a5b15b4..3d5eac4 100644
--- a/plugin/notes/notes.js
+++ b/plugin/notes/notes.js
@@ -11,24 +11,28 @@
*/
var RevealNotes = (function() {
+ var notesPopup = null;
+
function openNotes( notesFilePath ) {
+ if (notesPopup && !notesPopup.closed) {
+ notesPopup.focus();
+ return;
+ }
+
if( !notesFilePath ) {
var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path
jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path
notesFilePath = jsFileLocation + 'notes.html';
}
- var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
+ notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
if( !notesPopup ) {
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
return;
}
- // Allow popup window access to Reveal API
- notesPopup.Reveal = window.Reveal;
-
/**
* Connect to the notes window through a postmessage handshake.
* Using postmessage enables us to work in situations where the
@@ -52,10 +56,29 @@ var RevealNotes = (function() {
clearInterval( connectInterval );
onConnected();
}
+ if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
+ callRevealApi( data.methodName, data.arguments, data.callId );
+ }
} );
}
/**
+ * Calls the specified Reveal.js method with the provided argument
+ * and then pushes the result to the notes frame.
+ */
+ function callRevealApi( methodName, methodArguments, callId ) {
+
+ var result = Reveal[methodName].apply( Reveal, methodArguments );
+ notesPopup.postMessage( JSON.stringify( {
+ namespace: 'reveal-notes',
+ type: 'return',
+ result: result,
+ callId: callId
+ } ), '*' );
+
+ }
+
+ /**
* Posts the current slide data to the notes window
*/
function post( event ) {
@@ -128,20 +151,28 @@ var RevealNotes = (function() {
}
- if( !/receiver/i.test( window.location.search ) ) {
+ return {
+ init: function() {
- // If the there's a 'notes' query set, open directly
- if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
- openNotes();
- }
+ if( !/receiver/i.test( window.location.search ) ) {
- // Open the notes when the 's' key is hit
- Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
- openNotes();
- } );
+ // 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
+ Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
+ openNotes();
+ } );
- return { open: openNotes };
+ }
+
+ },
+
+ open: openNotes
+ };
})();
+
+Reveal.registerPlugin( 'notes', RevealNotes );