From f070ba47ecd14fa18777e138e065752fec772c4c Mon Sep 17 00:00:00 2001 From: RobertBaron Date: Thu, 23 Feb 2017 19:03:15 -0600 Subject: Allow whitespace on background-images, w3 compliance --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 65560a6..841cbb6 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3085,7 +3085,7 @@ // Images if( backgroundImage ) { - background.style.backgroundImage = 'url('+ backgroundImage +')'; + background.style.backgroundImage = 'url('+ encodeURI(backgroundImage) +')'; } // Videos else if ( backgroundVideo && !isSpeakerNotes() ) { -- cgit v1.2.3 From 7297474b2e683f6e6e382891b2ec36e7f22c0764 Mon Sep 17 00:00:00 2001 From: Greg Denehy Date: Sun, 30 Apr 2017 15:23:04 +0930 Subject: Added programatic support for custom key bindings with optional descriptions to be added to the help screen --- js/reveal.js | 71 +++++++++++++++++++++++++++++++++++++++++++++++++-- plugin/notes/notes.js | 14 +--------- 2 files changed, 70 insertions(+), 15 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e25337e..e8833c4 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -232,7 +232,10 @@ 'B , .': 'Pause', 'F': 'Fullscreen', 'ESC, O': 'Slide overview' - }; + }, + + // Holds custom key code mappings + registeredKeyBindings = {}; /** * Starts up the presentation if the client is capable. @@ -1091,6 +1094,33 @@ } + /** + * Add a custom key binding with optional description to be added to the help screen + */ + function addKeyBinding(binding, callback) { + if (typeof binding === 'object' && binding.code) { + registeredKeyBindings[binding.code] = { + callback: callback, + key: binding.key, + description: binding.description + } + } + else { + registeredKeyBindings[binding] = { + callback: callback, + key: null, + description: null + } + } + } + + /** + * Removes the specified custom key binding + */ + function removeKeyBinding(binding) { + delete registeredKeyBindings[binding]; + } + /** * Extend object a with the properties of object b. * If there's a conflict, object b takes precedence. @@ -1518,6 +1548,13 @@ html += '' + key + '' + keyboardShortcuts[ key ] + ''; } + // add custom key bindings that have associated descriptions + for( var binding in registeredKeyBindings ) { + if (registeredKeyBindings[binding].key && registeredKeyBindings[binding].description) { + html += '' + registeredKeyBindings[binding].key + '' + registeredKeyBindings[binding].description + ''; + } + } + html += ''; dom.overlay.innerHTML = [ @@ -3967,7 +4004,31 @@ } - // 2. System defined key bindings + // 2. Registered custom key bindings + if( triggered === false ) { + + for( key in registeredKeyBindings ) { + + // Check if this binding matches the pressed key + if( parseInt( key, 10 ) === event.keyCode ) { + + var value = registeredKeyBindings[ key ].callback; + + // Callback function + if( typeof value === 'function' ) { + value.apply( null, [ event ] ); + } + // String shortcuts to reveal.js API + else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) { + Reveal[ value ].call(); + } + + triggered = true; + } + } + } + + // 3. System defined key bindings if( triggered === false ) { // Assume true and try to prove false @@ -4676,6 +4737,12 @@ } }, + // Adds a custom key binding + addKeyBinding: addKeyBinding, + + // Removes a custom key binding + removeKeyBinding: removeKeyBinding, + // Programatically triggers a keyboard event triggerKey: function( keyCode ) { onDocumentKeyDown( { keyCode: keyCode } ); diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index 202e73b..8980fb4 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -106,19 +106,7 @@ var RevealNotes = (function() { } // Open the notes when the 's' key is hit - document.addEventListener( 'keydown', function( event ) { - // Disregard the event if the target is editable or a - // modifier is present - if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; - - // Disregard the event if keyboard is disabled - if ( Reveal.getConfig().keyboard === false ) return; - - if( event.keyCode === 83 ) { - event.preventDefault(); - openNotes(); - } - }, false ); + Reveal.addKeyBinding({code: 83, key: 'S', description: 'Speaker notes'}, openNotes); } -- cgit v1.2.3 From 8bf9986fa21c89b9b38145b43e6fe572c3acebd5 Mon Sep 17 00:00:00 2001 From: Greg Denehy Date: Sun, 30 Apr 2017 15:24:42 +0930 Subject: Pass through key event when calling keyboardCondition() to allow conditional function to filter on key codes --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e8833c4..9d4444f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3940,7 +3940,7 @@ // If there's a condition specified and it returns false, // ignore this event - if( typeof config.keyboardCondition === 'function' && config.keyboardCondition() === false ) { + if( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) { return true; } -- cgit v1.2.3 From e48e1e19b97d99de107966dd3f8c431a89457972 Mon Sep 17 00:00:00 2001 From: Greg Denehy Date: Sun, 30 Apr 2017 16:35:35 +0930 Subject: Changed custom key binding config properties to use 'keyCode' instead of 'code' --- js/reveal.js | 4 ++-- plugin/notes/notes.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 9d4444f..328edb0 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1098,8 +1098,8 @@ * Add a custom key binding with optional description to be added to the help screen */ function addKeyBinding(binding, callback) { - if (typeof binding === 'object' && binding.code) { - registeredKeyBindings[binding.code] = { + if (typeof binding === 'object' && binding.keyCode) { + registeredKeyBindings[binding.keyCode] = { callback: callback, key: binding.key, description: binding.description diff --git a/plugin/notes/notes.js b/plugin/notes/notes.js index 8980fb4..6373d97 100644 --- a/plugin/notes/notes.js +++ b/plugin/notes/notes.js @@ -106,7 +106,7 @@ var RevealNotes = (function() { } // Open the notes when the 's' key is hit - Reveal.addKeyBinding({code: 83, key: 'S', description: 'Speaker notes'}, openNotes); + Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes'}, openNotes); } -- cgit v1.2.3 From b86b667d2552b32dd0a6d52a210fcf6bbb132867 Mon Sep 17 00:00:00 2001 From: Greg Denehy Date: Sun, 30 Apr 2017 19:42:45 +0930 Subject: Changes to fix failed jshint test related to Key Binding API --- js/reveal.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 4e44b01..0bdcd12 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1234,14 +1234,14 @@ callback: callback, key: binding.key, description: binding.description - } + }; } else { registeredKeyBindings[binding] = { callback: callback, key: null, description: null - } + }; } } @@ -4386,15 +4386,15 @@ // Check if this binding matches the pressed key if( parseInt( key, 10 ) === event.keyCode ) { - var value = registeredKeyBindings[ key ].callback; + var action = registeredKeyBindings[ key ].callback; // Callback function - if( typeof value === 'function' ) { - value.apply( null, [ event ] ); + if( typeof action === 'function' ) { + action.apply( null, [ event ] ); } // String shortcuts to reveal.js API - else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) { - Reveal[ value ].call(); + else if( typeof action === 'string' && typeof Reveal[ action ] === 'function' ) { + Reveal[ action ].call(); } triggered = true; -- cgit v1.2.3 From a2cf23b30cbd962d752df5b9a8fc46f074fab20d Mon Sep 17 00:00:00 2001 From: Maximilian Köhl Date: Tue, 8 Aug 2017 22:47:10 +0200 Subject: PDF export: add option to export one page per fragment --- js/reveal.js | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index d3ba03c..4508add 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -727,14 +727,39 @@ numberElement.innerHTML = formatSlideNumber( slideNumberH, '.', slideNumberV ); page.appendChild( numberElement ); } + + // Copy page and show fragments one after another + if ( isPrintingPDFFragments() ) { + + var numberOfFragments = toArray( page.querySelectorAll( '.fragment' ) ).length; + + for ( var currentFragment = 0; currentFragment < numberOfFragments; currentFragment++ ) { + var clonedPage = page.cloneNode( true ); + page.parentNode.insertBefore( clonedPage, page.nextSibling ); + + toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ))).forEach( function ( fragment, fragmentIndex ) { + if ( fragmentIndex <= currentFragment ) { + fragment.classList.add( 'visible' ); + } else { + fragment.classList.remove( 'visible' ); + } + } ); + + page = clonedPage; + } + + } + // Show all fragments + else { + toArray( page.querySelectorAll( '.fragment' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + } ); + } + } } ); - // Show all fragments - toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' .fragment' ) ).forEach( function( fragment ) { - fragment.classList.add( 'visible' ); - } ); // Notify subscribers that the PDF layout is good to go dispatchEvent( 'pdf-ready' ); @@ -1497,6 +1522,15 @@ } + /** + * 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 08e0f5e47b73d01f5afa82e79b9046a2a694855d Mon Sep 17 00:00:00 2001 From: Maximilian Köhl Date: Tue, 8 Aug 2017 22:53:32 +0200 Subject: fix indent: replace spaces with tabs --- js/reveal.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 4508add..0f5cacd 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -734,19 +734,19 @@ var numberOfFragments = toArray( page.querySelectorAll( '.fragment' ) ).length; for ( var currentFragment = 0; currentFragment < numberOfFragments; currentFragment++ ) { - var clonedPage = page.cloneNode( true ); - page.parentNode.insertBefore( clonedPage, page.nextSibling ); - - toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ))).forEach( function ( fragment, fragmentIndex ) { - if ( fragmentIndex <= currentFragment ) { - fragment.classList.add( 'visible' ); - } else { - fragment.classList.remove( 'visible' ); - } - } ); - - page = clonedPage; - } + var clonedPage = page.cloneNode( true ); + page.parentNode.insertBefore( clonedPage, page.nextSibling ); + + toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ))).forEach( function ( fragment, fragmentIndex ) { + if ( fragmentIndex <= currentFragment ) { + fragment.classList.add( 'visible' ); + } else { + fragment.classList.remove( 'visible' ); + } + } ); + + page = clonedPage; + } } // Show all fragments @@ -1522,12 +1522,12 @@ } - /** + /** * Check if this instance is being used to print a PDF with fragments. - */ - function isPrintingPDFFragments() { + */ + function isPrintingPDFFragments() { - return ( /print-pdf-fragments/gi ).test( window.location.search ); + return ( /print-pdf-fragments/gi ).test( window.location.search ); } -- cgit v1.2.3 From fa8a7334ce2ea99a736dd5e72734b08fc01c6fdc Mon Sep 17 00:00:00 2001 From: Nicolas Normand Date: Fri, 17 Nov 2017 11:59:21 +0100 Subject: URI encode name hash --- js/reveal.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index d3ba03c..3747e15 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3563,10 +3563,11 @@ var element; // Ensure the named link is a valid HTML ID attribute - if( /^[a-zA-Z][\w:.-]*$/.test( name ) ) { - // Find the slide with the specified ID - element = document.getElementById( name ); - } + try { + element = document.getElementById( decodeURIComponent( name ) ); + } + catch (e) { + } if( element ) { // Find the position of the named slide and navigate to it @@ -3614,7 +3615,7 @@ // Attempt to create a named link based on the slide's ID var id = currentSlide.getAttribute( 'id' ); if( id ) { - id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' ); + id = encodeURIComponent( id ); } // If the current slide has an ID, use that as a named link -- cgit v1.2.3 From a0a9aa78219ad54c1a8be2c478b91bc4ccfa36c1 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 23 Nov 2017 15:45:15 +0100 Subject: optimize use of getSlideBackground by avoiding index lookup --- js/reveal.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index f125c55..9a43903 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3200,8 +3200,7 @@ // Show the corresponding background element - var indices = getIndices( slide ); - var background = getSlideBackground( indices.h, indices.v ); + var background = getSlideBackground( slide ); if( background ) { background.style.display = 'block'; @@ -3288,8 +3287,7 @@ slide.style.display = 'none'; // Hide the corresponding background element - var indices = getIndices( slide ); - var background = getSlideBackground( indices.h, indices.v ); + var background = getSlideBackground( slide ); if( background ) { background.style.display = 'none'; } @@ -3858,13 +3856,14 @@ * defined, have a background element so as long as the * index is valid an element will be returned. * - * @param {number} x Horizontal background index + * @param {mixed} x Horizontal background index OR a slide + * HTML element * @param {number} y Vertical background index * @return {(HTMLElement[]|*)} */ function getSlideBackground( x, y ) { - var slide = getSlide( x, y ); + var slide = typeof x === 'number' ? getSlide( x, y ) : x; if( slide ) { return slide.slideBackgroundElement; } -- cgit v1.2.3 From 8579fc773d4e0a735e808635f12a2782d9e9623f Mon Sep 17 00:00:00 2001 From: Greg Denehy Date: Sat, 25 Nov 2017 11:07:09 +1030 Subject: Fixed issue with getProgress() when called from slidechanged event on edge case --- js/reveal.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 9a43903..1a98ac9 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2411,16 +2411,7 @@ // Dispatch an event if the slide changed var slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore ); - if( slideChanged ) { - dispatchEvent( 'slidechanged', { - 'indexh': indexh, - 'indexv': indexv, - 'previousSlide': previousSlide, - 'currentSlide': currentSlide, - 'origin': o - } ); - } - else { + if (!slideChanged) { // Ensure that the previous slide is never the same as the current previousSlide = null; } @@ -2448,6 +2439,16 @@ } } + if( slideChanged ) { + dispatchEvent( 'slidechanged', { + 'indexh': indexh, + 'indexv': indexv, + 'previousSlide': previousSlide, + 'currentSlide': currentSlide, + 'origin': o + } ); + } + // Handle embedded content if( slideChanged || !previousSlide ) { stopEmbeddedContent( previousSlide ); -- cgit v1.2.3 From c966c118fa34394b480b14273233c4d874388cbe Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 29 Nov 2017 09:46:45 +0100 Subject: minor formatting tweaks --- js/reveal.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 021c8d9..b1dd5fa 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1265,10 +1265,12 @@ } /** - * Add a custom key binding with optional description to be added to the help screen + * Add a custom key binding with optional description to + * be added to the help screen. */ - function addKeyBinding(binding, callback) { - if (typeof binding === 'object' && binding.keyCode) { + function addKeyBinding( binding, callback ) { + + if( typeof binding === 'object' && binding.keyCode ) { registeredKeyBindings[binding.keyCode] = { callback: callback, key: binding.key, @@ -1282,13 +1284,16 @@ description: null }; } + } /** - * Removes the specified custom key binding + * Removes the specified custom key binding. */ - function removeKeyBinding(binding) { - delete registeredKeyBindings[binding]; + function removeKeyBinding( keyCode ) { + + delete registeredKeyBindings[keyCode]; + } /** @@ -1778,9 +1783,9 @@ html += '' + key + '' + keyboardShortcuts[ key ] + ''; } - // add custom key bindings that have associated descriptions + // Add custom key bindings that have associated descriptions for( var binding in registeredKeyBindings ) { - if (registeredKeyBindings[binding].key && registeredKeyBindings[binding].description) { + if( registeredKeyBindings[binding].key && registeredKeyBindings[binding].description ) { html += '' + registeredKeyBindings[binding].key + '' + registeredKeyBindings[binding].description + ''; } } -- cgit v1.2.3 From 260f28792644055998c7237cf879ec2a9ffe857e Mon Sep 17 00:00:00 2001 From: Dougal J. Sutherland Date: Thu, 4 Jan 2018 20:09:01 +0000 Subject: optionally put the fragment in the URL --- README.md | 4 ++++ js/reveal.js | 32 +++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) (limited to 'js/reveal.js') diff --git a/README.md b/README.md index 9d71472..9a2d516 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,10 @@ Reveal.initialize({ // Turns fragments on and off globally fragments: true, + // Flags whether to include the current fragment in the URL, + // so that reloading brings you to the same fragment position + fragmentInURL: false, + // Flags if the presentation is running in an embedded mode, // i.e. contained within a limited portion of the screen embedded: false, diff --git a/js/reveal.js b/js/reveal.js index f125c55..8edf66a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -102,6 +102,10 @@ // Turns fragments on and off globally fragments: true, + // Flags whether to include the current fragment in the URL, + // so that reloading brings you to the same fragment position + fragmentInURL: false, + // Flags if the presentation is running in an embedded mode, // i.e. contained within a limited portion of the screen embedded: false, @@ -3709,10 +3713,14 @@ else { // Read the index components of the hash var h = parseInt( bits[0], 10 ) || 0, - v = parseInt( bits[1], 10 ) || 0; + v = parseInt( bits[1], 10 ) || 0, + f; + if( config.fragmentInURL ) { + f = parseInt( bits[2], 10 ) || undefined; + } - if( h !== indexh || v !== indexv ) { - slide( h, v ); + if( h !== indexh || v !== indexv || f !== undefined ) { + slide( h, v, f ); } } @@ -3745,14 +3753,21 @@ id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' ); } - // If the current slide has an ID, use that as a named link - if( typeof id === 'string' && id.length ) { + var indexf; + if( config.fragmentInURL ) { + indexf = getIndices().f; + } + + // If the current slide has an ID, use that as a named link, + // but we don't support named links with a fragment index + if( typeof id === 'string' && id.length && indexf === undefined ) { url = '/' + id; } // Otherwise use the /h/v index else { - if( indexh > 0 || indexv > 0 ) url += indexh; - if( indexv > 0 ) url += '/' + indexv; + if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh; + if( indexv > 0 || indexf !== undefined ) url += '/' + indexv; + if( indexf !== undefined ) url += '/' + indexf; } window.location.hash = url; @@ -4089,6 +4104,9 @@ updateControls(); updateProgress(); + if( config.fragmentInURL ) { + writeURL(); + } return !!( fragmentsShown.length || fragmentsHidden.length ); -- cgit v1.2.3 From d68423f310cc680352b561af3e975230e2ff54b1 Mon Sep 17 00:00:00 2001 From: Dougal J. Sutherland Date: Sun, 21 Jan 2018 18:03:48 +0000 Subject: fix fragment handling when desired fragment is 0 --- js/reveal.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 8edf66a..14b3685 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3716,7 +3716,10 @@ v = parseInt( bits[1], 10 ) || 0, f; if( config.fragmentInURL ) { - f = parseInt( bits[2], 10 ) || undefined; + f = parseInt( bits[2], 10 ); + if( isNaN( f ) ) { + f = undefined; + } } if( h !== indexh || v !== indexv || f !== undefined ) { -- cgit v1.2.3 From fd7894fa13d2d775bddc3e2597aa8fc066058e40 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Mon, 22 Jan 2018 16:33:10 +0800 Subject: Allow JS files with query strings to be loaded. Fixes #1944. --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e944572..9d5fb26 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -418,7 +418,7 @@ } function loadScript( s ) { - head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() { + head.ready( s.src.match( /([\w\d_\-]*)\.?js(\?[\w\d.=&]*)?$|[^\\\/]*$/i )[0], function() { // Extension may contain callback functions if( typeof s.callback === 'function' ) { s.callback.apply( this ); -- cgit v1.2.3 From 6816a0205e329a2564d0a198cf89285064e3bc24 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Mon, 22 Jan 2018 17:17:08 +0800 Subject: Allow `data-background` images to load even if there is whitespace at the end. Fixes #2032. --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e944572..7f12d10 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -916,7 +916,7 @@ if( data.background ) { // Auto-wrap image urls in url(...) - if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#]|$)/gi.test( data.background ) ) { + if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { slide.setAttribute( 'data-background-image', data.background ); } else { -- cgit v1.2.3 From de746bb64242820dc688b17f47935911ba7bfa86 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 25 Jan 2018 09:26:10 +0100 Subject: reorganize config options --- README.md | 8 +++++--- js/reveal.js | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'js/reveal.js') diff --git a/README.md b/README.md index 94726ab..0c77d0e 100644 --- a/README.md +++ b/README.md @@ -198,9 +198,6 @@ Reveal.initialize({ // Display a presentation progress bar progress: true, - // Set default timing of 2 minutes per slide - defaultTiming: 120, - // Display the page number of the current slide slideNumber: false, @@ -259,6 +256,11 @@ Reveal.initialize({ // Use this method for navigation when auto-sliding autoSlideMethod: Reveal.navigateNext, + // Specify the average time in seconds that you think you will spend + // presenting each slide. This is used to show a pacing timer in the + // speaker view + defaultTiming: 120, + // Enable slide navigation via mouse wheel mouseWheel: false, diff --git a/js/reveal.js b/js/reveal.js index 0120f31..c9fa9f1 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -135,6 +135,11 @@ // Use this method for navigation when auto-sliding (defaults to navigateNext) autoSlideMethod: null, + // Specify the average time in seconds that you think you will spend + // presenting each slide. This is used to show a pacing timer in the + // speaker view + defaultTiming: null, + // Enable slide navigation via mouse wheel mouseWheel: false, -- cgit v1.2.3 From e704b3ffc8eb55913ed6c8f80db0615b9a692b91 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 25 Jan 2018 09:59:04 +0100 Subject: fix bug where left/right arrows appeared when there were no horizontal slides --- js/reveal.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index c9fa9f1..df63b89 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3364,9 +3364,11 @@ var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); + var hasHorizontalSlides = horizontalSlides.length > 1; + var routes = { - left: indexh > 0 || config.loop, - right: indexh < horizontalSlides.length - 1 || config.loop, + left: indexh > 0 || ( config.loop && hasHorizontalSlides ), + right: indexh < horizontalSlides.length - 1 || ( config.loop && hasHorizontalSlides ), up: indexv > 0, down: indexv < verticalSlides.length - 1 }; -- cgit v1.2.3 From 27aba10756fdde8b041e80cf55742dfeef4b6228 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 7 Feb 2018 13:45:52 +0100 Subject: fix looping of presentations that only have vertical slides --- js/reveal.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 0d49957..e3ffeac 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3368,16 +3368,28 @@ var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); - var hasHorizontalSlides = horizontalSlides.length > 1; - var routes = { - left: indexh > 0 || ( config.loop && hasHorizontalSlides ), - right: indexh < horizontalSlides.length - 1 || ( config.loop && hasHorizontalSlides ), + left: indexh > 0, + right: indexh < horizontalSlides.length - 1, up: indexv > 0, down: indexv < verticalSlides.length - 1 }; - // reverse horizontal controls for rtl + // Looped presentations can always be navigated as long as + // there are slides available + if( config.loop ) { + if( horizontalSlides.length > 1 ) { + routes.left = true; + routes.right = true; + } + + if( verticalSlides.length > 1 ) { + routes.up = true; + routes.down = true; + } + } + + // Reverse horizontal controls for rtl if( config.rtl ) { var left = routes.left; routes.left = routes.right; -- cgit v1.2.3 From 18e7dd21731d4eca92e062b25e07462531b5b380 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Thu, 8 Feb 2018 11:22:01 +0800 Subject: Cleanup code style. --- js/reveal.js | 14 ++-- plugin/print-pdf/print-pdf.js | 18 ++-- plugin/search/search.js | 188 +++++++++++++++++++++--------------------- 3 files changed, 109 insertions(+), 111 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e3ffeac..2439a05 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -403,13 +403,13 @@ } - /** - * Loads the dependencies of reveal.js. Dependencies are - * defined via the configuration option 'dependencies' - * and will be loaded prior to starting/binding reveal.js. - * Some dependencies may have an 'async' flag, if so they - * will load after reveal.js has been started up. - */ + /** + * Loads the dependencies of reveal.js. Dependencies are + * defined via the configuration option 'dependencies' + * and will be loaded prior to starting/binding reveal.js. + * Some dependencies may have an 'async' flag, if so they + * will load after reveal.js has been started up. + */ function load() { var scripts = [], diff --git a/plugin/print-pdf/print-pdf.js b/plugin/print-pdf/print-pdf.js index 15ce43e..f62aedc 100644 --- a/plugin/print-pdf/print-pdf.js +++ b/plugin/print-pdf/print-pdf.js @@ -42,28 +42,26 @@ probePage.open( inputFile, function( status ) { printPage.open( inputFile, function( status ) { console.log( 'Export PDF: Preparing pdf [3/4]') - printPage.evaluate(function() { + printPage.evaluate( function() { Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom ); - }); + } ); } ); - printPage.onCallback = function(data) { + printPage.onCallback = function( data ) { // For some reason we need to "jump the queue" for syntax highlighting to work. // See: http://stackoverflow.com/a/3580132/129269 - setTimeout(function() { + setTimeout( function() { console.log( 'Export PDF: Writing file [4/4]' ); printPage.render( outputFile ); console.log( 'Export PDF: Finished successfully!' ); phantom.exit(); - }, 0); + }, 0 ); }; } else { - console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' ); - phantom.exit(1); + console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' ); + phantom.exit( 1 ); - } + } } ); - - diff --git a/plugin/search/search.js b/plugin/search/search.js index f7e5c2f..6d694d2 100644 --- a/plugin/search/search.js +++ b/plugin/search/search.js @@ -19,92 +19,92 @@ var RevealSearch = (function() { function Hilitor(id, tag) { - var targetNode = document.getElementById(id) || document.body; - var hiliteTag = tag || "EM"; - var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$"); - var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"]; - var wordColor = []; - var colorIdx = 0; - var matchRegex = ""; - var matchingSlides = []; - - this.setRegex = function(input) - { - input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|"); - matchRegex = new RegExp("(" + input + ")","i"); - } - - this.getRegex = function() - { - return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " "); - } - - // recursively apply word highlighting - this.hiliteWords = function(node) - { - if(node == undefined || !node) return; - if(!matchRegex) return; - if(skipTags.test(node.nodeName)) return; - - if(node.hasChildNodes()) { - for(var i=0; i < node.childNodes.length; i++) - this.hiliteWords(node.childNodes[i]); - } - if(node.nodeType == 3) { // NODE_TEXT - if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) { - //find the slide's section element and save it in our list of matching slides - var secnode = node; - while (secnode != null && secnode.nodeName != 'SECTION') { - secnode = secnode.parentNode; - } - - var slideIndex = Reveal.getIndices(secnode); - var slidelen = matchingSlides.length; - var alreadyAdded = false; - for (var i=0; i < slidelen; i++) { - if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) { - alreadyAdded = true; - } - } - if (! alreadyAdded) { - matchingSlides.push(slideIndex); - } - - if(!wordColor[regs[0].toLowerCase()]) { - wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length]; - } - - var match = document.createElement(hiliteTag); - match.appendChild(document.createTextNode(regs[0])); - match.style.backgroundColor = wordColor[regs[0].toLowerCase()]; - match.style.fontStyle = "inherit"; - match.style.color = "#000"; - - var after = node.splitText(regs.index); - after.nodeValue = after.nodeValue.substring(regs[0].length); - node.parentNode.insertBefore(match, after); - } - } - }; - - // remove highlighting - this.remove = function() - { - var arr = document.getElementsByTagName(hiliteTag); - while(arr.length && (el = arr[0])) { - el.parentNode.replaceChild(el.firstChild, el); - } - }; - - // start highlighting at target node - this.apply = function(input) - { - if(input == undefined || !input) return; - this.remove(); - this.setRegex(input); - this.hiliteWords(targetNode); - return matchingSlides; - }; + var targetNode = document.getElementById(id) || document.body; + var hiliteTag = tag || "EM"; + var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$"); + var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"]; + var wordColor = []; + var colorIdx = 0; + var matchRegex = ""; + var matchingSlides = []; + + this.setRegex = function(input) + { + input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|"); + matchRegex = new RegExp("(" + input + ")","i"); + } + + this.getRegex = function() + { + return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " "); + } + + // recursively apply word highlighting + this.hiliteWords = function(node) + { + if(node == undefined || !node) return; + if(!matchRegex) return; + if(skipTags.test(node.nodeName)) return; + + if(node.hasChildNodes()) { + for(var i=0; i < node.childNodes.length; i++) + this.hiliteWords(node.childNodes[i]); + } + if(node.nodeType == 3) { // NODE_TEXT + if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) { + //find the slide's section element and save it in our list of matching slides + var secnode = node; + while (secnode != null && secnode.nodeName != 'SECTION') { + secnode = secnode.parentNode; + } + + var slideIndex = Reveal.getIndices(secnode); + var slidelen = matchingSlides.length; + var alreadyAdded = false; + for (var i=0; i < slidelen; i++) { + if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) { + alreadyAdded = true; + } + } + if (! alreadyAdded) { + matchingSlides.push(slideIndex); + } + + if(!wordColor[regs[0].toLowerCase()]) { + wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length]; + } + + var match = document.createElement(hiliteTag); + match.appendChild(document.createTextNode(regs[0])); + match.style.backgroundColor = wordColor[regs[0].toLowerCase()]; + match.style.fontStyle = "inherit"; + match.style.color = "#000"; + + var after = node.splitText(regs.index); + after.nodeValue = after.nodeValue.substring(regs[0].length); + node.parentNode.insertBefore(match, after); + } + } + }; + + // remove highlighting + this.remove = function() + { + var arr = document.getElementsByTagName(hiliteTag); + while(arr.length && (el = arr[0])) { + el.parentNode.replaceChild(el.firstChild, el); + } + }; + + // start highlighting at target node + this.apply = function(input) + { + if(input == undefined || !input) return; + this.remove(); + this.setRegex(input); + this.hiliteWords(targetNode); + return matchingSlides; + }; } @@ -150,7 +150,7 @@ function Hilitor(id, tag) } } - if (matchedSlides) { + if (matchedSlides) { //navigate to the next slide that has the keyword, wrapping to the first if necessary if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) { currentMatchedIndex = 0; @@ -169,20 +169,20 @@ function Hilitor(id, tag) var searchElement = document.createElement( 'div' ); searchElement.id = "searchinputdiv"; searchElement.classList.add( 'searchdiv' ); - searchElement.style.position = 'absolute'; - searchElement.style.top = '10px'; - searchElement.style.right = '10px'; + searchElement.style.position = 'absolute'; + searchElement.style.top = '10px'; + searchElement.style.right = '10px'; searchElement.style.zIndex = 10; - //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/: + //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/: searchElement.innerHTML = ''; dom.wrapper.appendChild( searchElement ); } - document.getElementById("searchbutton").addEventListener( 'click', function(event) { + document.getElementById( 'searchbutton' ).addEventListener( 'click', function(event) { doSearch(); }, false ); - document.getElementById("searchinput").addEventListener( 'keyup', function( event ) { + document.getElementById( 'searchinput' ).addEventListener( 'keyup', function( event ) { switch (event.keyCode) { case 13: event.preventDefault(); @@ -195,7 +195,7 @@ function Hilitor(id, tag) }, false ); document.addEventListener( 'keydown', function( event ) { - if( event.key == "F" && (event.ctrlKey || event.metaKey) ) {//Control+Shift+f + if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f event.preventDefault(); toggleSearch(); } -- cgit v1.2.3 From 5d273cfb2986b77bacee28301ea108a81e7616bc Mon Sep 17 00:00:00 2001 From: John Muccigrosso Date: Sat, 10 Feb 2018 12:32:16 -0500 Subject: Background repeat & position to parallax background --- js/reveal.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index c371371..6cf8fee 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -173,6 +173,12 @@ // Parallax background size parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px" + // Parallax background repeat + parallaxBackgroundRepeat: '', // repeat/repeat-x/repeat-y/no-repeat/initial/inherit + + // Parallax background position + parallaxBackgroundPosition: '', // CSS syntax, e.g. "top left" + // Amount of pixels to move the parallax background per slide step parallaxBackgroundHorizontal: null, parallaxBackgroundVertical: null, @@ -867,6 +873,8 @@ dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")'; dom.background.style.backgroundSize = config.parallaxBackgroundSize; + dom.background.style.backgroundRepeat = config.parallaxBackgroundRepeat; + dom.background.style.backgroundPosition = config.parallaxBackgroundPosition; // Make sure the below properties are set on the element - these properties are // needed for proper transitions to be set on the element via CSS. To remove -- cgit v1.2.3 From 325162692ea2de30e4f7ebd8b858da15580844f1 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 12 Feb 2018 13:49:33 +0100 Subject: navigateNext no longer gets stuck on first stack when looping is enabled --- js/reveal.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 95d1b8c..230d001 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -4410,7 +4410,17 @@ // Prioritize revealing fragments if( nextFragment() === false ) { - if( availableRoutes().down ) { + + var routes = availableRoutes(); + + // When looping is enabled `routes.down` is always available + // so we need a separate check for when we've reached the + // end of a stack and should move horizontally + if( routes.down && routes.right && config.loop && Reveal.isLastVerticalSlide( currentSlide ) ) { + routes.down = false; + } + + if( routes.down ) { navigateDown(); } else if( config.rtl ) { @@ -5300,7 +5310,7 @@ // Returns true if we're currently on the last slide isLastSlide: function() { if( currentSlide ) { - // Does this slide has next a sibling? + // Does this slide have a next sibling? if( currentSlide.nextElementSibling ) return false; // If it's vertical, does its parent have a next sibling? @@ -5312,6 +5322,19 @@ return false; }, + // Returns true if we're on the last slide in the current + // vertical stack + isLastVerticalSlide: function() { + if( currentSlide && isVerticalSlide( currentSlide ) ) { + // Does this slide have a next sibling? + if( currentSlide.nextElementSibling ) return false; + + return true; + } + + return false; + }, + // Checks if reveal.js has been loaded and is ready for use isReady: function() { return loaded; -- cgit v1.2.3 From 0282413b69223d4487a05b9123b8da3295beebd1 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 5 Mar 2018 14:59:32 +0100 Subject: fix autoplay of inline videos in ios --- js/reveal.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index d4778cb..b8026c1 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3498,9 +3498,16 @@ if( autoplay && typeof el.play === 'function' ) { + // If the media is ready, start playback if( el.readyState > 1 ) { startEmbeddedMedia( { target: el } ); } + // Mobile devices never fire a loaded event so instead + // of waiting, we initiate playback + else if( isMobileDevice ) { + el.play(); + } + // If the media isn't loaded, wait before playing else { el.removeEventListener( 'loadeddata', startEmbeddedMedia ); // remove first to avoid dupes el.addEventListener( 'loadeddata', startEmbeddedMedia ); -- cgit v1.2.3 From 389c3f52b5b57e5edd8c168969cb72b3f7c4fa5a Mon Sep 17 00:00:00 2001 From: Matt Rakow Date: Wed, 7 Mar 2018 09:16:39 -0800 Subject: Prefer W3C pointer events, remove pointerEnabled references (it is not part of the standard), unconditional event removal --- js/reveal.js | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index b8026c1..40943a5 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1172,13 +1172,8 @@ window.addEventListener( 'resize', onWindowResize, false ); if( config.touch ) { - dom.wrapper.addEventListener( 'touchstart', onTouchStart, false ); - dom.wrapper.addEventListener( 'touchmove', onTouchMove, false ); - dom.wrapper.addEventListener( 'touchend', onTouchEnd, false ); - - // Support pointer-style touch interaction as well - if( window.navigator.pointerEnabled ) { - // IE 11 uses un-prefixed version of pointer events + if('onpointerdown' in window) { + // Use W3C pointer events dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false ); dom.wrapper.addEventListener( 'pointermove', onPointerMove, false ); dom.wrapper.addEventListener( 'pointerup', onPointerUp, false ); @@ -1189,6 +1184,12 @@ dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false ); dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false ); } + else { + // Fall back to touch events + dom.wrapper.addEventListener( 'touchstart', onTouchStart, false ); + dom.wrapper.addEventListener( 'touchmove', onTouchMove, false ); + dom.wrapper.addEventListener( 'touchend', onTouchEnd, false ); + } } if( config.keyboard ) { @@ -1250,24 +1251,19 @@ document.removeEventListener( 'keypress', onDocumentKeyPress, false ); window.removeEventListener( 'hashchange', onWindowHashChange, false ); window.removeEventListener( 'resize', onWindowResize, false ); + + dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false ); + + dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false ); dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false ); dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false ); dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false ); - // IE11 - if( window.navigator.pointerEnabled ) { - dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false ); - dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false ); - dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false ); - } - // IE10 - else if( window.navigator.msPointerEnabled ) { - dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false ); - dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false ); - dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false ); - } - if ( config.progress && dom.progress ) { dom.progress.removeEventListener( 'click', onProgressClicked, false ); } -- cgit v1.2.3 From 511397c1775c012b690749ef749d33448e9773e6 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 14 Mar 2018 12:03:42 +0100 Subject: prevent missing 'present' class when navigating to same slide twice --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index b8026c1..626ce7a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2480,7 +2480,7 @@ // Solves an edge case where the previous slide maintains the // 'present' class when navigating between adjacent vertical // stacks - if( previousSlide ) { + if( previousSlide && previousSlide !== currentSlide ) { previousSlide.classList.remove( 'present' ); previousSlide.setAttribute( 'aria-hidden', 'true' ); -- cgit v1.2.3 From f76b4fda93a8d8770390d4e89b68f8ac27e32dc9 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 16 Mar 2018 13:52:03 +0100 Subject: remove pdf height offset --- js/reveal.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 626ce7a..dcd09c7 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -196,13 +196,6 @@ // to PDF, unlimited by default pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY, - // Offset used to reduce the height of content within exported PDF pages. - // This exists to account for environment differences based on how you - // print to PDF. CLI printing options, like phantomjs and wkpdf, can end - // on precisely the total height of the document whereas in-browser - // printing has to end one pixel before. - pdfPageHeightOffset: -1, - // Number of slides away from the current that are visible viewDistance: 3, @@ -668,8 +661,8 @@ var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight ); // Dimensions of the PDF pages - var pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ), - pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) ); + var pageWidth = Math.ceil( slideSize.width * ( 1 + config.margin ) ), + pageHeight = Math.ceil( slideSize.height * ( 1 + config.margin ) ); // Dimensions of slides within the pages var slideWidth = slideSize.width, @@ -726,7 +719,7 @@ // so that no page ever flows onto another var page = document.createElement( 'div' ); page.className = 'pdf-page'; - page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px'; + page.style.height = ( pageHeight * numberOfPages ) + 'px'; slide.parentNode.insertBefore( page, slide ); page.appendChild( slide ); -- cgit v1.2.3 From 8ff5fe4986a8f83a660c0f28a14e3542d986c884 Mon Sep 17 00:00:00 2001 From: craigsdennis Date: Fri, 16 Mar 2018 22:41:16 -0700 Subject: Updates copyright to 2018 --- Gruntfile.js | 4 ++-- LICENSE | 2 +- README.md | 2 +- css/reveal.css | 2 +- css/reveal.scss | 2 +- js/reveal.js | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'js/reveal.js') diff --git a/Gruntfile.js b/Gruntfile.js index ff7da2d..fc38abb 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) 2017 Hakim El Hattab, http://hakim.se\n' + + ' * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n' + ' */' }, @@ -164,7 +164,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks( 'grunt-retire' ); grunt.loadNpmTasks( 'grunt-sass' ); grunt.loadNpmTasks( 'grunt-zip' ); - + // Default task grunt.registerTask( 'default', [ 'css', 'js' ] ); diff --git a/LICENSE b/LICENSE index c3e6e5f..1b8b5a7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2017 Hakim El Hattab, http://hakim.se, and reveal.js contributors +Copyright (C) 2018 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 ad7d539..b7bbafc 100644 --- a/README.md +++ b/README.md @@ -1280,4 +1280,4 @@ Some reveal.js features, like external Markdown and speaker notes, require that MIT licensed -Copyright (C) 2017 Hakim El Hattab, http://hakim.se +Copyright (C) 2018 Hakim El Hattab, http://hakim.se diff --git a/css/reveal.css b/css/reveal.css index 3392753..d79024c 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2017 Hakim El Hattab, http://hakim.se + * Copyright (C) 2018 Hakim El Hattab, http://hakim.se */ /********************************************* * RESET STYLES diff --git a/css/reveal.scss b/css/reveal.scss index 1a87624..6fb5419 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2017 Hakim El Hattab, http://hakim.se + * Copyright (C) 2018 Hakim El Hattab, http://hakim.se */ diff --git a/js/reveal.js b/js/reveal.js index dcd09c7..e246db7 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3,7 +3,7 @@ * http://revealjs.com * MIT licensed * - * Copyright (C) 2017 Hakim El Hattab, http://hakim.se + * Copyright (C) 2018 Hakim El Hattab, http://hakim.se */ (function( root, factory ) { if( typeof define === 'function' && define.amd ) { @@ -300,7 +300,7 @@ 'F': 'Fullscreen', 'ESC, O': 'Slide overview' }, - + // Holds custom key code mappings registeredKeyBindings = {}; -- cgit v1.2.3 From ea57e697a12f0a87d2a54d4620b759f33f77dd1c Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 20 Mar 2018 10:09:47 +0100 Subject: Revert "remove pdf height offset" This reverts commit f76b4fda93a8d8770390d4e89b68f8ac27e32dc9. --- js/reveal.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index dcd09c7..626ce7a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -196,6 +196,13 @@ // to PDF, unlimited by default pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY, + // Offset used to reduce the height of content within exported PDF pages. + // This exists to account for environment differences based on how you + // print to PDF. CLI printing options, like phantomjs and wkpdf, can end + // on precisely the total height of the document whereas in-browser + // printing has to end one pixel before. + pdfPageHeightOffset: -1, + // Number of slides away from the current that are visible viewDistance: 3, @@ -661,8 +668,8 @@ var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight ); // Dimensions of the PDF pages - var pageWidth = Math.ceil( slideSize.width * ( 1 + config.margin ) ), - pageHeight = Math.ceil( slideSize.height * ( 1 + config.margin ) ); + var pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ), + pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) ); // Dimensions of slides within the pages var slideWidth = slideSize.width, @@ -719,7 +726,7 @@ // so that no page ever flows onto another var page = document.createElement( 'div' ); page.className = 'pdf-page'; - page.style.height = ( pageHeight * numberOfPages ) + 'px'; + page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px'; slide.parentNode.insertBefore( page, slide ); page.appendChild( slide ); -- cgit v1.2.3 From 443b4475bc3b0171f45519b52919e701ec401fb2 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Wed, 21 Mar 2018 18:08:16 -0700 Subject: Adding support for hash linked slideNumber --- js/reveal.js | 65 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index c371371..e636219 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2188,7 +2188,33 @@ return overview; } + + /** + * Return a hash URL that will resolve to the current slide location. + */ + + function locationHash() { + var url = '/'; + + // Attempt to create a named link based on the slide's ID + var id = currentSlide ? currentSlide.getAttribute( 'id' ) : null; + if( id ) { + id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' ); + } + // If the current slide has an ID, use that as a named link + if( typeof id === 'string' && id.length ) { + url = '/' + id; + } + // Otherwise use the /h/v index (adding 1 to match slide label) + else { + if( indexh > 0 || indexv > 0 ) url += indexh + 1; + if( indexv > 0 ) url += '/' + indexv + 1; + } + + return url; + } + /** * Checks if the current or specified slide is vertical * (nested within another slide). @@ -2853,6 +2879,7 @@ } + /** * Updates the slide number div to reflect the current slide. * @@ -2906,14 +2933,18 @@ * @return {string} HTML string fragment */ function formatSlideNumber( a, delimiter, b ) { - + var url = '#' + locationHash(); if( typeof b === 'number' && !isNaN( b ) ) { - return ''+ a +'' + + return '' + + ''+ a +'' + ''+ delimiter +'' + - ''+ b +''; + ''+ b +'' + + ''; } else { - return ''+ a +''; + return '' + + ''+ a +'' + + ''; } } @@ -3710,8 +3741,8 @@ } else { // Read the index components of the hash - var h = parseInt( bits[0], 10 ) || 0, - v = parseInt( bits[1], 10 ) || 0; + var h = (parseInt( bits[0], 10 ) || 0) - 1, + v = (parseInt( bits[1], 10 ) || 0) - 1; if( h !== indexh || v !== indexv ) { slide( h, v ); @@ -3719,7 +3750,7 @@ } } - + /** * Updates the page URL (hash) to reflect the current * state. @@ -3739,25 +3770,7 @@ writeURLTimeout = setTimeout( writeURL, delay ); } else if( currentSlide ) { - var url = '/'; - - // Attempt to create a named link based on the slide's ID - var id = currentSlide.getAttribute( 'id' ); - if( id ) { - id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' ); - } - - // If the current slide has an ID, use that as a named link - if( typeof id === 'string' && id.length ) { - url = '/' + id; - } - // Otherwise use the /h/v index - else { - if( indexh > 0 || indexv > 0 ) url += indexh; - if( indexv > 0 ) url += '/' + indexv; - } - - window.location.hash = url; + window.location.hash = locationHash(); } } -- cgit v1.2.3 From 9dbccd697846faf2b136e77b0459bebd2286a9ce Mon Sep 17 00:00:00 2001 From: Steve Hartzog Date: Thu, 22 Mar 2018 06:06:19 -0400 Subject: add support for overriding the default layout (#2121) * add support for overriding the default layout New `overrideLayout` option (if true) will prevent h/w calcs. * fix error if options are empty * Implement requested changes Rename overrideLayout to disableLayout and remove code to unset display --- js/reveal.js | 108 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 50 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 626ce7a..e0a475b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -84,6 +84,10 @@ // Enable the slide overview mode overview: true, + // Enable/disable user specified layouts (like css-grid) + // (basically prevents all the display & height/width calculations) + disableLayout: false, + // Vertical centering of slides center: true, @@ -1853,76 +1857,80 @@ if( dom.wrapper && !isPrintingPDF() ) { - var size = getComputedSlideSize(); + if( !config.disableLayout ) { - // Layout the contents of the slides - layoutSlideContents( config.width, config.height ); + var size = getComputedSlideSize(); - dom.slides.style.width = size.width + 'px'; - dom.slides.style.height = size.height + 'px'; + // Layout the contents of the slides + layoutSlideContents( config.width, config.height ); - // Determine scale of content to fit within available space - scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); + dom.slides.style.width = size.width + 'px'; + dom.slides.style.height = size.height + 'px'; - // Respect max/min scale settings - scale = Math.max( scale, config.minScale ); - scale = Math.min( scale, config.maxScale ); + // Determine scale of content to fit within available space + scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); - // Don't apply any scaling styles if scale is 1 - if( scale === 1 ) { - dom.slides.style.zoom = ''; - dom.slides.style.left = ''; - dom.slides.style.top = ''; - dom.slides.style.bottom = ''; - dom.slides.style.right = ''; - transformSlides( { layout: '' } ); - } - else { - // Prefer zoom for scaling up so that content remains crisp. - // Don't use zoom to scale down since that can lead to shifts - // in text layout/line breaks. - if( scale > 1 && features.zoom ) { - dom.slides.style.zoom = scale; + // Respect max/min scale settings + scale = Math.max( scale, config.minScale ); + scale = Math.min( scale, config.maxScale ); + + // Don't apply any scaling styles if scale is 1 + if( scale === 1 ) { + dom.slides.style.zoom = ''; dom.slides.style.left = ''; dom.slides.style.top = ''; dom.slides.style.bottom = ''; dom.slides.style.right = ''; transformSlides( { layout: '' } ); } - // Apply scale transform as a fallback else { - dom.slides.style.zoom = ''; - dom.slides.style.left = '50%'; - dom.slides.style.top = '50%'; - dom.slides.style.bottom = 'auto'; - dom.slides.style.right = 'auto'; - transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } ); + // Prefer zoom for scaling up so that content remains crisp. + // Don't use zoom to scale down since that can lead to shifts + // in text layout/line breaks. + if( scale > 1 && features.zoom ) { + dom.slides.style.zoom = scale; + dom.slides.style.left = ''; + dom.slides.style.top = ''; + dom.slides.style.bottom = ''; + dom.slides.style.right = ''; + transformSlides( { layout: '' } ); + } + // Apply scale transform as a fallback + else { + dom.slides.style.zoom = ''; + dom.slides.style.left = '50%'; + dom.slides.style.top = '50%'; + dom.slides.style.bottom = 'auto'; + dom.slides.style.right = 'auto'; + transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } ); + } } - } - // Select all slides, vertical and horizontal - var slides = toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ); + // Select all slides, vertical and horizontal + var slides = toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ); - for( var i = 0, len = slides.length; i < len; i++ ) { - var slide = slides[ i ]; + for( var i = 0, len = slides.length; i < len; i++ ) { + var slide = slides[ i ]; - // Don't bother updating invisible slides - if( slide.style.display === 'none' ) { - continue; - } + // Don't bother updating invisible slides + if( slide.style.display === 'none' ) { + continue; + } - if( config.center || slide.classList.contains( 'center' ) ) { - // Vertical stacks are not centred since their section - // children will be - if( slide.classList.contains( 'stack' ) ) { - slide.style.top = 0; + if( config.center || slide.classList.contains( 'center' ) ) { + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) ) { + slide.style.top = 0; + } + else { + slide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px'; + } } else { - slide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px'; + slide.style.top = ''; } - } - else { - slide.style.top = ''; + } } -- cgit v1.2.3 From 6dbc5932806a4dfe59e035cea55b0c9673133215 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 22 Mar 2018 11:10:27 +0100 Subject: disableLayout comment tweak --- js/reveal.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e0a475b..8ffb39f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -84,8 +84,8 @@ // Enable the slide overview mode overview: true, - // Enable/disable user specified layouts (like css-grid) - // (basically prevents all the display & height/width calculations) + // Disables the default reveal.js slide layout so that you can use + // custom CSS layout disableLayout: false, // Vertical centering of slides @@ -311,7 +311,7 @@ 'F': 'Fullscreen', 'ESC, O': 'Slide overview' }, - + // Holds custom key code mappings registeredKeyBindings = {}; -- cgit v1.2.3 From ba0e432542fd5c6c9e4de561e9cb3196f80d2b65 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 22 Mar 2018 11:55:44 +0100 Subject: formatting --- js/reveal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index be42f13..0e9fb28 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1176,7 +1176,7 @@ window.addEventListener( 'resize', onWindowResize, false ); if( config.touch ) { - if('onpointerdown' in window) { + if( 'onpointerdown' in window ) { // Use W3C pointer events dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false ); dom.wrapper.addEventListener( 'pointermove', onPointerMove, false ); -- cgit v1.2.3 From 1257ee7e27e56ce0051cb96ffbcc563937cc192b Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 22 Mar 2018 11:58:15 +0100 Subject: code formatting --- js/reveal.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index fe4b432..c6d05d5 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3778,9 +3778,8 @@ // Ensure the named link is a valid HTML ID attribute try { element = document.getElementById( decodeURIComponent( name ) ); - } - catch (e) { - } + } + catch ( error ) { } if( element ) { // Find the position of the named slide and navigate to it -- cgit v1.2.3 From 64b2a27455240e57c2cc1a90300391a3c3b91e28 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Fri, 23 Mar 2018 10:07:42 -0700 Subject: Made one based indexing optional --- js/reveal.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e636219..25abc3a 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -68,6 +68,10 @@ // Display the page number of the current slide slideNumber: false, + + // Use 1 based indexing for # links to match slide number (default is zero + // based) + hashOneBasedIndex: false, // Determine which displays to show the slide number on showSlideNumber: 'all', @@ -2208,8 +2212,8 @@ } // Otherwise use the /h/v index (adding 1 to match slide label) else { - if( indexh > 0 || indexv > 0 ) url += indexh + 1; - if( indexv > 0 ) url += '/' + indexv + 1; + if( indexh > 0 || indexv > 0 ) url += indexh + config.hashOneBasedIndex; + if( indexv > 0 ) url += '/' + (indexv + config.hashOneBasedIndex); } return url; @@ -3741,8 +3745,8 @@ } else { // Read the index components of the hash - var h = (parseInt( bits[0], 10 ) || 0) - 1, - v = (parseInt( bits[1], 10 ) || 0) - 1; + var h = (parseInt( bits[0], 10 ) || 0) - config.hashOneBasedIndex, + v = (parseInt( bits[1], 10 ) || 0) - config.hashOneBasedIndex; if( h !== indexh || v !== indexv ) { slide( h, v ); -- cgit v1.2.3 From 397feab8b4be5f8445ebb05808b507248188d4fe Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 27 Mar 2018 14:21:41 +0200 Subject: gracefully handle duplicate slide id's --- js/reveal.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index c6d05d5..2d85b89 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3781,7 +3781,10 @@ } catch ( error ) { } - if( element ) { + // 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 ); -- cgit v1.2.3 From 531d1e8791ea6b19834426bca603a3784ba71708 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 16 Apr 2018 09:48:37 +0200 Subject: prevent linked slide numbers from changing color --- css/reveal.css | 3 +++ css/reveal.scss | 4 ++++ js/reveal.js | 67 +++++++++++++++++++++++++++++---------------------------- 3 files changed, 41 insertions(+), 33 deletions(-) (limited to 'js/reveal.js') diff --git a/css/reveal.css b/css/reveal.css index d79024c..bc96e1e 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -460,6 +460,9 @@ body { background-color: rgba(0, 0, 0, 0.4); padding: 5px; } +.reveal .slide-number a { + color: currentColor; } + .reveal .slide-number-delimiter { margin: 0 3px; } diff --git a/css/reveal.scss b/css/reveal.scss index 6fb5419..5992250 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -553,6 +553,10 @@ $controlsArrowAngleActive: 36deg; padding: 5px; } +.reveal .slide-number a { + color: currentColor; +} + .reveal .slide-number-delimiter { margin: 0 3px; } diff --git a/js/reveal.js b/js/reveal.js index a953fe2..477a1ea 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -68,7 +68,7 @@ // Display the page number of the current slide slideNumber: false, - + // Use 1 based indexing for # links to match slide number (default is zero // based) hashOneBasedIndex: false, @@ -1259,7 +1259,7 @@ document.removeEventListener( 'keypress', onDocumentKeyPress, false ); window.removeEventListener( 'hashchange', onWindowHashChange, false ); window.removeEventListener( 'resize', onWindowResize, false ); - + dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false ); dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false ); dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false ); @@ -2255,41 +2255,41 @@ return overview; } - + /** * Return a hash URL that will resolve to the current slide location. */ - function locationHash() { - - var url = '/'; - // Attempt to create a named link based on the slide's ID + var url = '/'; + + // Attempt to create a named link based on the slide's ID var id = currentSlide ? currentSlide.getAttribute( 'id' ) : null; - if( id ) { - id = encodeURIComponent( id ); - } - - var indexf; - if( config.fragmentInURL ) { - indexf = getIndices().f; - } - - // If the current slide has an ID, use that as a named link, - // but we don't support named links with a fragment index - if( typeof id === 'string' && id.length && indexf === undefined ) { - url = '/' + id; - } - // Otherwise use the /h/v index - else { - if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh + config.hashOneBasedIndex; - if( indexv > 0 || indexf !== undefined ) url += '/' + (indexv + config.hashOneBasedIndex); - if( indexf !== undefined ) url += '/' + indexf; - } - - return url; - } - + if( id ) { + id = encodeURIComponent( id ); + } + + var indexf; + if( config.fragmentInURL ) { + indexf = getIndices().f; + } + + // If the current slide has an ID, use that as a named link, + // but we don't support named links with a fragment index + if( typeof id === 'string' && id.length && indexf === undefined ) { + url = '/' + id; + } + // Otherwise use the /h/v index + else { + if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh + config.hashOneBasedIndex; + if( indexv > 0 || indexf !== undefined ) url += '/' + (indexv + config.hashOneBasedIndex); + if( indexf !== undefined ) url += '/' + indexf; + } + + return url; + + } + /** * Checks if the current or specified slide is vertical * (nested within another slide). @@ -3009,6 +3009,7 @@ * @return {string} HTML string fragment */ function formatSlideNumber( a, delimiter, b ) { + var url = '#' + locationHash(); if( typeof b === 'number' && !isNaN( b ) ) { return '' + @@ -3839,10 +3840,10 @@ } else { // Read the index components of the hash - var h = parseInt( bits[0], 10 ) || 0 - config.hashOneBasedIndex, v = parseInt( bits[1], 10 ) || 0 - config.hashOneBasedIndex, f; + if( config.fragmentInURL ) { f = parseInt( bits[2], 10 ); if( isNaN( f ) ) { @@ -3856,7 +3857,7 @@ } } - + /** * Updates the page URL (hash) to reflect the current * state. -- cgit v1.2.3 From 2a57223939cde0680b37cc333e67f42130f73984 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 16 Apr 2018 09:58:03 +0200 Subject: revise readURL to handle one-based indices --- js/reveal.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 477a1ea..ebdeb9f 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2281,8 +2281,9 @@ } // Otherwise use the /h/v index else { - if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh + config.hashOneBasedIndex; - if( indexv > 0 || indexf !== undefined ) url += '/' + (indexv + config.hashOneBasedIndex); + var hashIndexBase = config.hashOneBasedIndex ? 1 : 0; + if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh + hashIndexBase; + if( indexv > 0 || indexf !== undefined ) url += '/' + (indexv + hashIndexBase ); if( indexf !== undefined ) url += '/' + indexf; } @@ -3839,9 +3840,11 @@ } } else { + var hashIndexBase = config.hashOneBasedIndex ? 1 : 0; + // Read the index components of the hash - var h = parseInt( bits[0], 10 ) || 0 - config.hashOneBasedIndex, - v = parseInt( bits[1], 10 ) || 0 - config.hashOneBasedIndex, + var h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0, + v = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0, f; if( config.fragmentInURL ) { -- cgit v1.2.3 From 4ba0d733458408ee666163792c0dc13ebec41ac4 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Fri, 27 Apr 2018 15:53:02 +0200 Subject: add , adds wrapper element around background images/videos/iframes --- README.md | 26 ++++++++++++++------------ css/reveal.css | 9 +++++++-- css/reveal.scss | 11 +++++++++-- js/reveal.js | 34 +++++++++++++++++++++++----------- test/test.js | 8 ++++---- 5 files changed, 57 insertions(+), 31 deletions(-) (limited to 'js/reveal.js') diff --git a/README.md b/README.md index b7bbafc..9694d52 100644 --- a/README.md +++ b/README.md @@ -624,12 +624,13 @@ All CSS color formats are supported, like rgba() or hsl(). #### Image Backgrounds By default, background images are resized to cover the full page. Available options: -| Attribute | Default | Description | -| :--------------------------- | :--------- | :---------- | -| data-background-image | | URL of the image to show. GIFs restart when the slide opens. | -| data-background-size | cover | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN. | -| data-background-position | center | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. | -| data-background-repeat | no-repeat | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. | +| Attribute | Default | Description | +| :------------------------------- | :--------- | :---------- | +| data-background-image | | URL of the image to show. GIFs restart when the slide opens. | +| data-background-size | cover | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN. | +| data-background-position | center | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. | +| data-background-repeat | no-repeat | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. | +| data-background-content-opacity | 1 | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. | ```html

