Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made the speaker's notes usable without the server #2104

Merged
merged 3 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,23 @@
<body>
<div class="reveal">
<div class="slides">
<section>Slide 1</section>
<section>Slide 2</section>
<section data-timing="6">
Slide 1

<aside>
these are not notes
</aside>
<aside class="notes">
these are notes for the first slide
</aside>
</section>
<section>
Slide 2

<aside class="notes">
these are the nodes for the second slide
</aside>
</section>
</div>
</div>

Expand All @@ -42,7 +57,9 @@
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
],
controlsTutorial: false,
defaultTiming: 3
});
</script>
</body>
Expand Down
21 changes: 21 additions & 0 deletions js/reveal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3901,6 +3901,23 @@

}

/**
* Returns an array of objects where each object represents the attributes on its respective slide.
*/
function getSlidesMetaInfo() {

var slides = getSlides();
return slides.map( function (slide) {
var meta = {};
for( var i = 0; i < slide.attributes.length; i++ ) {
var attribute = slide.attributes[ i ];
meta[ attribute.name ] = attribute.value;
}
return meta;
} );

}

/**
* Retrieves the total number of slides in this presentation.
*
Expand Down Expand Up @@ -5252,6 +5269,10 @@
// Returns an Array of all slides
getSlides: getSlides,

// Returns an Array of objects representing the attributes on
// the slides
getSlidesMetaInfo: getSlidesMetaInfo,

// Returns the total number of slides
getTotalSlides: getTotalSlides,

Expand Down
192 changes: 116 additions & 76 deletions plugin/notes/notes.html
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ <h4 class="label">Notes</h4>
upcomingSlide,
layoutLabel,
layoutDropdown,
pendingCalls = {},
lastRevealApiCallId = 0,
connected = false;

var SPEAKER_LAYOUTS = {
Expand Down Expand Up @@ -356,6 +358,10 @@ <h4 class="label">Notes</h4>
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' ) {
Expand All @@ -372,6 +378,21 @@ <h4 class="label">Notes</h4>

} );

/**
* 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.
Expand Down Expand Up @@ -486,44 +507,50 @@ <h4 class="label">Notes</h4>

}

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( 'getSlidesMetaInfo', [], function ( slides ) {
callRevealApi( 'getConfig', [], function ( config ) {
var defaultTiming = config.defaultTiming;
if (defaultTiming == null) {
callback(null);
return;
}
}
timings.push(timing);
}
return timings;

var timings = [];
for ( var i in slides ) {
var slide = slides[ 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);
}

callback( timings );
} );
} );

}

/**
* 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 );
} );

}

Expand All @@ -545,12 +572,51 @@ <h4 class="label">Notes</h4>
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 ? "-" : "";
Expand Down Expand Up @@ -592,52 +658,26 @@ <h4 class="label">Notes</h4>

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 );

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 );
} );
} );
}

// 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();

}

timeEl.addEventListener( 'click', function() {
_resetTimer();
return false;
} );

}

/**
Expand Down
19 changes: 17 additions & 2 deletions plugin/notes/notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ var RevealNotes = (function() {

var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );

// Allow popup window access to Reveal API
notesPopup.Reveal = this.Reveal;

/**
* Connect to the notes window through a postmessage handshake.
Expand All @@ -47,9 +45,26 @@ 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].call(Reveal, methodArguments);
notesPopup.postMessage( JSON.stringify( {
namespace: 'reveal-notes',
type: 'return',
result: result,
callId: callId
} ), '*' );
}

/**
* Posts the current slide data to the notes window
*/
Expand Down