From ee98f13dd97ca3d2e08e04a0bf89ab3225d07f66 Mon Sep 17 00:00:00 2001 From: S Anand Date: Thu, 2 Apr 2015 21:04:00 +0530 Subject: display .stretch images in overview mode --- js/reveal.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 65ac29f..16d9e0f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1195,10 +1195,15 @@ // Change the .stretch element height to 0 in order find the height of all // the other elements element.style.height = '0px'; + // In Overview mode, the parent (.slide) height is set of 700px. + // Restore it temporarily to its natural height. + element.parentNode.style.height = 'auto'; newHeight = height - element.parentNode.offsetHeight; // Restore the old height, just in case element.style.height = oldHeight + 'px'; + // Clear the parent (.slide) height. .removeProperty works in IE9+ + element.parentNode.style.removeProperty('height'); return newHeight; } -- cgit v1.2.3 From 8468d82433cd04952e1fdc0ce68363a2cf618b13 Mon Sep 17 00:00:00 2001 From: Martin Jurča Date: Sun, 18 Feb 2018 21:30:17 +0100 Subject: fixed showing speaker's view with timings/pacing while serving the presentation from the file system --- js/reveal.js | 16 ++++ plugin/notes/notes.html | 189 +++++++++++++++++++++++++++++------------------- plugin/notes/notes.js | 15 +++- 3 files changed, 142 insertions(+), 78 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 230d001..091372e 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3901,6 +3901,20 @@ } + 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. * @@ -5252,6 +5266,8 @@ // Returns an Array of all slides getSlides: getSlides, + getSlidesMetaInfo: getSlidesMetaInfo, + // Returns the total number of slides getTotalSlides: getTotalSlides, diff --git a/plugin/notes/notes.html b/plugin/notes/notes.html index 5b75d73..eff1275 100644 --- a/plugin/notes/notes.html +++ b/plugin/notes/notes.html @@ -329,6 +329,8 @@ upcomingSlide, layoutLabel, layoutDropdown, + pendingCalls = {}, + lastRevealApiCallId = 0, connected = false; var SPEAKER_LAYOUTS = { @@ -356,6 +358,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' ) { @@ -372,6 +378,18 @@ } ); + 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. @@ -486,28 +504,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( 'getSlidesMetaInfo', [], function ( slides ) { + callRevealApi( 'getConfig', [], function ( config ) { + var defaultTiming = config.defaultTiming; + if (defaultTiming == null) { + callback(null); + return; + } + + 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); } - } - timings.push(timing); - } - return timings; + + callback( timings ); + } ); + } ); } @@ -515,15 +539,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 ); + } ); } @@ -545,12 +569,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 ? "-" : ""; @@ -592,52 +655,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 3f00eb6..dd7df8e 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -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. @@ -47,9 +45,22 @@ var RevealNotes = (function() { clearInterval( connectInterval ); onConnected(); } + if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) { + callRevealApi( data.methodName, data.arguments, data.callId ); + } } ); } + 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 */ -- cgit v1.2.3 From 6a2c5b4de833c73f656945253e7b72e31870c88a Mon Sep 17 00:00:00 2001 From: Martin Jurča Date: Tue, 20 Feb 2018 10:30:56 +0100 Subject: documentation --- js/reveal.js | 3 +++ plugin/notes/notes.html | 3 +++ plugin/notes/notes.js | 4 ++++ 3 files changed, 10 insertions(+) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 091372e..9a1422f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3901,6 +3901,9 @@ } + /** + * Returns an array of objects where each object represents the attributes on its respective slide. + */ function getSlidesMetaInfo() { var slides = getSlides(); diff --git a/plugin/notes/notes.html b/plugin/notes/notes.html index eff1275..a6bd5e2 100644 --- a/plugin/notes/notes.html +++ b/plugin/notes/notes.html @@ -378,6 +378,9 @@ } ); + /** + * Asynchronously calls the Reveal.js API of the main frame. + */ function callRevealApi( methodName, methodArguments, callback ) { var callId = ++lastRevealApiCallId; pendingCalls[callId] = callback; diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index dd7df8e..dce9b4e 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -51,6 +51,10 @@ var RevealNotes = (function() { } ); } + /** + * 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( { -- cgit v1.2.3 From 250580fc4c97f83185e46f9d0e22286d0a01d3af Mon Sep 17 00:00:00 2001 From: Martin Jurča Date: Tue, 20 Feb 2018 16:08:29 +0100 Subject: added missing documentation --- index.html | 23 ++++++++++++++++++++--- js/reveal.js | 2 ++ 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'js') diff --git a/index.html b/index.html index 98accc3..e3e10c1 100644 --- a/index.html +++ b/index.html @@ -24,8 +24,23 @@
-
Slide 1
-
Slide 2
+
+ Slide 1 + + + +
+
+ Slide 2 + + +
@@ -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 }); diff --git a/js/reveal.js b/js/reveal.js index 9a1422f..12d67bf 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -5269,6 +5269,8 @@ // 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 -- cgit v1.2.3 From f52460a6fd83d2b59f8f4f9cbb45fa1930c9666a Mon Sep 17 00:00:00 2001 From: anderslemke Date: Wed, 15 Aug 2018 19:45:48 +0200 Subject: Only show resume on pause if controls enabled --- js/reveal.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 3c31b97..b071cc3 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -593,8 +593,7 @@ dom.speakerNotes.setAttribute( 'tabindex', '0' ); // Overlay graphic which is displayed during the paused mode - dom.pauseOverlay = createSingletonNode( dom.wrapper, 'div', 'pause-overlay', '' ); - dom.resumeButton = dom.pauseOverlay.querySelector( '.resume-button' ); + dom.pauseOverlay = createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '' : null ); dom.wrapper.setAttribute( 'role', 'application' ); @@ -1299,7 +1298,7 @@ dom.progress.addEventListener( 'click', onProgressClicked, false ); } - dom.resumeButton.addEventListener( 'click', resume, false ); + dom.pauseOverlay.addEventListener( 'click', resume, false ); if( config.focusBodyOnPageVisibilityChange ) { var visibilityChange; @@ -1364,7 +1363,7 @@ dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false ); dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false ); - dom.resumeButton.removeEventListener( 'click', resume, false ); + dom.pauseOverlay.removeEventListener( 'click', resume, false ); if ( config.progress && dom.progress ) { dom.progress.removeEventListener( 'click', onProgressClicked, false ); -- cgit v1.2.3 From d5cf3fa13c899014008314d41292880fa8b699bd Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 4 Oct 2018 13:26:16 +0200 Subject: formatting and tweaks for #2104 --- index.html | 23 +++-------------------- js/reveal.js | 18 ++++++++++-------- plugin/notes/notes.html | 8 +++++--- plugin/notes/notes.js | 8 +++++--- 4 files changed, 23 insertions(+), 34 deletions(-) (limited to 'js') diff --git a/index.html b/index.html index e3e10c1..98accc3 100644 --- a/index.html +++ b/index.html @@ -24,23 +24,8 @@
-
- Slide 1 - - - -
-
- Slide 2 - - -
+
Slide 1
+
Slide 2
@@ -57,9 +42,7 @@ { 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 + ] }); diff --git a/js/reveal.js b/js/reveal.js index 4946df5..ac3135d 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -4099,18 +4099,20 @@ } /** - * Returns an array of objects where each object represents the attributes on its respective slide. + * Returns an array of objects where each object represents the + * attributes on its respective slide. */ - function getSlidesMetaInfo() { + function getSlidesAttributes() { - var slides = getSlides(); - return slides.map( function (slide) { - var meta = {}; + return getSlides().map( function( slide ) { + + var attributes = {}; for( var i = 0; i < slide.attributes.length; i++ ) { var attribute = slide.attributes[ i ]; - meta[ attribute.name ] = attribute.value; + attributes[ attribute.name ] = attribute.value; } - return meta; + return attributes; + } ); } @@ -5473,7 +5475,7 @@ // Returns an Array of objects representing the attributes on // the slides - getSlidesMetaInfo: getSlidesMetaInfo, + getSlidesAttributes: getSlidesAttributes, // Returns the total number of slides getTotalSlides: getTotalSlides, diff --git a/plugin/notes/notes.html b/plugin/notes/notes.html index 56f5187..9e0b230 100644 --- a/plugin/notes/notes.html +++ b/plugin/notes/notes.html @@ -408,6 +408,7 @@ * 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( { @@ -417,6 +418,7 @@ methodName: methodName, arguments: methodArguments } ), '*' ); + } /** @@ -535,7 +537,7 @@ function getTimings( callback ) { - callRevealApi( 'getSlidesMetaInfo', [], function ( slides ) { + callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) { callRevealApi( 'getConfig', [], function ( config ) { var defaultTiming = config.defaultTiming; if (defaultTiming == null) { @@ -544,8 +546,8 @@ } var timings = []; - for ( var i in slides ) { - var slide = slides[ i ]; + for ( var i in slideAttributes ) { + var slide = slideAttributes[ i ]; var timing = defaultTiming; if( slide.hasOwnProperty( 'data-timing' )) { var t = slide[ 'data-timing' ]; diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index 552a6fe..fdefd75 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -56,17 +56,19 @@ var RevealNotes = (function() { } /** - * Calls the specified Reveal.js method with the provided argument and then pushes the result to the notes - * frame. + * 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); + + var result = Reveal[methodName].call( Reveal, methodArguments ); notesPopup.postMessage( JSON.stringify( { namespace: 'reveal-notes', type: 'return', result: result, callId: callId } ), '*' ); + } /** -- cgit v1.2.3 From 29b0e86089eb3ec0d4bb5811c9b723dfcf36703c Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 4 Oct 2018 14:48:01 +0200 Subject: remove head.min.js in favor of simple built-in script loader --- demo.html | 1 - index.html | 1 - js/reveal.js | 90 ++++++++++++++++++++++-------- lib/js/head.min.js | 6 -- plugin/markdown/example.html | 1 - test/assets/external-script-a.js | 1 + test/assets/external-script-b.js | 1 + test/assets/external-script-c.js | 1 + test/assets/external-script-d.js | 1 + test/examples/embedded-media.html | 1 - test/examples/math.html | 1 - test/examples/slide-backgrounds.html | 1 - test/examples/slide-transitions.html | 1 - test/test-async-dependencies.html | 74 ++++++++++++++++++++++++ test/test-dependencies.html | 54 ++++++++++++++++++ test/test-markdown-element-attributes.html | 1 - test/test-markdown-external.html | 1 - test/test-markdown-options.html | 1 - test/test-markdown-slide-attributes.html | 1 - test/test-markdown.html | 1 - test/test-pdf.html | 1 - test/test.html | 1 - 22 files changed, 200 insertions(+), 42 deletions(-) delete mode 100644 lib/js/head.min.js create mode 100644 test/assets/external-script-a.js create mode 100644 test/assets/external-script-b.js create mode 100644 test/assets/external-script-c.js create mode 100644 test/assets/external-script-d.js create mode 100644 test/test-async-dependencies.html create mode 100644 test/test-dependencies.html (limited to 'js') diff --git a/demo.html b/demo.html index 8aa4aba..04b47d2 100644 --- a/demo.html +++ b/demo.html @@ -384,7 +384,6 @@ Reveal.addEventListener( 'customevent', function() { - + + + + + + diff --git a/test/test-dependencies.html b/test/test-dependencies.html new file mode 100644 index 0000000..49aaf60 --- /dev/null +++ b/test/test-dependencies.html @@ -0,0 +1,54 @@ + + + + + + + reveal.js - Test Dependencies + + + + + + + +
+
+ + + + + + + + + + diff --git a/test/test-markdown-element-attributes.html b/test/test-markdown-element-attributes.html index 4a09272..409d068 100644 --- a/test/test-markdown-element-attributes.html +++ b/test/test-markdown-element-attributes.html @@ -122,7 +122,6 @@ - diff --git a/test/test-markdown-external.html b/test/test-markdown-external.html index d4912b0..76c6ae6 100644 --- a/test/test-markdown-external.html +++ b/test/test-markdown-external.html @@ -23,7 +23,6 @@ - diff --git a/test/test-markdown-options.html b/test/test-markdown-options.html index 598243a..5391a19 100644 --- a/test/test-markdown-options.html +++ b/test/test-markdown-options.html @@ -31,7 +31,6 @@ - diff --git a/test/test-markdown-slide-attributes.html b/test/test-markdown-slide-attributes.html index e90a9cf..ba9e710 100644 --- a/test/test-markdown-slide-attributes.html +++ b/test/test-markdown-slide-attributes.html @@ -116,7 +116,6 @@ - diff --git a/test/test-markdown.html b/test/test-markdown.html index 00f7e7a..e1e5926 100644 --- a/test/test-markdown.html +++ b/test/test-markdown.html @@ -40,7 +40,6 @@ - diff --git a/test/test-pdf.html b/test/test-pdf.html index 5ab8578..1455fb9 100644 --- a/test/test-pdf.html +++ b/test/test-pdf.html @@ -73,7 +73,6 @@ - diff --git a/test/test.html b/test/test.html index f0a5050..67932b7 100644 --- a/test/test.html +++ b/test/test.html @@ -76,7 +76,6 @@ - -- cgit v1.2.3 From 7b707696b40a98e717d91e24162869f6d9c22957 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 8 Oct 2018 09:58:06 +0200 Subject: automatically hide the mouse pointer after 5s of inactivity (#1837) --- README.md | 6 ++++++ js/reveal.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) (limited to 'js') diff --git a/README.md b/README.md index 734036b..72d2ac9 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,12 @@ Reveal.initialize({ // Enable slide navigation via mouse wheel mouseWheel: false, + // Hide cursor if inactive + hideInactiveCursor: true, + + // Time before the cursor is hidden (in ms) + hideCursorTime: 5000, + // Hides the address bar on mobile devices hideAddressBar: true, diff --git a/js/reveal.js b/js/reveal.js index ca2a9a0..48efc08 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -220,6 +220,12 @@ // The display mode that will be used to show slides display: 'block', + // Hide cursor if inactive + hideInactiveCursor: true, + + // Time before the cursor is hidden (in ms) + hideCursorTime: 5000, + // Script dependencies to load dependencies: [] @@ -282,6 +288,12 @@ // Delays updates to the URL due to a Chrome thumbnailer bug writeURLTimeout = 0, + // Is the mouse pointer currently hidden from view + cursorHidden = false, + + // Timeout used to determine when the cursor is inactive + cursorInactiveTimeout = 0, + // Flags if the interaction event listeners are bound eventsAreBound = false, @@ -1253,6 +1265,18 @@ disableRollingLinks(); } + // Auto-hide the mouse pointer when its inactive + if( config.hideInactiveCursor ) { + document.addEventListener( 'mousemove', onDocumentCursorActive, false ); + document.addEventListener( 'mousedown', onDocumentCursorActive, false ); + } + else { + showCursor(); + + document.removeEventListener( 'mousemove', onDocumentCursorActive, false ); + document.removeEventListener( 'mousedown', onDocumentCursorActive, false ); + } + // Iframe link previews if( config.previewLinks ) { enablePreviewLinks(); @@ -2479,6 +2503,32 @@ } + /** + * Shows the mouse pointer after it has been hidden with + * #hideCursor. + */ + function showCursor() { + + if( cursorHidden ) { + cursorHidden = false; + dom.wrapper.style.cursor = ''; + } + + } + + /** + * Hides the mouse pointer when it's on top of the .reveal + * container. + */ + function hideCursor() { + + if( cursorHidden === false ) { + cursorHidden = true; + dom.wrapper.style.cursor = 'none'; + } + + } + /** * Enters the paused mode which fades everything on screen to * black. @@ -4731,6 +4781,22 @@ } + /** + * Called whenever there is mouse input at the document level + * to determine if the cursor is active or not. + * + * @param {object} event + */ + function onDocumentCursorActive( event ) { + + showCursor(); + + clearTimeout( cursorInactiveTimeout ); + + cursorInactiveTimeout = setTimeout( hideCursor, config.hideCursorTime ); + + } + /** * Handler for the document level 'keypress' event. * -- cgit v1.2.3 From a4dc1c64400bea2f88b175fce7a8d0a009209d37 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 11 Oct 2018 11:24:54 +0200 Subject: fix #1590 --- js/reveal.js | 111 ++++++++++++++++++++++++++++++++++++++++------------------- test/test.js | 6 ++++ 2 files changed, 81 insertions(+), 36 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 48efc08..6c11540 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2766,6 +2766,7 @@ updateParallax(); updateSlideNumber(); updateNotes(); + updateFragments(); // Update the URL hash writeURL(); @@ -4405,6 +4406,73 @@ } + /** + * Refreshes the fragments on the current slide so that they + * have the appropriate classes (.visible + .current-fragment). + * + * @param {number} [index] The index of the current fragment + * @param {array} [fragments] Array containing all fragments + * in the current slide + * + * @return {{shown: array, hidden: array}} + */ + function updateFragments( index, fragments ) { + + var changedFragments = { + shown: [], + hidden: [] + }; + + if( currentSlide && config.fragments ) { + + fragments = fragments || sortFragments( currentSlide.querySelectorAll( '.fragment' ) ); + + if( fragments.length ) { + + if( typeof index !== 'number' ) { + var currentFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); + if( currentFragment ) { + index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); + } + } + + toArray( fragments ).forEach( function( el, i ) { + + if( el.hasAttribute( 'data-fragment-index' ) ) { + i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 ); + } + + // Visible fragments + if( i <= index ) { + if( !el.classList.contains( 'visible' ) ) changedFragments.shown.push( el ); + el.classList.add( 'visible' ); + el.classList.remove( 'current-fragment' ); + + // Announce the fragments one by one to the Screen Reader + dom.statusDiv.textContent = getStatusText( el ); + + if( i === index ) { + el.classList.add( 'current-fragment' ); + startEmbeddedContent( el ); + } + } + // Hidden fragments + else { + if( el.classList.contains( 'visible' ) ) changedFragments.hidden.push( el ); + el.classList.remove( 'visible' ); + el.classList.remove( 'current-fragment' ); + } + + } ); + + } + + } + + return changedFragments; + + } + /** * Navigate to the specified slide fragment. * @@ -4440,53 +4508,24 @@ index += offset; } - var fragmentsShown = [], - fragmentsHidden = []; - - toArray( fragments ).forEach( function( element, i ) { + var changedFragments = updateFragments( index, fragments ); - if( element.hasAttribute( 'data-fragment-index' ) ) { - i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 ); - } - - // Visible fragments - if( i <= index ) { - if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element ); - element.classList.add( 'visible' ); - element.classList.remove( 'current-fragment' ); - - // Announce the fragments one by one to the Screen Reader - dom.statusDiv.textContent = getStatusText( element ); - - if( i === index ) { - element.classList.add( 'current-fragment' ); - startEmbeddedContent( element ); - } - } - // Hidden fragments - else { - if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element ); - element.classList.remove( 'visible' ); - element.classList.remove( 'current-fragment' ); - } - - } ); - - if( fragmentsHidden.length ) { - dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } ); + if( changedFragments.hidden.length ) { + dispatchEvent( 'fragmenthidden', { fragment: changedFragments.hidden[0], fragments: changedFragments.hidden } ); } - if( fragmentsShown.length ) { - dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } ); + if( changedFragments.shown.length ) { + dispatchEvent( 'fragmentshown', { fragment: changedFragments.shown[0], fragments: changedFragments.shown } ); } updateControls(); updateProgress(); + if( config.fragmentInURL ) { writeURL(); } - return !!( fragmentsShown.length || fragmentsHidden.length ); + return !!( changedFragments.shown.length || changedFragments.hidden.length ); } diff --git a/test/test.js b/test/test.js index f8515a0..6e862e8 100644 --- a/test/test.js +++ b/test/test.js @@ -262,6 +262,8 @@ Reveal.addEventListener( 'ready', function() { QUnit.test( 'Current fragment', function( assert ) { var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' ); + var fragments = fragmentSlide.querySelectorAll( '.fragment' ); + var lastFragmentIndex = fragments[ fragments.length - 1 ].getAttribute( 'data-fragment-index' ); Reveal.slide( 2, 0 ); assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' ); @@ -274,6 +276,10 @@ Reveal.addEventListener( 'ready', function() { Reveal.slide( 3, 0, 0 ); assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' ); + + Reveal.slide( 2, 1, -1 ); + Reveal.prev(); + assert.strictEqual( fragmentSlide.querySelector( '.fragment.current-fragment' ).getAttribute( 'data-fragment-index' ), lastFragmentIndex, 'last fragment is current fragment when returning from future slide' ); }); QUnit.test( 'Stepping through fragments', function( assert ) { -- cgit v1.2.3 From 387455b755b2cf537130e321e1e04f291b3062d2 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 11 Oct 2018 11:32:16 +0200 Subject: replace while with forEach loop --- js/reveal.js | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 6c11540..d78d3a9 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2991,14 +2991,11 @@ element.classList.add( reverse ? 'future' : 'past' ); if( config.fragments ) { - var pastFragments = toArray( element.querySelectorAll( '.fragment' ) ); - - // Show all fragments on prior slides - while( pastFragments.length ) { - var pastFragment = pastFragments.pop(); - pastFragment.classList.add( 'visible' ); - pastFragment.classList.remove( 'current-fragment' ); - } + // Show all fragments in prior slides + toArray( element.querySelectorAll( '.fragment' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + fragment.classList.remove( 'current-fragment' ); + } ); } } else if( i > index ) { @@ -3006,14 +3003,11 @@ element.classList.add( reverse ? 'past' : 'future' ); if( config.fragments ) { - var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) ); - - // No fragments in future slides should be visible ahead of time - while( futureFragments.length ) { - var futureFragment = futureFragments.pop(); - futureFragment.classList.remove( 'visible' ); - futureFragment.classList.remove( 'current-fragment' ); - } + // Hide all fragments in future slides + toArray( element.querySelectorAll( '.fragment.visible' ) ).forEach( function( fragment ) { + fragment.classList.remove( 'visible' ); + fragment.classList.remove( 'current-fragment' ); + } ); } } } -- cgit v1.2.3 From 8a35a1e1ed9b0579f1e549273348a0477167c207 Mon Sep 17 00:00:00 2001 From: Mario Botsch Date: Wed, 24 Oct 2018 23:22:11 +0200 Subject: Fix nested if-statement in readURL that caused slide(h,v) to be called even when the current slide is the target slide. --- js/reveal.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index d78d3a9..f797084 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -4070,10 +4070,13 @@ // Ensure that we're not already on a slide with the same name var isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false; - if( element && !isSameNameAsCurrentSlide ) { - // Find the position of the named slide and navigate to it - var indices = Reveal.getIndices( element ); - slide( indices.h, indices.v ); + if( element ) { + // If the slide exists and is not the current slide... + if ( !isSameNameAsCurrentSlide ) { + // ...find the position of the named slide and navigate to it + var indices = Reveal.getIndices(element); + slide(indices.h, indices.v); + } } // If the slide doesn't exist, navigate to the current slide else { -- cgit v1.2.3 From 42e796afb2a4db10772cf0f4b517094c0fbec644 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 26 Oct 2018 11:29:08 +0200 Subject: dispatch state events after current slide has updated #2264 --- js/reveal.js | 44 ++++++++-------- test/test-state.html | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 22 deletions(-) create mode 100644 test/test-state.html (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index f797084..1c0e69d 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2671,28 +2671,6 @@ layout(); - // Apply the new state - stateLoop: for( var i = 0, len = state.length; i < len; i++ ) { - // Check if this state existed on the previous slide. If it - // did, we will avoid adding it repeatedly - for( var j = 0; j < stateBefore.length; j++ ) { - if( stateBefore[j] === state[i] ) { - stateBefore.splice( j, 1 ); - continue stateLoop; - } - } - - document.documentElement.classList.add( state[i] ); - - // Dispatch custom event matching the state's name - dispatchEvent( state[i] ); - } - - // Clean up the remains of the previous state - while( stateBefore.length ) { - document.documentElement.classList.remove( stateBefore.pop() ); - } - // Update the overview if it's currently active if( isOverview() ) { updateOverview(); @@ -2741,6 +2719,28 @@ } } + // Apply the new state + stateLoop: for( var i = 0, len = state.length; i < len; i++ ) { + // Check if this state existed on the previous slide. If it + // did, we will avoid adding it repeatedly + for( var j = 0; j < stateBefore.length; j++ ) { + if( stateBefore[j] === state[i] ) { + stateBefore.splice( j, 1 ); + continue stateLoop; + } + } + + document.documentElement.classList.add( state[i] ); + + // Dispatch custom event matching the state's name + dispatchEvent( state[i] ); + } + + // Clean up the remains of the previous state + while( stateBefore.length ) { + document.documentElement.classList.remove( stateBefore.pop() ); + } + if( slideChanged ) { dispatchEvent( 'slidechanged', { 'indexh': indexh, diff --git a/test/test-state.html b/test/test-state.html new file mode 100644 index 0000000..e6ae423 --- /dev/null +++ b/test/test-state.html @@ -0,0 +1,139 @@ + + + + + + + reveal.js - Test State + + + + + + + +
+
+ + + + + + + + + + -- cgit v1.2.3 From f042a8c394718ebb7756aceb58f35d6204559779 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 13 Nov 2018 10:48:23 +0100 Subject: add cmd/ctrl + arrow key shortcuts to first/last slides --- js/reveal.js | 40 ++++++++++++++++++++++++---------------- plugin/search/search.js | 2 +- 2 files changed, 25 insertions(+), 17 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 1c0e69d..f6f7903 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -318,17 +318,17 @@ // Holds information about the keyboard shortcuts keyboardShortcuts = { - 'N , SPACE': 'Next slide', - 'P': 'Previous slide', - '← , H': 'Navigate left', - '→ , L': 'Navigate right', - '↑ , K': 'Navigate up', - '↓ , J': 'Navigate down', - 'Home': 'First slide', - 'End': 'Last slide', - 'B , .': 'Pause', - 'F': 'Fullscreen', - 'ESC, O': 'Slide overview' + 'N , SPACE': 'Next slide', + 'P': 'Previous slide', + '← , H': 'Navigate left', + '→ , L': 'Navigate right', + '↑ , K': 'Navigate up', + '↓ , J': 'Navigate down', + 'Home , ⌘/CTRL ←': 'First slide', + 'End , ⌘/CTRL →': 'Last slide', + 'B , .': 'Pause', + 'F': 'Fullscreen', + 'ESC, O': 'Slide overview' }, // Holds custom key code mappings @@ -4865,15 +4865,23 @@ onUserInput( event ); - // Check if there's a focused element that could be using - // the keyboard + // Is there a focused element that could be using the keyboard? var activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit'; var activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName ); var activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className); + // Whitelist specific modified + keycode combinations + var prevSlideShortcut = event.shiftKey && event.keyCode === 32; + var firstSlideShortcut = ( event.metaKey || event.ctrlKey ) && event.keyCode === 37; + var lastSlideShortcut = ( event.metaKey || event.ctrlKey ) && event.keyCode === 39; + + // Prevent all other events when a modifier is pressed + var unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut && + ( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ); + // Disregard the event if there's a focused element or a // keyboard modifier key is present - if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return; + if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return; // While paused only allow resume keyboard events; 'b', 'v', '.' var resumeKeyCodes = [66,86,190,191]; @@ -4957,9 +4965,9 @@ // n, page down case 78: case 34: navigateNext(); break; // h, left - case 72: case 37: navigateLeft(); break; + case 72: case 37: firstSlideShortcut ? slide( 0 ) : navigateLeft(); break; // l, right - case 76: case 39: navigateRight(); break; + case 76: case 39: lastSlideShortcut ? slide( Number.MAX_VALUE ) : navigateRight(); break; // k, up case 75: case 38: navigateUp(); break; // j, down diff --git a/plugin/search/search.js b/plugin/search/search.js index 6d694d2..21c0367 100644 --- a/plugin/search/search.js +++ b/plugin/search/search.js @@ -200,7 +200,7 @@ function Hilitor(id, tag) toggleSearch(); } }, false ); - if( window.Reveal ) Reveal.registerKeyboardShortcut( 'Ctrl-Shift-F', 'Search' ); + if( window.Reveal ) Reveal.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' ); closeSearch(); return { open: openSearch }; })(); -- cgit v1.2.3 From 8ac3383bee936aaf4939bf8d4cb30d5998ceff2b Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 16 Nov 2018 10:39:43 +0100 Subject: add getRevealElement API method --- README.md | 3 +++ js/reveal.js | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index c60e6a4..d8960b1 100644 --- a/README.md +++ b/README.md @@ -592,6 +592,9 @@ Reveal.isLastSlide(); Reveal.isOverview(); Reveal.isPaused(); Reveal.isAutoSliding(); + +// Returns the top-level DOM element +getRevealElement(); //
...
``` ### Custom Key Bindings diff --git a/js/reveal.js b/js/reveal.js index f6f7903..637ea63 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -5683,6 +5683,11 @@ return query; }, + // Returns the top-level DOM element + getRevealElement: function() { + return dom.wrapper || document.querySelector( '.reveal' ); + }, + // Returns true if we're currently on the first slide isFirstSlide: function() { return ( indexh === 0 && indexv === 0 ); @@ -5724,12 +5729,12 @@ // Forward event binding to the reveal DOM element addEventListener: function( type, listener, useCapture ) { if( 'addEventListener' in window ) { - ( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture ); + Reveal.getRevealElement().addEventListener( type, listener, useCapture ); } }, removeEventListener: function( type, listener, useCapture ) { if( 'addEventListener' in window ) { - ( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture ); + Reveal.getRevealElement().removeEventListener( type, listener, useCapture ); } }, -- cgit v1.2.3 From fd6245bb281d6e4bf278628f6fe63a2d15be0993 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Dec 2018 16:46:00 -0800 Subject: Add new 'hash: true' option which uses replaceState for url Resolves #2211 --- README.md | 5 ++++- js/reveal.js | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index d8960b1..e32478a 100644 --- a/README.md +++ b/README.md @@ -259,9 +259,12 @@ Reveal.initialize({ // Display the page number of the current slide slideNumber: false, - // Push each slide change to the browser history + // Push each slide change to the browser history. Implies `hash: true` history: false, + // Change the hash when changing slides -- impacts browser history with `history: true` + hash: false, + // Enable keyboard shortcuts for navigation keyboard: true, diff --git a/js/reveal.js b/js/reveal.js index 637ea63..c9f3b3b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -76,9 +76,12 @@ // Determine which displays to show the slide number on showSlideNumber: 'all', - // Push each slide change to the browser history + // Push each slide change to the browser history. Implies `hash: true` history: false, + // Change the hash when changing slides -- impacts browser history with `history: true` + hash: false, + // Enable keyboard shortcuts for navigation keyboard: true, @@ -4114,18 +4117,20 @@ */ function writeURL( delay ) { - if( config.history ) { - - // Make sure there's never more than one timeout running - clearTimeout( writeURLTimeout ); + // Make sure there's never more than one timeout running + clearTimeout( writeURLTimeout ); - // If a delay is specified, timeout this call - if( typeof delay === 'number' ) { - writeURLTimeout = setTimeout( writeURL, delay ); - } - else if( currentSlide ) { + // If a delay is specified, timeout this call + if( typeof delay === 'number' ) { + writeURLTimeout = setTimeout( writeURL, delay ); + } + else if( currentSlide ) { + if ( config.history ) { window.location.hash = locationHash(); } + else if ( config.hash ) { + window.history.replaceState(null, null, '#' + locationHash()); + } } } -- cgit v1.2.3 From db9c346b412be5dca4ea7ca820f8f39007ef146f Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 18 Dec 2018 14:21:11 +0100 Subject: optimization; avoid reading computed styles unless necessary --- js/reveal.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 637ea63..4cf43f7 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1131,18 +1131,27 @@ if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition; if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity; - // If this slide has a background color, add a class that + // If this slide has a background color, we add a class that // signals if it is light or dark. If the slide has no background - // color, no class will be set - var computedBackgroundStyle = window.getComputedStyle( element ); - if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) { - var rgb = colorToRgb( computedBackgroundStyle.backgroundColor ); + // color, no class will be added + var contrastColor = data.backgroundColor; + + // If no bg color was found, check the computed background + if( !contrastColor ) { + var computedBackgroundStyle = window.getComputedStyle( element ); + if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) { + contrastColor = computedBackgroundStyle.backgroundColor; + } + } + + if( contrastColor ) { + var rgb = colorToRgb( contrastColor ); // Ignore fully transparent backgrounds. Some browsers return // rgba(0,0,0,0) when reading the computed background color of // an element with no background if( rgb && rgb.a !== 0 ) { - if( colorBrightness( computedBackgroundStyle.backgroundColor ) < 128 ) { + if( colorBrightness( contrastColor ) < 128 ) { slide.classList.add( 'has-dark-background' ); } else { -- cgit v1.2.3 From 665dfb9cd63188a7c5a02aa1d3e2b593bf00bf2c Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 19 Dec 2018 09:38:15 +0100 Subject: add gridNavigation config to configure navigation between adjacent vertical stacks --- js/reveal.js | 22 ++++++++++--- test/test-grid-navigation.html | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 test/test-grid-navigation.html (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 4cf43f7..16ff6df 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -104,6 +104,20 @@ // Change the presentation direction to be RTL rtl: false, + // When this is enabled, stepping left/right from a vertical stack + // to an adjacent vertical stack will land you at the same vertical + // index. + // + // Consider a deck with six slides ordered in two stacks like this: + // 1.1 2.1 + // 1.2 2.2 + // 1.3 2.3 + // + // If you're on slide 1.3 and navigate right, you will normally move + // from 1.3 -> 2.1. With "grid" enabled the same navigation takes you + // from 1.3 -> 2.3. + gridNavigation: false, + // Randomizes the order of slides each time the presentation loads shuffle: false, @@ -4678,12 +4692,12 @@ // Reverse for RTL if( config.rtl ) { if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) { - slide( indexh + 1 ); + slide( indexh + 1, config.gridNavigation ? indexv : undefined ); } } // Normal navigation else if( ( isOverview() || previousFragment() === false ) && availableRoutes().left ) { - slide( indexh - 1 ); + slide( indexh - 1, config.gridNavigation ? indexv : undefined ); } } @@ -4695,12 +4709,12 @@ // Reverse for RTL if( config.rtl ) { if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) { - slide( indexh - 1 ); + slide( indexh - 1, config.gridNavigation ? indexv : undefined ); } } // Normal navigation else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) { - slide( indexh + 1 ); + slide( indexh + 1, config.gridNavigation ? indexv : undefined ); } } diff --git a/test/test-grid-navigation.html b/test/test-grid-navigation.html new file mode 100644 index 0000000..2814ca3 --- /dev/null +++ b/test/test-grid-navigation.html @@ -0,0 +1,74 @@ + + + + + + + reveal.js - Test Grid + + + + + + + +
+
+ + + + + + + + + + -- cgit v1.2.3 From 7eb74ac3358e538dd2bf61fbb11e8af94af39c21 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 19 Dec 2018 10:40:59 +0100 Subject: correct variable name in inline comment --- js/reveal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 16ff6df..59854b7 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -114,8 +114,8 @@ // 1.3 2.3 // // If you're on slide 1.3 and navigate right, you will normally move - // from 1.3 -> 2.1. With "grid" enabled the same navigation takes you - // from 1.3 -> 2.3. + // from 1.3 -> 2.1. With "gridNavigation" enabled the same navigation + // takes you from 1.3 -> 2.3. gridNavigation: false, // Randomizes the order of slides each time the presentation loads -- cgit v1.2.3 From b645828707cd9752055f2e2c237f977207c4ea73 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 19 Dec 2018 11:04:29 +0100 Subject: ensure history api is available, default to hash: true with no history in demo #2286 --- README.md | 11 ++++++----- demo.html | 2 +- js/reveal.js | 11 ++++++----- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index 00fe8d8..bd3965f 100644 --- a/README.md +++ b/README.md @@ -260,12 +260,13 @@ Reveal.initialize({ // Display the page number of the current slide slideNumber: false, - // Push each slide change to the browser history. Implies `hash: true` - history: false, - - // Change the hash when changing slides -- impacts browser history with `history: true` + // Add the current slide number to the URL hash so that reloading the + // page/copying the URL will return you to the same slide hash: false, + // Push each slide change to the browser history. Implies `hash: true` + history: false, + // Enable keyboard shortcuts for navigation keyboard: true, @@ -283,7 +284,7 @@ Reveal.initialize({ // Change the presentation direction to be RTL rtl: false, - + // When this is enabled, stepping left/right from a vertical stack // to an adjacent vertical stack will land you at the same vertical // index instead of the top. diff --git a/demo.html b/demo.html index 69f964b..9471f8b 100644 --- a/demo.html +++ b/demo.html @@ -393,8 +393,8 @@ Reveal.addEventListener( 'customevent', function() { Reveal.initialize({ controls: true, progress: true, - history: true, center: true, + hash: true, transition: 'slide', // none/fade/slide/convex/concave/zoom diff --git a/js/reveal.js b/js/reveal.js index afbc35a..f3f4ae1 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -76,12 +76,13 @@ // Determine which displays to show the slide number on showSlideNumber: 'all', + // Add the current slide number to the URL hash so that reloading the + // page/copying the URL will return you to the same slide + hash: false, + // Push each slide change to the browser history. Implies `hash: true` history: false, - // Change the hash when changing slides -- impacts browser history with `history: true` - hash: false, - // Enable keyboard shortcuts for navigation keyboard: true, @@ -4148,10 +4149,10 @@ writeURLTimeout = setTimeout( writeURL, delay ); } else if( currentSlide ) { - if ( config.history ) { + if( config.history || !window.history ) { window.location.hash = locationHash(); } - else if ( config.hash ) { + else if( config.hash ) { window.history.replaceState(null, null, '#' + locationHash()); } } -- cgit v1.2.3 From 9712cc9ad64cda09306834250c8770d1e81b2856 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 7 Jan 2019 14:43:46 +0100 Subject: whitespace --- js/reveal.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index f01358e..2442a5c 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1765,13 +1765,16 @@ // Change the .stretch element height to 0 in order find the height of all // the other elements element.style.height = '0px'; + // In Overview mode, the parent (.slide) height is set of 700px. // Restore it temporarily to its natural height. element.parentNode.style.height = 'auto'; + newHeight = height - element.parentNode.offsetHeight; // Restore the old height, just in case element.style.height = oldHeight + 'px'; + // Clear the parent (.slide) height. .removeProperty works in IE9+ element.parentNode.style.removeProperty('height'); -- cgit v1.2.3 From 10e44aabfcaba104ab52bdc11f2f6963155cdea4 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 10 Jan 2019 14:43:33 +0100 Subject: remove pinch gesture for triggering overview mode on touch devices, enables regular mobile pinch-to-zoom --- js/reveal.js | 44 +------------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 2442a5c..9e14fb9 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -328,7 +328,6 @@ touch = { startX: 0, startY: 0, - startSpan: 0, startCount: 0, captured: false, threshold: 40 @@ -5066,18 +5065,6 @@ touch.startY = event.touches[0].clientY; touch.startCount = event.touches.length; - // If there's two touches we need to memorize the distance - // between those two points to detect pinching - if( event.touches.length === 2 && config.overview ) { - touch.startSpan = distanceBetween( { - x: event.touches[1].clientX, - y: event.touches[1].clientY - }, { - x: touch.startX, - y: touch.startY - } ); - } - } /** @@ -5096,37 +5083,8 @@ var currentX = event.touches[0].clientX; var currentY = event.touches[0].clientY; - // If the touch started with two points and still has - // two active touches; test for the pinch gesture - if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) { - - // The current distance in pixels between the two touch points - var currentSpan = distanceBetween( { - x: event.touches[1].clientX, - y: event.touches[1].clientY - }, { - x: touch.startX, - y: touch.startY - } ); - - // If the span is larger than the desire amount we've got - // ourselves a pinch - if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) { - touch.captured = true; - - if( currentSpan < touch.startSpan ) { - activateOverview(); - } - else { - deactivateOverview(); - } - } - - event.preventDefault(); - - } // There was only one touch point, look for a swipe - else if( event.touches.length === 1 && touch.startCount !== 2 ) { + if( event.touches.length === 1 && touch.startCount !== 2 ) { var deltaX = currentX - touch.startX, deltaY = currentY - touch.startY; -- cgit v1.2.3 From c36caef5e7f2a448df8503ff8eb37defea297152 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 10 Jan 2019 14:58:38 +0100 Subject: 2019 --- Gruntfile.js | 2 +- LICENSE | 2 +- README.md | 2 +- css/reveal.css | 2 +- css/reveal.scss | 2 +- js/reveal.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/Gruntfile.js b/Gruntfile.js index 8d8300b..59ad896 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -15,7 +15,7 @@ module.exports = function(grunt) { ' * http://revealjs.com\n' + ' * MIT licensed\n' + ' *\n' + - ' * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n' + + ' * Copyright (C) 2019 Hakim El Hattab, http://hakim.se\n' + ' */' }, diff --git a/LICENSE b/LICENSE index 1b8b5a7..697d156 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2018 Hakim El Hattab, http://hakim.se, and reveal.js contributors +Copyright (C) 2019 Hakim El Hattab, http://hakim.se, and reveal.js contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index bd3965f..8028e82 100644 --- a/README.md +++ b/README.md @@ -1349,4 +1349,4 @@ If you want to include math inside of a presentation written in Markdown you nee MIT licensed -Copyright (C) 2018 Hakim El Hattab, http://hakim.se +Copyright (C) 2019 Hakim El Hattab, http://hakim.se diff --git a/css/reveal.css b/css/reveal.css index ebc399f..5de7b4c 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2018 Hakim El Hattab, http://hakim.se + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se */ /********************************************* * GLOBAL STYLES diff --git a/css/reveal.scss b/css/reveal.scss index 75ffb72..7e75dde 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2018 Hakim El Hattab, http://hakim.se + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se */ diff --git a/js/reveal.js b/js/reveal.js index 9e14fb9..afd678b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2018 Hakim El Hattab, http://hakim.se + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se */ (function( root, factory ) { if( typeof define === 'function' && define.amd ) { -- cgit v1.2.3 From abee356e42bd27a06db3f1308fd7b751de646102 Mon Sep 17 00:00:00 2001 From: Mario Wolff Date: Tue, 15 Jan 2019 13:13:19 +0100 Subject: emmit resize event if scale changed --- README.md | 8 ++++++++ js/reveal.js | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'js') diff --git a/README.md b/README.md index a301d5f..4804c29 100644 --- a/README.md +++ b/README.md @@ -958,6 +958,14 @@ Limitations: - Only direct descendants of a slide section can be stretched - Only one descendant per slide section can be stretched +### Resize Event + +When reveal.js changes the scale of the slides it fires an resize event. You can subscribe to the event to resize your elements accordingly. + +```javascript +Reveal.addEventListener( 'overviewshown', function( event ) { /* console.log(event.scale,event.oldscale,event.size); */ } ); +``` + ### postMessage API The framework has a built-in postMessage API that can be used when communicating with a presentation inside of another window. Here's an example showing how you'd make a reveal.js instance in the given window proceed to slide 2: diff --git a/js/reveal.js b/js/reveal.js index 3c31b97..b291bc7 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1971,6 +1971,7 @@ dom.slides.style.height = size.height + 'px'; // Determine scale of content to fit within available space + var oldscale =scale; scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); // Respect max/min scale settings @@ -2036,6 +2037,13 @@ } + if( oldscale!==scale ){ + dispatchEvent( 'resize', { + 'oldscale': oldscale, + 'scale': scale, + 'size': size + } ); + } } updateProgress(); -- cgit v1.2.3 From 65584ff3a9ecde118f8b33c94c3e5c3ee4345c3f Mon Sep 17 00:00:00 2001 From: Stéphane Este-Gracias Date: Mon, 21 Jan 2019 21:57:20 +0100 Subject: Enable simpleNavigation --- js/reveal.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index afd678b..a658a3b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -108,6 +108,9 @@ // Change the presentation direction to be RTL rtl: false, + // When this is enabled, stepping only with previous and next slide. + simpleNavigation: false, + // When this is enabled, stepping left/right from a vertical stack // to an adjacent vertical stack will land you at the same vertical // index. @@ -5001,13 +5004,13 @@ // n, page down case 78: case 34: navigateNext(); break; // h, left - case 72: case 37: firstSlideShortcut ? slide( 0 ) : navigateLeft(); break; + case 72: case 37: firstSlideShortcut ? slide( 0 ) : isOverview() || !config.simpleNavigation ? navigateLeft() : navigatePrev(); break; // l, right - case 76: case 39: lastSlideShortcut ? slide( Number.MAX_VALUE ) : navigateRight(); break; + case 76: case 39: lastSlideShortcut ? slide( Number.MAX_VALUE ) : isOverview() || !config.simpleNavigation ? navigateRight() : navigateNext(); break; // k, up - case 75: case 38: navigateUp(); break; + case 75: case 38: isOverview() || !config.simpleNavigation ? navigateUp() : navigatePrev(); break; // j, down - case 74: case 40: navigateDown(); break; + case 74: case 40: isOverview() || !config.simpleNavigation ? navigateDown() : navigateNext(); break; // home case 36: slide( 0 ); break; // end -- cgit v1.2.3 From 5002304fb119859fe0d115883acceb094bc41be0 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 22 Jan 2019 09:45:33 +0100 Subject: correct height of reveal.js on mobile devices, fixes vertical overflow --- css/reveal.css | 5 +---- css/reveal.scss | 11 +---------- js/reveal.js | 10 ++++++++++ 3 files changed, 12 insertions(+), 14 deletions(-) (limited to 'js') diff --git a/css/reveal.css b/css/reveal.css index 5de7b4c..c685926 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -12,6 +12,7 @@ html, body { width: 100%; height: 100%; + height: calc( var(--vh, 1vh) * 100); overflow: hidden; } body { @@ -463,10 +464,6 @@ body { -ms-touch-action: none; touch-action: none; } -@media only screen and (orientation: landscape) { - .reveal.ua-iphone { - position: fixed; } } - .reveal .slides { position: absolute; width: 100%; diff --git a/css/reveal.scss b/css/reveal.scss index 7e75dde..7bec964 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -15,6 +15,7 @@ html, body { width: 100%; height: 100%; + height: calc( var(--vh, 1vh) * 100 ); overflow: hidden; } @@ -559,16 +560,6 @@ $controlsArrowAngleActive: 36deg; touch-action: none; } -// Mobile Safari sometimes overlays a header at the top -// of the page when in landscape mode. Using fixed -// positioning ensures that reveal.js reduces its height -// when this header is visible. -@media only screen and (orientation : landscape) { - .reveal.ua-iphone { - position: fixed; - } -} - .reveal .slides { position: absolute; width: 100%; diff --git a/js/reveal.js b/js/reveal.js index afd678b..88ce029 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2065,6 +2065,16 @@ if( !config.disableLayout ) { + // On some mobile devices '100vh' is taller than the visible + // viewport which leads to part of the presentation being + // cut off. To work around this we define our own '--vh' custom + // property where 100x adds up to the correct height. + // + // https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ + if( isMobileDevice ) { + document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' ); + } + var size = getComputedSlideSize(); // Layout the contents of the slides -- cgit v1.2.3 From 4c3f778e6e39c885e1197c9970e098bdbc643398 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 22 Jan 2019 15:43:31 +0100 Subject: refactor keyboard listener conditions --- js/reveal.js | 130 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 35 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 07a86e5..5743646 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -4909,6 +4909,9 @@ return true; } + // Shorthand + var keyCode = event.keyCode; + // Remember if auto-sliding was paused so we can toggle it var autoSlideWasPaused = autoSlidePaused; @@ -4921,8 +4924,8 @@ // Whitelist specific modified + keycode combinations var prevSlideShortcut = event.shiftKey && event.keyCode === 32; - var firstSlideShortcut = ( event.metaKey || event.ctrlKey ) && event.keyCode === 37; - var lastSlideShortcut = ( event.metaKey || event.ctrlKey ) && event.keyCode === 39; + var firstSlideShortcut = ( event.metaKey || event.ctrlKey ) && keyCode === 37; + var lastSlideShortcut = ( event.metaKey || event.ctrlKey ) && keyCode === 39; // Prevent all other events when a modifier is pressed var unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut && @@ -4945,7 +4948,7 @@ } } - if( isPaused() && resumeKeyCodes.indexOf( event.keyCode ) === -1 ) { + if( isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) { return false; } @@ -4957,7 +4960,7 @@ for( key in config.keyboard ) { // Check if this binding matches the pressed key - if( parseInt( key, 10 ) === event.keyCode ) { + if( parseInt( key, 10 ) === keyCode ) { var value = config.keyboard[ key ]; @@ -4984,7 +4987,7 @@ for( key in registeredKeyBindings ) { // Check if this binding matches the pressed key - if( parseInt( key, 10 ) === event.keyCode ) { + if( parseInt( key, 10 ) === keyCode ) { var action = registeredKeyBindings[ key ].callback; @@ -5008,35 +5011,92 @@ // Assume true and try to prove false triggered = true; - switch( event.keyCode ) { - // p, page up - case 80: case 33: navigatePrev(); break; - // n, page down - case 78: case 34: navigateNext(); break; - // h, left - case 72: case 37: firstSlideShortcut ? slide( 0 ) : isOverview() || !config.simpleNavigation ? navigateLeft() : navigatePrev(); break; - // l, right - case 76: case 39: lastSlideShortcut ? slide( Number.MAX_VALUE ) : isOverview() || !config.simpleNavigation ? navigateRight() : navigateNext(); break; - // k, up - case 75: case 38: isOverview() || !config.simpleNavigation ? navigateUp() : navigatePrev(); break; - // j, down - case 74: case 40: isOverview() || !config.simpleNavigation ? navigateDown() : navigateNext(); break; - // home - case 36: slide( 0 ); break; - // end - case 35: slide( Number.MAX_VALUE ); break; - // space - case 32: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break; - // return - case 13: isOverview() ? deactivateOverview() : triggered = false; break; - // two-spot, semicolon, b, v, period, Logitech presenter tools "black screen" button - case 58: case 59: case 66: case 86: case 190: case 191: togglePause(); break; - // f - case 70: enterFullscreen(); break; - // a - case 65: if ( config.autoSlideStoppable ) toggleAutoSlide( autoSlideWasPaused ); break; - default: - triggered = false; + // P, PAGE UP + if( keyCode === 80 || keyCode === 33 ) { + navigatePrev(); + } + // N, PAGE DOWN + else if( keyCode === 78 || keyCode === 34 ) { + navigateNext(); + } + // H, LEFT + else if( keyCode === 72 || keyCode === 37 ) { + if( firstSlideShortcut ) { + slide( 0 ); + } + else if( !isOverview() && config.simpleNavigation ) { + navigatePrev(); + } + else { + navigateLeft(); + } + } + // L, RIGHT + else if( keyCode === 76 || keyCode === 39 ) { + if( lastSlideShortcut ) { + slide( Number.MAX_VALUE ); + } + else if( !isOverview() && config.simpleNavigation ) { + navigateNext(); + } + else { + navigateRight(); + } + } + // K, UP + else if( keyCode === 75 || keyCode === 38 ) { + if( !isOverview() && config.simpleNavigation ) { + navigatePrev(); + } + else { + navigateUp() + } + } + // J, DOWN + else if( keyCode === 74 || keyCode === 40 ) { + if( !isOverview() && config.simpleNavigation ) { + navigateNext() + } + else { + navigateDown() + } + } + // HOME + else if( keyCode === 36 ) { + slide( 0 ); + } + // END + else if( keyCode === 35 ) { + slide( Number.MAX_VALUE ); + } + // SPACE + else if( keyCode === 32 ) { + if( isOverview() ) { + deactivateOverview(); + } + if( event.shiftKey ) { + navigatePrev(); + } + else { + navigateNext(); + } + } + // TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON + else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) { + togglePause(); + } + // F + else if( keyCode === 70 ) { + enterFullscreen(); + } + // A + else if( keyCode === 65 ) { + if ( config.autoSlideStoppable ) { + toggleAutoSlide( autoSlideWasPaused ); + } + } + else { + triggered = false; } } @@ -5047,7 +5107,7 @@ event.preventDefault && event.preventDefault(); } // ESC or O key - else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) { + else if ( ( keyCode === 27 || keyCode === 79 ) && features.transforms3d ) { if( dom.overlay ) { closeOverlay(); } -- cgit v1.2.3 From 51b1658a60a053a1ee9fe18255f1c40a52c02a65 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 23 Jan 2019 09:58:10 +0100 Subject: 'gridNavigation' and 'simpleNavigation' merged into 'navigationMode' setting #2307 --- js/reveal.js | 43 ++++++++++++++++++++++++++---------------- test/test-grid-navigation.html | 2 +- 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 5743646..5addf75 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -108,14 +108,25 @@ // Change the presentation direction to be RTL rtl: false, - // When this is enabled, stepping only with previous and next slide. - simpleNavigation: false, - + // Changes the behavior of our navigation directions. + // + // "default" + // Left/right arrow keys step between horizontal slides, up/down + // arrow keys step between vertical slides. Space key steps through + // all slides (both horizontal and vertical). + // + // "linear" + // When this is enabled, the left/right arrow keys step through all + // slides (both horizontal and vertical) in a linear way. If the + // presentation has no vertical slides this setting is identical + // to "default". + // + // "grid" // When this is enabled, stepping left/right from a vertical stack // to an adjacent vertical stack will land you at the same vertical // index. // - // Consider a deck with six slides ordered in two stacks like this: + // Consider a deck with six slides ordered in two vertical stacks: // 1.1 2.1 // 1.2 2.2 // 1.3 2.3 @@ -123,7 +134,7 @@ // If you're on slide 1.3 and navigate right, you will normally move // from 1.3 -> 2.1. With "gridNavigation" enabled the same navigation // takes you from 1.3 -> 2.3. - gridNavigation: false, + navigationMode: 'default', // Randomizes the order of slides each time the presentation loads shuffle: false, @@ -4718,12 +4729,12 @@ // Reverse for RTL if( config.rtl ) { if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) { - slide( indexh + 1, config.gridNavigation ? indexv : undefined ); + slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); } } // Normal navigation else if( ( isOverview() || previousFragment() === false ) && availableRoutes().left ) { - slide( indexh - 1, config.gridNavigation ? indexv : undefined ); + slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); } } @@ -4735,12 +4746,12 @@ // Reverse for RTL if( config.rtl ) { if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) { - slide( indexh - 1, config.gridNavigation ? indexv : undefined ); + slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); } } // Normal navigation else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) { - slide( indexh + 1, config.gridNavigation ? indexv : undefined ); + slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); } } @@ -5024,7 +5035,7 @@ if( firstSlideShortcut ) { slide( 0 ); } - else if( !isOverview() && config.simpleNavigation ) { + else if( !isOverview() && config.navigationMode === 'linear' ) { navigatePrev(); } else { @@ -5036,7 +5047,7 @@ if( lastSlideShortcut ) { slide( Number.MAX_VALUE ); } - else if( !isOverview() && config.simpleNavigation ) { + else if( !isOverview() && config.navigationMode === 'linear' ) { navigateNext(); } else { @@ -5045,20 +5056,20 @@ } // K, UP else if( keyCode === 75 || keyCode === 38 ) { - if( !isOverview() && config.simpleNavigation ) { + if( !isOverview() && config.navigationMode === 'linear' ) { navigatePrev(); } else { - navigateUp() + navigateUp(); } } // J, DOWN else if( keyCode === 74 || keyCode === 40 ) { - if( !isOverview() && config.simpleNavigation ) { - navigateNext() + if( !isOverview() && config.navigationMode === 'linear' ) { + navigateNext(); } else { - navigateDown() + navigateDown(); } } // HOME diff --git a/test/test-grid-navigation.html b/test/test-grid-navigation.html index 2814ca3..21e7636 100644 --- a/test/test-grid-navigation.html +++ b/test/test-grid-navigation.html @@ -55,7 +55,7 @@ }); QUnit.test( 'Enabled', function( assert ) { - Reveal.configure({ gridNavigation: true }); + Reveal.configure({ navigationMode: 'grid' }); Reveal.slide( 0, 0 ); Reveal.right(); Reveal.down(); -- cgit v1.2.3 From 2fa3ab6a6bf9083877dfe46257857a2ab019c293 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 23 Jan 2019 10:14:40 +0100 Subject: documentation for navigationMode #2307 --- README.md | 24 +++++++++++------------- js/reveal.js | 6 ++---- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index d137630..ff58915 100644 --- a/README.md +++ b/README.md @@ -285,10 +285,8 @@ Reveal.initialize({ // Change the presentation direction to be RTL rtl: false, - // When this is enabled, stepping left/right from a vertical stack - // to an adjacent vertical stack will land you at the same vertical - // index instead of the top. - gridNavigation: false, + // . + navigationMode: 'default', // Randomizes the order of slides each time the presentation loads shuffle: false, @@ -523,15 +521,15 @@ Slides can be nested within other slides to create vertical stacks (see [Markup] -#### Grid Navigation -If you are on a vertical slide and step right onto an adjacent vertical stack, you'll arrive at the top of that stack. Consider a deck with six slides organized in two stacks like this: -``` -1.1 2.1 -1.2 2.2 -1.3 2.3 -``` -If you're on slide 1.3 and navigate right, you will normally move from 1.3 -> 2.1. If you prefer remaining at the same vertical index and going directly from 1.3 -> 2.3 you can enable the `gridNavigation` config option: `Reveal.configure({ gridNavigation: true })`. - +#### Navigation Mode +You can finetune the reveal.js navigation behavior by using the `navigationMode` config option. This option supports the following values: + +| Value | Description | +| :--------------------------- | :---------- | +| default | Left/right arrow keys step between horizontal slides. Up/down arrow keys step between vertical slides. Space key steps through all slides (both horizontal and vertical). | +| linear | Removes the up/down arrows. Left/right arrows step through all slides (both horizontal and vertical). | +| grid | When this is enabled, stepping left/right from a vertical stack to an adjacent vertical stack will land you at the same vertical index.

Consider a deck with six slides ordered in two vertical stacks:
1.1 2.1
1.2 2.2
1.3 2.3

If you're on slide 1.3 and navigate right, you will normally move from 1.3 -> 2.1. With navigationMode set to "grid" the same navigation takes you from 1.3 -> 2.3. | + ### Touch Navigation You can swipe to navigate through a presentation on any touch-enabled device. Horizontal swipes change between horizontal slides, vertical swipes change between vertical slides. If you wish to disable this you can set the `touch` config option to false when initializing reveal.js. diff --git a/js/reveal.js b/js/reveal.js index 5addf75..ba69d1a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -116,10 +116,8 @@ // all slides (both horizontal and vertical). // // "linear" - // When this is enabled, the left/right arrow keys step through all - // slides (both horizontal and vertical) in a linear way. If the - // presentation has no vertical slides this setting is identical - // to "default". + // Removes the up/down arrows. Left/right arrows step through all + // slides (both horizontal and vertical). // // "grid" // When this is enabled, stepping left/right from a vertical stack -- cgit v1.2.3 From 481208f43fda7270a6ac628a412b32120bfc9018 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 23 Jan 2019 10:30:29 +0100 Subject: hide vertical arrows when navigationMode is 'linear' #2307 --- css/reveal.css | 6 ++++++ css/reveal.scss | 7 +++++++ js/reveal.js | 12 ++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/css/reveal.css b/css/reveal.css index d7442d6..4a9f030 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -343,10 +343,16 @@ body { .reveal .controls .enabled.fragmented:hover { opacity: 1; } +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-up, +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-down { + display: none; } + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-left, .reveal:not(.has-vertical-slides) .controls .navigate-left { bottom: 1.4em; right: 5.5em; } +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-right, .reveal:not(.has-vertical-slides) .controls .navigate-right { bottom: 1.4em; right: 0.5em; } diff --git a/css/reveal.scss b/css/reveal.scss index c93276f..c79a562 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -407,12 +407,19 @@ $controlsArrowAngleActive: 36deg; } } +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-up, +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-down { + display: none; +} + // Adjust the layout when there are no vertical slides +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-left, .reveal:not(.has-vertical-slides) .controls .navigate-left { bottom: $controlArrowSpacing; right: 0.5em + $controlArrowSpacing + $controlArrowSize; } +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-right, .reveal:not(.has-vertical-slides) .controls .navigate-right { bottom: $controlArrowSpacing; right: 0.5em; diff --git a/js/reveal.js b/js/reveal.js index ba69d1a..cee39e2 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1362,6 +1362,14 @@ dom.slideNumber.style.display = slideNumberDisplay; + // Add the navigation mode to the DOM so we can adjust styling + if( config.navigationMode !== 'default' ) { + dom.wrapper.setAttribute( 'data-navigation-mode', config.navigationMode ); + } + else { + dom.wrapper.removeAttribute( 'data-navigation-mode' ); + } + sync(); } @@ -5316,8 +5324,8 @@ /** * Event handler for navigation control buttons. */ - function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); } - function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); } + function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); config.navigationMode === 'linear' ? navigatePrev() : navigateLeft(); } + function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); config.navigationMode === 'linear' ? navigateNext() : navigateRight(); } function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); } function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); } function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); } -- cgit v1.2.3 From 2219107c69189997289cfbcb3f76ba5ddff1ac51 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 29 Jan 2019 11:26:46 +0100 Subject: only force media controls to be visible when necessarry --- js/reveal.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index cee39e2..08ece7f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3809,13 +3809,6 @@ _appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' ); _appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' ); - // Always show media controls on mobile devices - if( isMobileDevice ) { - toArray( dom.slides.querySelectorAll( 'video, audio' ) ).forEach( function( el ) { - el.controls = true; - } ); - } - } /** @@ -3859,7 +3852,20 @@ // Mobile devices never fire a loaded event so instead // of waiting, we initiate playback else if( isMobileDevice ) { - el.play(); + var promise = el.play(); + + // If autoplay does not work, ensure that the controls are visible so + // that the viewer can start the media on their own + if( promise && typeof promise.catch === 'function' && el.controls === false ) { + promise.catch( function() { + el.controls = true; + + // Once the video does start playing, hide the controls again + el.addEventListener( 'play', function() { + el.controls = false; + } ); + } ); + } } // If the media isn't loaded, wait before playing else { -- cgit v1.2.3 From 43d1c711078c94253770b3656b97dc67fc85f4c7 Mon Sep 17 00:00:00 2001 From: "Dougal J. Sutherland" Date: Thu, 31 Jan 2019 18:28:38 +0000 Subject: allow custom slide numbering functions --- js/reveal.js | 60 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 26 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 08ece7f..240dc42 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3257,40 +3257,48 @@ * "h/v": horizontal / vertical slide number * "c": flattened slide number * "c/t": flattened slide number / total slides + * + * Alternatively, config.slideNumber can be a function returning a + * three-element array with arguments to formatSlideNumber(). */ function updateSlideNumber() { // Update slide number if enabled if( config.slideNumber && dom.slideNumber ) { - var value = []; + var value; var format = 'h.v'; - // Check if a custom number format is available - if( typeof config.slideNumber === 'string' ) { - format = config.slideNumber; - } - - // If there are ONLY vertical slides in this deck, always use - // a flattened slide number - if( !/c/.test( format ) && dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length === 1 ) { - format = 'c'; - } - - switch( format ) { - case 'c': - value.push( getSlidePastCount() + 1 ); - break; - case 'c/t': - value.push( getSlidePastCount() + 1, '/', getTotalSlides() ); - break; - case 'h/v': - value.push( indexh + 1 ); - if( isVerticalSlide() ) value.push( '/', indexv + 1 ); - break; - default: - value.push( indexh + 1 ); - if( isVerticalSlide() ) value.push( '.', indexv + 1 ); + if ( typeof config.slideNumber === 'function' ) { + value = config.slideNumber(); + } else { + // Check if a custom number format is available + if( typeof config.slideNumber === 'string' ) { + format = config.slideNumber; + } + + // If there are ONLY vertical slides in this deck, always use + // a flattened slide number + if( !/c/.test( format ) && dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length === 1 ) { + format = 'c'; + } + + value = []; + switch( format ) { + case 'c': + value.push( getSlidePastCount() + 1 ); + break; + case 'c/t': + value.push( getSlidePastCount() + 1, '/', getTotalSlides() ); + break; + case 'h/v': + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '/', indexv + 1 ); + break; + default: + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '.', indexv + 1 ); + } } dom.slideNumber.innerHTML = formatSlideNumber( value[0], value[1], value[2] ); -- cgit v1.2.3 From 812b802c1cf896f2af44cd87eef63be4ecf98842 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 31 Jan 2019 20:13:32 +0100 Subject: resize event tweaks for #2300 --- README.md | 6 ++++-- js/reveal.js | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index 8439017..b8ad6a0 100644 --- a/README.md +++ b/README.md @@ -994,10 +994,12 @@ Limitations: ### Resize Event -When reveal.js changes the scale of the slides it fires an resize event. You can subscribe to the event to resize your elements accordingly. +When reveal.js changes the scale of the slides it fires a resize event. You can subscribe to the event to resize your elements accordingly. ```javascript -Reveal.addEventListener( 'resize', function( event ) { /* console.log(event.scale,event.oldscale,event.size); */ } ); +Reveal.addEventListener( 'resize', function( event ) { + // event.scale, event.oldScale, event.size +} ); ``` ### postMessage API diff --git a/js/reveal.js b/js/reveal.js index 8d150d8..e146752 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2097,6 +2097,8 @@ var size = getComputedSlideSize(); + var oldScale = scale; + // Layout the contents of the slides layoutSlideContents( config.width, config.height ); @@ -2104,7 +2106,6 @@ dom.slides.style.height = size.height + 'px'; // Determine scale of content to fit within available space - var oldscale =scale; scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); // Respect max/min scale settings @@ -2170,9 +2171,9 @@ } - if( oldscale!==scale ){ + if( oldScale !== scale ) { dispatchEvent( 'resize', { - 'oldscale': oldscale, + 'oldScale': oldScale, 'scale': scale, 'size': size } ); -- cgit v1.2.3 From 2a9edd23e69ee63a8a4f85a273508114777fad2e Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 1 Feb 2019 09:48:36 +0100 Subject: define available values for showSlideNumber --- js/reveal.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index e146752..8e5d24f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -73,7 +73,10 @@ // based) hashOneBasedIndex: false, - // Determine which displays to show the slide number on + // Controls which contexts the slide number should appear in + // - "all": Always show the slide number + // - "print": Only when printing to PDF + // - "speaker": Only in the speaker view showSlideNumber: 'all', // Add the current slide number to the URL hash so that reloading the -- cgit v1.2.3 From ce53e63b5b725243f1745971f632d4b46763a344 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 1 Feb 2019 10:15:10 +0100 Subject: documentation for #2315 --- README.md | 6 ++++++ js/reveal.js | 39 ++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'js') diff --git a/README.md b/README.md index b8ad6a0..53183ad 100644 --- a/README.md +++ b/README.md @@ -937,6 +937,12 @@ Reveal.configure({ slideNumber: true }); // "c/t": flattened slide number / total slides Reveal.configure({ slideNumber: 'c/t' }); +// You can provide a function to fully customize the number: +Reveal.configure({ slideNumber: function() { + // Ignore numbering of vertical slides + return [ Reveal.getIndices().h ]; +}}); + // Control which views the slide number displays on using the "showSlideNumber" value: // "all": show on all views (default) // "speaker": only show slide numbers on speaker notes view diff --git a/js/reveal.js b/js/reveal.js index 8feb45d..237c0c4 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -67,18 +67,31 @@ progress: true, // Display the page number of the current slide + // - true: Show slide number + // - false: Hide slide number + // + // Can optionally be set as a string that specifies the number formatting: + // - "h.v": Horizontal . vertical slide number (default) + // - "h/v": Horizontal / vertical slide number + // - "c": Flattened slide number + // - "c/t": Flattened slide number / total slides + // + // Alternatively, you can provide a function that returns the slide + // number for the current slide. The function needs to return an array + // with one string [slideNumber] or three strings [n1,delimiter,n2]. + // See #formatSlideNumber(). slideNumber: false, - // Use 1 based indexing for # links to match slide number (default is zero - // based) - hashOneBasedIndex: false, - - // Controls which contexts the slide number should appear in + // Can be used to limit the contexts in which the slide number appears // - "all": Always show the slide number // - "print": Only when printing to PDF // - "speaker": Only in the speaker view showSlideNumber: 'all', + // Use 1 based indexing for # links to match slide number (default is zero + // based) + hashOneBasedIndex: false, + // Add the current slide number to the URL hash so that reloading the // page/copying the URL will return you to the same slide hash: false, @@ -3262,16 +3275,7 @@ /** - * Updates the slide number div to reflect the current slide. - * - * The following slide number formats are available: - * "h.v": horizontal . vertical slide number (default) - * "h/v": horizontal / vertical slide number - * "c": flattened slide number - * "c/t": flattened slide number / total slides - * - * Alternatively, config.slideNumber can be a function returning a - * three-element array with arguments to formatSlideNumber(). + * Updates the slide number to match the current slide. */ function updateSlideNumber() { @@ -3281,9 +3285,10 @@ var value; var format = 'h.v'; - if ( typeof config.slideNumber === 'function' ) { + if( typeof config.slideNumber === 'function' ) { value = config.slideNumber(); - } else { + } + else { // Check if a custom number format is available if( typeof config.slideNumber === 'string' ) { format = config.slideNumber; -- cgit v1.2.3 From a36f7cbf99c1af6ed973f382708311bcec912841 Mon Sep 17 00:00:00 2001 From: "Dougal J. Sutherland" Date: Thu, 28 Feb 2019 01:19:43 +0000 Subject: remove unused `isPrintingPDFFragments` function --- js/reveal.js | 9 --------- 1 file changed, 9 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 237c0c4..a17a33a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1829,15 +1829,6 @@ } - /** - * Check if this instance is being used to print a PDF with fragments. - */ - function isPrintingPDFFragments() { - - return ( /print-pdf-fragments/gi ).test( window.location.search ); - - } - /** * Hides the address bar if we're on a mobile device. */ -- cgit v1.2.3 From 4862de26eb75d44b36849ef574db986203d3c879 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 1 Mar 2019 21:28:52 +0100 Subject: async loading of external markdown, add Reveal.registerPlugin() --- js/reveal.js | 104 ++++++++++++++++++------- plugin/markdown/markdown.js | 185 ++++++++++++++++++++++++++------------------ 2 files changed, 185 insertions(+), 104 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index a17a33a..9b29f78 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -319,6 +319,12 @@ // Cached references to DOM elements dom = {}, + // A list of registered reveal.js plugins + plugins = {}, + + // List of asynchronously loaded reveal.js dependencies + asyncDependencies = [], + // Features supported by the browser, see #checkCapabilities() features = {}, @@ -434,7 +440,7 @@ // Hide the address bar in mobile browsers hideAddressBar(); - // Loads the dependencies and continues to #start() once done + // Loads dependencies and continues to #start() once done load(); } @@ -489,37 +495,22 @@ function load() { var scripts = [], - scriptsAsync = [], - scriptsToPreload = 0; - - // Called once synchronous scripts finish loading - function afterSynchronousScriptsLoaded() { - // Load asynchronous scripts - if( scriptsAsync.length ) { - scriptsAsync.forEach( function( s ) { - loadScript( s.src, s.callback ); - } ); - } - - start(); - } - - for( var i = 0, len = config.dependencies.length; i < len; i++ ) { - var s = config.dependencies[i]; + scriptsToLoad = 0; + config.dependencies.forEach( function( s ) { // Load if there's no condition or the condition is truthy if( !s.condition || s.condition() ) { if( s.async ) { - scriptsAsync.push( s ); + asyncDependencies.push( s ); } else { scripts.push( s ); } } - } + } ); if( scripts.length ) { - scriptsToPreload = scripts.length; + scriptsToLoad = scripts.length; // Load synchronous scripts scripts.forEach( function( s ) { @@ -527,21 +518,66 @@ if( typeof s.callback === 'function' ) s.callback(); - if( --scriptsToPreload === 0 ) { - - afterSynchronousScriptsLoaded(); - + if( --scriptsToLoad === 0 ) { + loadPlugins(); } } ); } ); } else { - afterSynchronousScriptsLoaded(); + loadPlugins(); + } + + } + + /** + * Loads all plugins that require preloading. + */ + function loadPlugins() { + + var pluginsToLoad = Object.keys( plugins ).length; + + for( var i in plugins ) { + + var plugin = plugins[i]; + + // If the plugin has an 'init' method, initialize and + // wait for the callback + if( typeof plugin.init === 'function' ) { + plugin.init( function() { + if( --pluginsToLoad === 0 ) { + loadAsyncDependencies(); + } + } ); + } + else { + pluginsToLoad -= 1; + } + + } + + if( pluginsToLoad === 0 ) { + loadAsyncDependencies(); } } + /** + * Loads all async reveal.js dependencies. + */ + function loadAsyncDependencies() { + + if( asyncDependencies.length ) { + asyncDependencies.forEach( function( s ) { + loadScript( s.src, s.callback ); + } ); + } + + start(); + + } + /** * Loads a JavaScript file from the given URL and executes it. * @@ -1512,6 +1548,15 @@ } + /** + * Registers a new plugin with this reveal.js instance. + */ + function registerPlugin( id, plugin ) { + + plugins[id] = plugin; + + } + /** * Add a custom key binding with optional description to * be added to the help screen. @@ -5845,12 +5890,13 @@ } }, - // Adds a custom key binding + // Adds/remvoes a custom key binding addKeyBinding: addKeyBinding, - - // Removes a custom key binding removeKeyBinding: removeKeyBinding, + // Called by plugins to register/unregister themselves + registerPlugin: registerPlugin, + // Programatically triggers a keyboard event triggerKey: function( keyCode ) { onDocumentKeyDown( { keyCode: keyCode } ); diff --git a/plugin/markdown/markdown.js b/plugin/markdown/markdown.js index 31029ae..181116d 100755 --- a/plugin/markdown/markdown.js +++ b/plugin/markdown/markdown.js @@ -7,13 +7,11 @@ if (typeof define === 'function' && define.amd) { root.marked = require( './marked' ); root.RevealMarkdown = factory( root.marked ); - root.RevealMarkdown.initialize(); } else if( typeof exports === 'object' ) { module.exports = factory( require( './marked' ) ); } else { // Browser globals (root is window) root.RevealMarkdown = factory( root.marked ); - root.RevealMarkdown.initialize(); } }( this, function( marked ) { @@ -24,6 +22,10 @@ var SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; + var markdownFilesToLoad = 0; + + var loadCallback; + /** * Retrieves the markdown contents of a slide section @@ -199,73 +201,85 @@ */ function processSlides() { - var sections = document.querySelectorAll( '[data-markdown]'), - section; + [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { - for( var i = 0, len = sections.length; i < len; i++ ) { + if( section.getAttribute( 'data-markdown' ).length ) { - section = sections[i]; + loadExternalMarkdown( section ); - if( section.getAttribute( 'data-markdown' ).length ) { + } + else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { + + section.outerHTML = slidify( getMarkdownFromSlide( section ), { + separator: section.getAttribute( 'data-separator' ), + verticalSeparator: section.getAttribute( 'data-separator-vertical' ), + notesSeparator: section.getAttribute( 'data-separator-notes' ), + attributes: getForwardedAttributes( section ) + }); - var xhr = new XMLHttpRequest(), - url = section.getAttribute( 'data-markdown' ); + } + else { + section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); + } - datacharset = section.getAttribute( 'data-charset' ); + }); - // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes - if( datacharset != null && datacharset != '' ) { - xhr.overrideMimeType( 'text/html; charset=' + datacharset ); - } + checkIfLoaded(); - xhr.onreadystatechange = function() { - if( xhr.readyState === 4 ) { - // file protocol yields status code 0 (useful for local debug, mobile applications etc.) - if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { + } - section.outerHTML = slidify( xhr.responseText, { - separator: section.getAttribute( 'data-separator' ), - verticalSeparator: section.getAttribute( 'data-separator-vertical' ), - notesSeparator: section.getAttribute( 'data-separator-notes' ), - attributes: getForwardedAttributes( section ) - }); + function loadExternalMarkdown( section ) { - } - else { + markdownFilesToLoad += 1; - section.outerHTML = '
' + - 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + - 'Check your browser\'s JavaScript console for more details.' + - '

Remember that you need to serve the presentation HTML from a HTTP server.

' + - '
'; + var xhr = new XMLHttpRequest(), + url = section.getAttribute( 'data-markdown' ); - } - } - }; + datacharset = section.getAttribute( 'data-charset' ); + + // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes + if( datacharset != null && datacharset != '' ) { + xhr.overrideMimeType( 'text/html; charset=' + datacharset ); + } + + xhr.onreadystatechange = function( section, xhr ) { + if( xhr.readyState === 4 ) { + // file protocol yields status code 0 (useful for local debug, mobile applications etc.) + if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { - xhr.open( 'GET', url, false ); + section.outerHTML = slidify( xhr.responseText, { + separator: section.getAttribute( 'data-separator' ), + verticalSeparator: section.getAttribute( 'data-separator-vertical' ), + notesSeparator: section.getAttribute( 'data-separator-notes' ), + attributes: getForwardedAttributes( section ) + }); - try { - xhr.send(); } - catch ( e ) { - alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); + else { + + section.outerHTML = '
' + + 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + + 'Check your browser\'s JavaScript console for more details.' + + '

Remember that you need to serve the presentation HTML from a HTTP server.

' + + '
'; + } - } - else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { + convertSlides(); - section.outerHTML = slidify( getMarkdownFromSlide( section ), { - separator: section.getAttribute( 'data-separator' ), - verticalSeparator: section.getAttribute( 'data-separator-vertical' ), - notesSeparator: section.getAttribute( 'data-separator-notes' ), - attributes: getForwardedAttributes( section ) - }); + markdownFilesToLoad -= 1; + checkIfLoaded(); } - else { - section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); - } + }.bind( this, section, xhr ); + + xhr.open( 'GET', url, true ); + + try { + xhr.send(); + } + catch ( e ) { + alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); } } @@ -342,44 +356,56 @@ */ function convertSlides() { - var sections = document.querySelectorAll( '[data-markdown]'); + var sections = document.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])'); - for( var i = 0, len = sections.length; i < len; i++ ) { + [].slice.call( sections ).forEach( function( section ) { - var section = sections[i]; + section.setAttribute( 'data-markdown-parsed', true ) - // Only parse the same slide once - if( !section.getAttribute( 'data-markdown-parsed' ) ) { + var notes = section.querySelector( 'aside.notes' ); + var markdown = getMarkdownFromSlide( section ); - section.setAttribute( 'data-markdown-parsed', true ) + section.innerHTML = marked( markdown ); + addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) || + section.parentNode.getAttribute( 'data-element-attributes' ) || + DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR, + section.getAttribute( 'data-attributes' ) || + section.parentNode.getAttribute( 'data-attributes' ) || + DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR); - var notes = section.querySelector( 'aside.notes' ); - var markdown = getMarkdownFromSlide( section ); + // If there were notes, we need to re-add them after + // having overwritten the section's HTML + if( notes ) { + section.appendChild( notes ); + } - section.innerHTML = marked( markdown ); - addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) || - section.parentNode.getAttribute( 'data-element-attributes' ) || - DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR, - section.getAttribute( 'data-attributes' ) || - section.parentNode.getAttribute( 'data-attributes' ) || - DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR); + } ); - // If there were notes, we need to re-add them after - // having overwritten the section's HTML - if( notes ) { - section.appendChild( notes ); - } + } - } + function checkIfLoaded() { + if( markdownFilesToLoad === 0 ) { + if( loadCallback ) { + loadCallback(); + loadCallback = null; + } } } // API - return { + var RevealMarkdown = { + + /** + * Starts processing and converting Markdown within the + * current reveal.js deck. + * + * @param {function} callback function to invoke once + * we've finished loading and parsing Markdown + */ + init: function( callback ) { - initialize: function() { if( typeof marked === 'undefined' ) { throw 'The reveal.js Markdown plugin requires marked to be loaded'; } @@ -392,14 +418,17 @@ }); } + // marked can be configured via reveal.js config options var options = Reveal.getConfig().markdown; - - if ( options ) { + if( options ) { marked.setOptions( options ); } + loadCallback = callback; + processSlides(); convertSlides(); + }, // TODO: Do these belong in the API? @@ -409,4 +438,10 @@ }; + // Register our plugin so that reveal.js will call our + // plugin 'init' method as part of the initialization + Reveal.registerPlugin( 'markdown', RevealMarkdown ); + + return RevealMarkdown; + })); -- cgit v1.2.3 From 46f8f86fa1d682e913459c13b5131f2baa25bcb5 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 1 Mar 2019 21:34:11 +0100 Subject: few plugin registration tweaks --- js/reveal.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 9b29f78..9da7f8f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -519,24 +519,25 @@ if( typeof s.callback === 'function' ) s.callback(); if( --scriptsToLoad === 0 ) { - loadPlugins(); + initPlugins(); } } ); } ); } else { - loadPlugins(); + initPlugins(); } } /** - * Loads all plugins that require preloading. + * Initializes our plugins and waits for them to be ready + * before proceeding. */ - function loadPlugins() { + function initPlugins() { - var pluginsToLoad = Object.keys( plugins ).length; + var pluginsToInitialize = Object.keys( plugins ).length; for( var i in plugins ) { @@ -546,18 +547,18 @@ // wait for the callback if( typeof plugin.init === 'function' ) { plugin.init( function() { - if( --pluginsToLoad === 0 ) { + if( --pluginsToInitialize === 0 ) { loadAsyncDependencies(); } } ); } else { - pluginsToLoad -= 1; + pluginsToInitialize -= 1; } } - if( pluginsToLoad === 0 ) { + if( pluginsToInitialize === 0 ) { loadAsyncDependencies(); } @@ -5894,7 +5895,7 @@ addKeyBinding: addKeyBinding, removeKeyBinding: removeKeyBinding, - // Called by plugins to register/unregister themselves + // Called by plugins to register themselves registerPlugin: registerPlugin, // Programatically triggers a keyboard event -- cgit v1.2.3 From d780352b7f78e16635ce9fabf2dbb53639610f18 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 4 Mar 2019 14:11:21 +0100 Subject: reveal.js plugin flow now uses promises, refactor markdown plugin to use promises --- js/reveal.js | 17 +++++- plugin/markdown/markdown.js | 145 ++++++++++++++++++++++---------------------- plugin/notes/notes.js | 32 ++++++---- 3 files changed, 109 insertions(+), 85 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 9da7f8f..f408048 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -546,7 +546,7 @@ // If the plugin has an 'init' method, initialize and // wait for the callback if( typeof plugin.init === 'function' ) { - plugin.init( function() { + plugin.init().then( function() { if( --pluginsToInitialize === 0 ) { loadAsyncDependencies(); } @@ -1551,11 +1551,21 @@ /** * Registers a new plugin with this reveal.js instance. + * + * reveal.js waits for all regisered plugins to initialize + * before considering itself ready, as long as the plugin + * is registered before calling `Reveal.initialize()`. */ function registerPlugin( id, plugin ) { plugins[id] = plugin; + // If a plugin is registered after reveal.js is loaded, + // initialize it right away + if( loaded && typeof plugin.init === 'function' ) { + plugin.init(); + } + } /** @@ -5841,6 +5851,11 @@ return dom.wrapper || document.querySelector( '.reveal' ); }, + // Returns a hash with all registered plugins + getPlugins: function() { + return plugins; + }, + // Returns true if we're currently on the first slide isFirstSlide: function() { return ( indexh === 0 && indexv === 0 ); diff --git a/plugin/markdown/markdown.js b/plugin/markdown/markdown.js index 181116d..c641d81 100755 --- a/plugin/markdown/markdown.js +++ b/plugin/markdown/markdown.js @@ -22,10 +22,6 @@ var SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; - var markdownFilesToLoad = 0; - - var loadCallback; - /** * Retrieves the markdown contents of a slide section @@ -201,53 +197,41 @@ */ function processSlides() { - [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { - - if( section.getAttribute( 'data-markdown' ).length ) { - - loadExternalMarkdown( section ); - - } - else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { - - section.outerHTML = slidify( getMarkdownFromSlide( section ), { - separator: section.getAttribute( 'data-separator' ), - verticalSeparator: section.getAttribute( 'data-separator-vertical' ), - notesSeparator: section.getAttribute( 'data-separator-notes' ), - attributes: getForwardedAttributes( section ) - }); - - } - else { - section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); - } - - }); + return new Promise( function( resolve ) { - checkIfLoaded(); + var externalPromises = []; - } + [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { - function loadExternalMarkdown( section ) { + if( section.getAttribute( 'data-markdown' ).length ) { - markdownFilesToLoad += 1; + externalPromises.push( loadExternalMarkdown( section ).then( - var xhr = new XMLHttpRequest(), - url = section.getAttribute( 'data-markdown' ); + // Finished loading external file + function( xhr, url ) { + section.outerHTML = slidify( xhr.responseText, { + separator: section.getAttribute( 'data-separator' ), + verticalSeparator: section.getAttribute( 'data-separator-vertical' ), + notesSeparator: section.getAttribute( 'data-separator-notes' ), + attributes: getForwardedAttributes( section ) + }); + }, - datacharset = section.getAttribute( 'data-charset' ); + // Failed to load markdown + function( xhr, url ) { + section.outerHTML = '
' + + 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + + 'Check your browser\'s JavaScript console for more details.' + + '

Remember that you need to serve the presentation HTML from a HTTP server.

' + + '
'; + } - // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes - if( datacharset != null && datacharset != '' ) { - xhr.overrideMimeType( 'text/html; charset=' + datacharset ); - } + ) ); - xhr.onreadystatechange = function( section, xhr ) { - if( xhr.readyState === 4 ) { - // file protocol yields status code 0 (useful for local debug, mobile applications etc.) - if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { + } + else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { - section.outerHTML = slidify( xhr.responseText, { + section.outerHTML = slidify( getMarkdownFromSlide( section ), { separator: section.getAttribute( 'data-separator' ), verticalSeparator: section.getAttribute( 'data-separator-vertical' ), notesSeparator: section.getAttribute( 'data-separator-notes' ), @@ -256,31 +240,58 @@ } else { + section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); + } - section.outerHTML = '
' + - 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + - 'Check your browser\'s JavaScript console for more details.' + - '

Remember that you need to serve the presentation HTML from a HTTP server.

' + - '
'; + }); - } + Promise.all( externalPromises ).then( resolve ); + + } ); - convertSlides(); + } - markdownFilesToLoad -= 1; + function loadExternalMarkdown( section ) { - checkIfLoaded(); + return new Promise( function( resolve, reject ) { + + var xhr = new XMLHttpRequest(), + url = section.getAttribute( 'data-markdown' ); + + datacharset = section.getAttribute( 'data-charset' ); + + // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes + if( datacharset != null && datacharset != '' ) { + xhr.overrideMimeType( 'text/html; charset=' + datacharset ); } - }.bind( this, section, xhr ); - xhr.open( 'GET', url, true ); + xhr.onreadystatechange = function( section, xhr ) { + if( xhr.readyState === 4 ) { + // file protocol yields status code 0 (useful for local debug, mobile applications etc.) + if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { - try { - xhr.send(); - } - catch ( e ) { - alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); - } + resolve( xhr, url ); + + } + else { + + reject( xhr, url ); + + } + } + }.bind( this, section, xhr ); + + xhr.open( 'GET', url, true ); + + try { + xhr.send(); + } + catch ( e ) { + alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); + resolve( xhr, url ); + } + + } ); } @@ -381,16 +392,7 @@ } ); - } - - function checkIfLoaded() { - - if( markdownFilesToLoad === 0 ) { - if( loadCallback ) { - loadCallback(); - loadCallback = null; - } - } + return Promise.resolve(); } @@ -424,10 +426,7 @@ marked.setOptions( options ); } - loadCallback = callback; - - processSlides(); - convertSlides(); + return processSlides().then( convertSlides ); }, diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index 8d58ad0..718d149 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -151,20 +151,30 @@ 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 ) ) { + + // 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(); - } ); + // Open the notes when the 's' key is hit + Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { + openNotes(); + } ); - } + } + + return Promise.resolve(); - return { open: openNotes }; + }, + + open: openNotes + }; })(); + +Reveal.registerPlugin( 'notes', RevealNotes ); -- cgit v1.2.3 From 69ee643846e059c7b49264831c632bdf9701f8e0 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 11 Mar 2019 14:50:35 +0100 Subject: syncFragments now returns all affected fragments --- js/reveal.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index f408048..552ba5d 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2975,6 +2975,9 @@ */ function syncSlide( slide ) { + // Default to the current slide + slide = slide || Reveal.getCurrentSlide(); + syncBackground( slide ); syncFragments( slide ); @@ -2991,10 +2994,14 @@ * after reveal.js has already initialized. * * @param {HTMLElement} slide + * @return {Array} a list of the HTML fragments that were synced */ function syncFragments( slide ) { - sortFragments( slide.querySelectorAll( '.fragment' ) ); + // Default to the current slide + slide = slide || Reveal.getCurrentSlide(); + + return sortFragments( slide.querySelectorAll( '.fragment' ) ); } -- cgit v1.2.3 From 5adc2032c0d9d49a8b784d4a4f271999ad7e63a9 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 11 Mar 2019 15:03:13 +0100 Subject: use internal pointer for current slide --- js/reveal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 552ba5d..616a935 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2976,7 +2976,7 @@ function syncSlide( slide ) { // Default to the current slide - slide = slide || Reveal.getCurrentSlide(); + slide = slide || currentSlide; syncBackground( slide ); syncFragments( slide ); @@ -2999,7 +2999,7 @@ function syncFragments( slide ) { // Default to the current slide - slide = slide || Reveal.getCurrentSlide(); + slide = slide || currentSlide; return sortFragments( slide.querySelectorAll( '.fragment' ) ); -- cgit v1.2.3 From 7b62a0f3566bf788fc14ba51e5b6e0e8cc34b637 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 12 Mar 2019 13:17:08 +0100 Subject: prevent same plugin from being registered twice --- js/reveal.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 616a935..1ef10aa 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1558,12 +1558,17 @@ */ function registerPlugin( id, plugin ) { - plugins[id] = plugin; + if( plugins[id] === undefined ) { + plugins[id] = plugin; - // If a plugin is registered after reveal.js is loaded, - // initialize it right away - if( loaded && typeof plugin.init === 'function' ) { - plugin.init(); + // If a plugin is registered after reveal.js is loaded, + // initialize it right away + if( loaded && typeof plugin.init === 'function' ) { + plugin.init(); + } + } + else { + console.warn( 'reveal.js: "'+ id +'" plugin has already been registered' ); } } -- cgit v1.2.3 From 6410ed15aa5ce2bdfc1f7f02c818a562ec8a1fc4 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 14 Mar 2019 14:52:59 +0100 Subject: support for plugins where the init method doesn't return a Promise --- js/reveal.js | 29 +++++++++++++++++------------ plugin/highlight/highlight.js | 2 -- plugin/math/math.js | 2 -- plugin/notes/notes.js | 2 -- plugin/zoom-js/zoom.js | 2 -- 5 files changed, 17 insertions(+), 20 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 1ef10aa..51b1ed0 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -539,29 +539,34 @@ var pluginsToInitialize = Object.keys( plugins ).length; + var afterPlugInitialized = function() { + if( --pluginsToInitialize === 0 ) { + loadAsyncDependencies(); + } + }; + for( var i in plugins ) { var plugin = plugins[i]; - // If the plugin has an 'init' method, initialize and - // wait for the callback + // If the plugin has an 'init' method, invoke it if( typeof plugin.init === 'function' ) { - plugin.init().then( function() { - if( --pluginsToInitialize === 0 ) { - loadAsyncDependencies(); - } - } ); + var callback = plugin.init(); + + // If the plugin returned a Promise, wait for it + if( callback && typeof callback.then === 'function' ) { + callback.then( afterPlugInitialized ); + } + else { + afterPlugInitialized(); + } } else { - pluginsToInitialize -= 1; + afterPlugInitialized(); } } - if( pluginsToInitialize === 0 ) { - loadAsyncDependencies(); - } - } /** diff --git a/plugin/highlight/highlight.js b/plugin/highlight/highlight.js index 6d6910b..b3599e8 100644 --- a/plugin/highlight/highlight.js +++ b/plugin/highlight/highlight.js @@ -97,8 +97,6 @@ c:[{cN:"comment",b:/\(\*/,e:/\*\)/},e.ASM,e.QSM,e.CNM,{b:/\{/,e:/\}/,i:/:/}]}}); } } ); - return Promise.resolve(); - }, /** diff --git a/plugin/math/math.js b/plugin/math/math.js index b78d120..d76c9dd 100755 --- a/plugin/math/math.js +++ b/plugin/math/math.js @@ -84,8 +84,6 @@ var RevealMath = window.RevealMath || (function(){ } ); - return Promise.resolve(); - } } diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index 54dcf31..3d5eac4 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -168,8 +168,6 @@ var RevealNotes = (function() { } - return Promise.resolve(); - }, open: openNotes diff --git a/plugin/zoom-js/zoom.js b/plugin/zoom-js/zoom.js index 031514d..92c3ba5 100644 --- a/plugin/zoom-js/zoom.js +++ b/plugin/zoom-js/zoom.js @@ -22,8 +22,6 @@ var RevealZoom = (function(){ } } ); - return Promise.resolve(); - } } -- cgit v1.2.3 From b180d94e0227558de766af47b37d96693a942b60 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 14 Mar 2019 15:39:19 +0100 Subject: fix error when reveal.js was initialized with no plugins --- js/reveal.js | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'js') diff --git a/js/reveal.js b/js/reveal.js index 51b1ed0..387077a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -539,30 +539,39 @@ var pluginsToInitialize = Object.keys( plugins ).length; - var afterPlugInitialized = function() { - if( --pluginsToInitialize === 0 ) { - loadAsyncDependencies(); - } - }; + // If there are no plugins, skip this step + if( pluginsToInitialize === 0 ) { + loadAsyncDependencies(); + } + // ... otherwise initialize plugins + else { + + var afterPlugInitialized = function() { + if( --pluginsToInitialize === 0 ) { + loadAsyncDependencies(); + } + }; - for( var i in plugins ) { + for( var i in plugins ) { - var plugin = plugins[i]; + var plugin = plugins[i]; - // If the plugin has an 'init' method, invoke it - if( typeof plugin.init === 'function' ) { - var callback = plugin.init(); + // If the plugin has an 'init' method, invoke it + if( typeof plugin.init === 'function' ) { + var callback = plugin.init(); - // If the plugin returned a Promise, wait for it - if( callback && typeof callback.then === 'function' ) { - callback.then( afterPlugInitialized ); + // If the plugin returned a Promise, wait for it + if( callback && typeof callback.then === 'function' ) { + callback.then( afterPlugInitialized ); + } + else { + afterPlugInitialized(); + } } else { afterPlugInitialized(); } - } - else { - afterPlugInitialized(); + } } -- cgit v1.2.3