Image

@@ -642,12 +643,13 @@ By default, background images are resized to cover the full page. Available opti #### Video Backgrounds Automatically plays a full size video behind the slide. -| Attribute | Default | Description | -| :--------------------------- | :------ | :---------- | -| data-background-video | | A single video source, or a comma separated list of video sources. | -| data-background-video-loop | false | Flags if the video should play repeatedly. | -| data-background-video-muted | false | Flags if the audio should be muted. | -| data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. | +| Attribute | Default | Description | +| :--------------------------- | :------ | :---------- | +| data-background-video | | A single video source, or a comma separated list of video sources. | +| data-background-video-loop | false | Flags if the video should play repeatedly. | +| data-background-video-muted | false | Flags if the audio should be muted. | +| data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. | +| data-background-content-opacity | 1 | Opacity of the background video on a 0-1 scale. 0 is transparent and 1 is fully opaque. | ```html
diff --git a/css/reveal.css b/css/reveal.css index 05c2e8d..ac095f4 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -1015,10 +1015,15 @@ body { visibility: hidden; overflow: hidden; background-color: transparent; + transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal .slide-background-content { + position: absolute; + width: 100%; + height: 100%; background-position: 50% 50%; background-repeat: no-repeat; - background-size: cover; - transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + background-size: cover; } .reveal .slide-background.stack { display: block; } diff --git a/css/reveal.scss b/css/reveal.scss index 065a0a1..efb4114 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -1091,11 +1091,18 @@ $controlsArrowAngleActive: 36deg; overflow: hidden; background-color: rgba( 0, 0, 0, 0 ); + + transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + + .reveal .slide-background-content { + position: absolute; + width: 100%; + height: 100%; + background-position: 50% 50%; background-repeat: no-repeat; background-size: cover; - - transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); } .reveal .slide-background.stack { diff --git a/js/reveal.js b/js/reveal.js index ebdeb9f..ae1c4ae 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -933,14 +933,18 @@ backgroundColor: slide.getAttribute( 'data-background-color' ), backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), backgroundPosition: slide.getAttribute( 'data-background-position' ), - backgroundTransition: slide.getAttribute( 'data-background-transition' ) + backgroundTransition: slide.getAttribute( 'data-background-transition' ), + backgroundContentOpacity: slide.getAttribute( 'data-background-content-opacity' ) }; + // Main slide background element var element = document.createElement( 'div' ); - - // Carry over custom classes from the slide to the background element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); + // Inner background element that wraps images/videos/iframes + var contentElement = document.createElement( 'div' ); + contentElement.className = 'slide-background-content'; + if( data.background ) { // Auto-wrap image urls in url(...) if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { @@ -963,17 +967,22 @@ data.backgroundColor + data.backgroundRepeat + data.backgroundPosition + - data.backgroundTransition ); + data.backgroundTransition + + data.backgroundContentOpacity ); } // Additional and optional background properties - if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize; if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize ); if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; - if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat; - if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition; if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); + // Background image options are set on the content wrapper + if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize; + if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat; + if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition; + if( data.backgroundContentOpacity ) contentElement.style.opacity = data.backgroundContentOpacity; + + element.appendChild( contentElement ); container.appendChild( element ); // If backgrounds are being recreated, clear old classes @@ -981,6 +990,7 @@ slide.classList.remove( 'has-light-background' ); slide.slideBackgroundElement = element; + slide.slideBackgroundContentElement = contentElement; // If this slide has a background color, add a class that // signals if it is light or dark. If the slide has no background @@ -3311,10 +3321,12 @@ // Show the corresponding background element - var background = getSlideBackground( slide ); + var background = slide.slideBackgroundElement; if( background ) { background.style.display = 'block'; + var backgroundContent = slide.slideBackgroundContentElement; + // If the background contains media, load it if( background.hasAttribute( 'data-loaded' ) === false ) { background.setAttribute( 'data-loaded', 'true' ); @@ -3327,7 +3339,7 @@ // Images if( backgroundImage ) { - background.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')'; + backgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')'; } // Videos else if ( backgroundVideo && !isSpeakerNotes() ) { @@ -3355,7 +3367,7 @@ video.innerHTML += ''; } ); - background.appendChild( video ); + backgroundContent.appendChild( video ); } // Iframes else if( backgroundIframe && options.excludeIframes !== true ) { @@ -3378,7 +3390,7 @@ iframe.style.maxHeight = '100%'; iframe.style.maxWidth = '100%'; - background.appendChild( iframe ); + backgroundContent.appendChild( iframe ); } } diff --git a/test/test.js b/test/test.js index 042e4e8..f8515a0 100644 --- a/test/test.js +++ b/test/test.js @@ -130,8 +130,8 @@ Reveal.addEventListener( 'ready', function() { QUnit.test( 'Reveal.getSlideBackground', function( assert ) { assert.equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' ); assert.equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' ); - assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(1)' ), 'v index 0 returns first vertical child' ); - assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 1 returns second vertical child' ); + assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 0 returns first vertical child' ); + assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(3)' ), 'v index 1 returns second vertical child' ); assert.strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' ); assert.strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' ); @@ -523,8 +523,8 @@ Reveal.addEventListener( 'ready', function() { var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' ); // check that the images are applied to the background elements - assert.ok( Reveal.getSlideBackground( 0 ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' ); - assert.ok( Reveal.getSlideBackground( 1, 0 ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' ); + assert.ok( Reveal.getSlideBackground( 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' ); + assert.ok( Reveal.getSlideBackground( 1, 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' ); }); -- cgit v1.2.3 From 042fbde61baa76d2b6241c0ef3c7579b28f6e8c0 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 3 May 2018 11:02:36 +0200 Subject: data-background-content-opacity -> data-background-opacity --- README.md | 4 ++-- js/reveal.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'js/reveal.js') diff --git a/README.md b/README.md index 9694d52..9d094a1 100644 --- a/README.md +++ b/README.md @@ -630,7 +630,7 @@ By default, background images are resized to cover the full page. Available opti | data-background-size | cover | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN. | | data-background-position | center | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. | | data-background-repeat | no-repeat | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. | -| data-background-content-opacity | 1 | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. | +| data-background-opacity | 1 | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. | ```html

