diff --git a/exampleSite/content/publication/conference-paper/index.md b/exampleSite/content/publication/conference-paper/index.md index 8f63ec0f..ec425bc6 100644 --- a/exampleSite/content/publication/conference-paper/index.md +++ b/exampleSite/content/publication/conference-paper/index.md @@ -46,12 +46,20 @@ tags = ["Source Themes"] # Otherwise, set `projects = []`. projects = ["internal-project"] +# Slides (optional). +# Associate this publication with Markdown slides. +# Simply enter your slide deck's filename without extension. +# E.g. `slides = "example-slides"` references +# `content/slides/example-slides.md`. +# Otherwise, set `slides = ""`. +slides = "example" + # Links (optional). url_pdf = "http://eprints.soton.ac.uk/352095/1/Cushen-IMV2013.pdf" url_code = "#" url_dataset = "#" url_project = "" -url_slides = "#" +url_slides = "" url_video = "#" url_poster = "#" url_source = "#" diff --git a/exampleSite/content/publication/journal-article/index.md b/exampleSite/content/publication/journal-article/index.md index c00af431..5733d664 100644 --- a/exampleSite/content/publication/journal-article/index.md +++ b/exampleSite/content/publication/journal-article/index.md @@ -52,7 +52,7 @@ projects = [] # E.g. `slides = "example-slides"` references # `content/slides/example-slides.md`. # Otherwise, set `slides = ""`. -slides = "example-slides" +slides = "example" # Links (optional). url_pdf = "http://arxiv.org/pdf/1512.04133v1" diff --git a/exampleSite/content/slides/example-slides.md b/exampleSite/content/slides/example/index.md similarity index 100% rename from exampleSite/content/slides/example-slides.md rename to exampleSite/content/slides/example/index.md diff --git a/exampleSite/content/talk/example/index.md b/exampleSite/content/talk/example/index.md index 8bbc71f0..37e2149b 100644 --- a/exampleSite/content/talk/example/index.md +++ b/exampleSite/content/talk/example/index.md @@ -39,7 +39,7 @@ tags = [] # E.g. `slides = "example-slides"` references # `content/slides/example-slides.md`. # Otherwise, set `slides = ""`. -slides = "example-slides" +slides = "example" # Optional filename of your slides within your talk folder or a URL. url_slides = "" diff --git a/layouts/slides/baseof.html b/layouts/slides/baseof.html index e973a4c0..63ccd28e 100644 --- a/layouts/slides/baseof.html +++ b/layouts/slides/baseof.html @@ -2,7 +2,7 @@
{{ $css := .Site.Data.assets.css }} - {{ $cdn_url_reveal := "https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0" }} + {{ $cdn_url_reveal := "https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.8.0" }} diff --git a/static/js/vendor/reveal.js/plugin/notes/notes.html b/static/js/vendor/reveal.js/plugin/notes/notes.html index f8dc4cfb..255dade3 100644 --- a/static/js/vendor/reveal.js/plugin/notes/notes.html +++ b/static/js/vendor/reveal.js/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' ) { @@ -398,6 +404,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; } - } - timings.push(timing); - } - return timings; + + 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); + } + + 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 ); + 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; - } ); - } /** diff --git a/static/js/vendor/reveal.js/plugin/notes/notes.js b/static/js/vendor/reveal.js/plugin/notes/notes.js index 26294a06..ee631151 100644 --- a/static/js/vendor/reveal.js/plugin/notes/notes.js +++ b/static/js/vendor/reveal.js/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,9 +56,28 @@ 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 */ @@ -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 );