Image

@@ -649,7 +649,7 @@ Automatically plays a full size video behind the slide. | data-background-video-loop | false | Flags if the video should play repeatedly. | | data-background-video-muted | false | Flags if the audio should be muted. | | data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. | -| data-background-content-opacity | 1 | Opacity of the background video on a 0-1 scale. 0 is transparent and 1 is fully opaque. | +| data-background-opacity | 1 | Opacity of the background video on a 0-1 scale. 0 is transparent and 1 is fully opaque. | ```html
diff --git a/js/reveal.js b/js/reveal.js index ae1c4ae..e3bbb23 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -934,7 +934,7 @@ backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), backgroundPosition: slide.getAttribute( 'data-background-position' ), backgroundTransition: slide.getAttribute( 'data-background-transition' ), - backgroundContentOpacity: slide.getAttribute( 'data-background-content-opacity' ) + backgroundOpacity: slide.getAttribute( 'data-background-opacity' ) }; // Main slide background element @@ -968,7 +968,7 @@ data.backgroundRepeat + data.backgroundPosition + data.backgroundTransition + - data.backgroundContentOpacity ); + data.backgroundOpacity ); } // Additional and optional background properties @@ -980,7 +980,7 @@ if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize; if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat; if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition; - if( data.backgroundContentOpacity ) contentElement.style.opacity = data.backgroundContentOpacity; + if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity; element.appendChild( contentElement ); container.appendChild( element ); -- cgit v1.2.3 From 0bbcc6b59439c0b596910004985b0f11ea8a3b80 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 3 May 2018 15:25:54 +0200 Subject: add Reveal.syncSlide --- js/reveal.js | 95 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 20 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index e3bbb23..7ca6877 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -924,6 +924,57 @@ */ function createBackground( slide, container ) { + + // Main slide background element + var element = document.createElement( 'div' ); + element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); + + // Inner background element that wraps images/videos/iframes + var contentElement = document.createElement( 'div' ); + contentElement.className = 'slide-background-content'; + + element.appendChild( contentElement ); + container.appendChild( element ); + + slide.slideBackgroundElement = element; + slide.slideBackgroundContentElement = contentElement; + + // Syncs the background to reflect all current background settings + syncBackground( slide ); + + return element; + + } + + /** + * Renders all of the visual properties of a slide background + * based on the various background attributes. + * + * @param {HTMLElement} slide + */ + function syncBackground( slide ) { + + var element = slide.slideBackgroundElement, + contentElement = slide.slideBackgroundContentElement; + + // Reset the prior background state in case this is not the + // initial sync + slide.classList.remove( 'has-dark-background' ); + slide.classList.remove( 'has-light-background' ); + + element.removeAttribute( 'data-loaded' ); + element.removeAttribute( 'data-background-hash' ); + element.removeAttribute( 'data-background-size' ); + element.removeAttribute( 'data-background-transition' ); + element.style.backgroundColor = ''; + + contentElement.style.backgroundSize = ''; + contentElement.style.backgroundRepeat = ''; + contentElement.style.backgroundPosition = ''; + contentElement.style.backgroundImage = ''; + contentElement.style.opacity = ''; + contentElement.innerHTML = ''; + var data = { background: slide.getAttribute( 'data-background' ), backgroundSize: slide.getAttribute( 'data-background-size' ), @@ -937,14 +988,6 @@ backgroundOpacity: slide.getAttribute( 'data-background-opacity' ) }; - // Main slide background element - var element = document.createElement( 'div' ); - element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); - - // Inner background element that wraps images/videos/iframes - var contentElement = document.createElement( 'div' ); - contentElement.className = 'slide-background-content'; - if( data.background ) { // Auto-wrap image urls in url(...) if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { @@ -982,16 +1025,6 @@ if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition; if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity; - element.appendChild( contentElement ); - container.appendChild( element ); - - // If backgrounds are being recreated, clear old classes - slide.classList.remove( 'has-dark-background' ); - slide.classList.remove( 'has-light-background' ); - - slide.slideBackgroundElement = element; - slide.slideBackgroundContentElement = contentElement; - // If this slide has a background color, add a class that // signals if it is light or dark. If the slide has no background // color, no class will be set @@ -1012,8 +1045,6 @@ } } - return element; - } /** @@ -2638,6 +2669,29 @@ } + /** + * Updates reveal.js to keep in sync with new slide attributes. For + * example, if you add a new `data-background-image` you can call + * this to have reveal.js render the new background image. + * + * Similar to #sync() but more efficient when you only need to + * refresh a specific slide. + * + * @param {HTMLElement} slide + */ + function syncSlide( slide ) { + + syncBackground( slide ); + + sortFragments( slide.querySelectorAll( '.fragment' ) ); + + updateBackground(); + updateNotes(); + + loadSlide( slide ); + + } + /** * Resets all vertical slides so that only the first * is visible. @@ -5233,6 +5287,7 @@ initialize: initialize, configure: configure, sync: sync, + syncSlide: syncSlide, // Navigation methods slide: slide, -- cgit v1.2.3 From 667c83f1b7db63fcffce0ad611835eb1ac5e3965 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 3 May 2018 15:45:31 +0200 Subject: refactor code to match new background dom structure --- js/reveal.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 7ca6877..163bc99 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3237,13 +3237,18 @@ startEmbeddedContent( currentBackground ); - var backgroundImageURL = currentBackground.style.backgroundImage || ''; + var currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' ); + if( currentBackgroundContent ) { + + var backgroundImageURL = currentBackgroundContent.style.backgroundImage || ''; + + // Restart GIFs (doesn't work in Firefox) + if( /\.gif/i.test( backgroundImageURL ) ) { + currentBackgroundContent.style.backgroundImage = ''; + window.getComputedStyle( currentBackgroundContent ).opacity; + currentBackgroundContent.style.backgroundImage = backgroundImageURL; + } - // Restart GIFs (doesn't work in Firefox) - if( /\.gif/i.test( backgroundImageURL ) ) { - currentBackground.style.backgroundImage = ''; - window.getComputedStyle( currentBackground ).opacity; - currentBackground.style.backgroundImage = backgroundImageURL; } // Don't transition between identical backgrounds. This -- cgit v1.2.3 From 30b670cf42c458b80d0af22abeb5162507229061 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 24 May 2018 09:21:37 +0200 Subject: flatten slide number when there are only vertical slides --- js/reveal.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 163bc99..0f40977 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -3043,6 +3043,12 @@ 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 ); -- cgit v1.2.3 From 4672801229e58cb85f10309c43827050e23649ed Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Thu, 31 May 2018 10:35:07 +0200 Subject: new syncFragments api method --- js/reveal.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 0f40977..ed9db7b 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -2682,8 +2682,7 @@ function syncSlide( slide ) { syncBackground( slide ); - - sortFragments( slide.querySelectorAll( '.fragment' ) ); + syncFragments( slide ); updateBackground(); updateNotes(); @@ -2692,6 +2691,19 @@ } + /** + * Formats the fragments on the given slide so that they have + * valid indices. Call this if fragments are changed in the DOM + * after reveal.js has already initialized. + * + * @param {HTMLElement} slide + */ + function syncFragments( slide ) { + + sortFragments( slide.querySelectorAll( '.fragment' ) ); + + } + /** * Resets all vertical slides so that only the first * is visible. @@ -5297,8 +5309,10 @@ initialize: initialize, configure: configure, + sync: sync, syncSlide: syncSlide, + syncFragments: syncFragments, // Navigation methods slide: slide, -- cgit v1.2.3 From 3680f1ad10d1cbb4a48eb98673fa7018d1ab36e5 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 11 Jun 2018 12:35:11 +0200 Subject: merge #1955 with minor changes --- Gruntfile.js | 1 + README.md | 5 +++++ js/reveal.js | 27 +++++++++++++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) (limited to 'js/reveal.js') diff --git a/Gruntfile.js b/Gruntfile.js index fc38abb..8d8300b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -78,6 +78,7 @@ module.exports = function(grunt) { eqnull: true, browser: true, expr: true, + loopfunc: true, globals: { head: false, module: false, diff --git a/README.md b/README.md index 9c7b3d8..7a570d5 100644 --- a/README.md +++ b/README.md @@ -947,6 +947,11 @@ Reveal.initialize({ Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome) or [Chromium](https://www.chromium.org/Home) and to be serving the presentation from a webserver. Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-300. +### Separate pages for fragments +[Fragments](#fragments) are printed on separate slides by default. Meaning if you have a slide with three fragment steps, it will generate three separate slides where the fragments appear incrementally. + +If you prefer printing all fragments in their visible states on the same slide you can set the `pdfSeparateFragments` config option to false. + ### Page size Export dimensions are inferred from the configured [presentation size](#presentation-size). Slides that are too tall to fit within a single page will expand onto multiple pages. You can limit how many pages a slide may expand onto using the `pdfMaxPagesPerSlide` config option, for example `Reveal.configure({ pdfMaxPagesPerSlide: 1 })` ensures that no slide ever grows to more than one printed page. diff --git a/js/reveal.js b/js/reveal.js index 926b1d9..921b633 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -204,6 +204,9 @@ // to PDF, unlimited by default pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY, + // Prints each fragment on a separate slide + pdfSeparateFragments: true, + // Offset used to reduce the height of content within exported PDF pages. // This exists to account for environment differences based on how you // print to PDF. CLI printing options, like phantomjs and wkpdf, can end @@ -789,29 +792,38 @@ } // Copy page and show fragments one after another - if ( isPrintingPDFFragments() ) { + if( config.pdfSeparateFragments ) { var numberOfFragments = toArray( page.querySelectorAll( '.fragment' ) ).length; - for ( var currentFragment = 0; currentFragment < numberOfFragments; currentFragment++ ) { + for( var currentFragment = 0; currentFragment < numberOfFragments; currentFragment++ ) { + var clonedPage = page.cloneNode( true ); page.parentNode.insertBefore( clonedPage, page.nextSibling ); - toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ))).forEach( function ( fragment, fragmentIndex ) { - if ( fragmentIndex <= currentFragment ) { + toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ) ) ).forEach( function( fragment, fragmentIndex ) { + + if( fragmentIndex < currentFragment ) { fragment.classList.add( 'visible' ); - } else { - fragment.classList.remove( 'visible' ); + fragment.classList.remove( 'current-fragment' ); + } + else if( fragmentIndex === currentFragment ) { + fragment.classList.add( 'visible', 'current-fragment' ); } + else { + fragment.classList.remove( 'visible', 'current-fragment' ); + } + } ); page = clonedPage; + } } // Show all fragments else { - toArray( page.querySelectorAll( '.fragment' ) ).forEach( function( fragment ) { + toArray( page.querySelectorAll( '.fragment:not(.fade-out)' ) ).forEach( function( fragment ) { fragment.classList.add( 'visible' ); } ); } @@ -820,7 +832,6 @@ } ); - // Notify subscribers that the PDF layout is good to go dispatchEvent( 'pdf-ready' ); -- cgit v1.2.3 From 078a7520cd6a0c1c403c8270a9a58d77c09cd9de Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Tue, 12 Jun 2018 20:44:49 +0200 Subject: refactor fragment pdf exporting to support multiple fragments with same index #1955 --- js/reveal.js | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'js/reveal.js') diff --git a/js/reveal.js b/js/reveal.js index 921b633..93ed446 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -794,31 +794,43 @@ // Copy page and show fragments one after another if( config.pdfSeparateFragments ) { - var numberOfFragments = toArray( page.querySelectorAll( '.fragment' ) ).length; + // Each fragment 'group' is an array containing one or more + // fragments. Multiple fragments that appear at the same time + // are part of the same group. + var fragmentGroups = sortFragments( page.querySelectorAll( '.fragment' ), true ); - for( var currentFragment = 0; currentFragment < numberOfFragments; currentFragment++ ) { + var previousFragmentStep; + var previousPage; - var clonedPage = page.cloneNode( true ); - page.parentNode.insertBefore( clonedPage, page.nextSibling ); - - toArray( sortFragments( clonedPage.querySelectorAll( '.fragment' ) ) ).forEach( function( fragment, fragmentIndex ) { + fragmentGroups.forEach( function( fragments ) { - if( fragmentIndex < currentFragment ) { - fragment.classList.add( 'visible' ); + // Remove 'current-fragment' from the previous group + if( previousFragmentStep ) { + previousFragmentStep.forEach( function( fragment ) { fragment.classList.remove( 'current-fragment' ); - } - else if( fragmentIndex === currentFragment ) { - fragment.classList.add( 'visible', 'current-fragment' ); - } - else { - fragment.classList.remove( 'visible', 'current-fragment' ); - } + } ); + } + // Show the fragments for the current index + fragments.forEach( function( fragment ) { + fragment.classList.add( 'visible', 'current-fragment' ); } ); - page = clonedPage; + // Create a separate page for the current fragment state + var clonedPage = page.cloneNode( true ); + page.parentNode.insertBefore( clonedPage, ( previousPage || page ).nextSibling ); - } + previousFragmentStep = fragments; + previousPage = clonedPage; + + } ); + + // Reset the first/original page so that all fragments are hidden + fragmentGroups.forEach( function( fragments ) { + fragments.forEach( function( fragment ) { + fragment.classList.remove( 'visible', 'current-fragment' ); + } ); + } ); } // Show all fragments @@ -4223,9 +4235,11 @@ * the fragment within the fragments list. * * @param {object[]|*} fragments + * @param {boolean} grouped If true the returned array will contain + * nested arrays for all fragments with the same index * @return {object[]} sorted Sorted array of fragments */ - function sortFragments( fragments ) { + function sortFragments( fragments, grouped ) { fragments = toArray( fragments ); @@ -4268,7 +4282,7 @@ index ++; } ); - return sorted; + return grouped === true ? ordered : sorted; } -- cgit v1.2.3 From b9bb353a11bb7bcd1f79a40a80e0d5dfcca05591 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 2 Jul 2018 11:08:45 +0200 Subject: add 'resume presentation' button to pause overlay --- css/reveal.css | 15 +++++++++++++++ css/reveal.scss | 19 +++++++++++++++++++ js/reveal.js | 7 ++++++- 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'js/reveal.js') diff --git a/css/reveal.css b/css/reveal.css index 9f2089e..eda311e 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -964,6 +964,21 @@ body { z-index: 100; transition: all 1s ease; } +.reveal .pause-overlay .resume-button { + position: absolute; + bottom: 20px; + right: 20px; + color: #ccc; + border-radius: 2px; + padding: 6px 14px; + border: 2px solid #ccc; + font-size: 16px; + background: transparent; + cursor: pointer; } + .reveal .pause-overlay .resume-button:hover { + color: #fff; + border-color: #fff; } + .reveal.paused .pause-overlay { visibility: visible; opacity: 1; } diff --git a/css/reveal.scss b/css/reveal.scss index 1fff346..e6608d4 100644 --- a/css/reveal.scss +++ b/css/reveal.scss @@ -1034,6 +1034,25 @@ $controlsArrowAngleActive: 36deg; z-index: 100; transition: all 1s ease; } + +.reveal .pause-overlay .resume-button { + position: absolute; + bottom: 20px; + right: 20px; + color: #ccc; + border-radius: 2px; + padding: 6px 14px; + border: 2px solid #ccc; + font-size: 16px; + background: transparent; + cursor: pointer; + + &:hover { + color: #fff; + border-color: #fff; + } +} + .reveal.paused .pause-overlay { visibility: visible; opacity: 1; diff --git a/js/reveal.js b/js/reveal.js index 93ed446..103fa82 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -593,7 +593,8 @@ dom.speakerNotes.setAttribute( 'tabindex', '0' ); // Overlay graphic which is displayed during the paused mode - createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null ); + dom.pauseOverlay = createSingletonNode( dom.wrapper, 'div', 'pause-overlay', '' ); + dom.resumeButton = dom.pauseOverlay.querySelector( '.resume-button' ); dom.wrapper.setAttribute( 'role', 'application' ); @@ -1298,6 +1299,8 @@ dom.progress.addEventListener( 'click', onProgressClicked, false ); } + dom.resumeButton.addEventListener( 'click', resume, false ); + if( config.focusBodyOnPageVisibilityChange ) { var visibilityChange; @@ -1361,6 +1364,8 @@ dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false ); dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false ); + dom.resumeButton.removeEventListener( 'click', resume, false ); + if ( config.progress && dom.progress ) { dom.progress.removeEventListener( 'click', onProgressClicked, false ); } -- cgit v1.2.3