diff --git a/README.md b/README.md index bbce4c2..0a3178c 100644 --- a/README.md +++ b/README.md @@ -1017,9 +1017,9 @@ Reveal.configure({ slideNumber: true }); Reveal.configure({ slideNumber: 'c/t' }); // You can provide a function to fully customize the number: -Reveal.configure({ slideNumber: function() { +Reveal.configure({ slideNumber: function( slide ) { // Ignore numbering of vertical slides - return [ Reveal.getIndices().h ]; + return [ Reveal.getIndices( slide ).h ]; }}); // Control which views the slide number displays on using the "showSlideNumber" value: diff --git a/js/reveal.js b/js/reveal.js index 56719cc..198a613 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -77,9 +77,9 @@ // - "c/t": Flattened slide number / total slides // // Alternatively, you can provide a function that returns the slide - // number for the current slide. The function needs to return an array - // with one string [slideNumber] or three strings [n1,delimiter,n2]. - // See #formatSlideNumber(). + // number for the current slide. The function should take in a slide + // object and return an array with one string [slideNumber] or + // three strings [n1,delimiter,n2]. See #formatSlideNumber(). slideNumber: false, // Can be used to limit the contexts in which the slide number appears @@ -855,17 +855,10 @@ // Make sure stretch elements fit on slide layoutSlideContents( slideWidth, slideHeight ); - // Add each slide's index as attributes on itself, we need these - // indices to generate slide numbers below - toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( hslide, h ) { - hslide.setAttribute( 'data-index-h', h ); - - if( hslide.classList.contains( 'stack' ) ) { - toArray( hslide.querySelectorAll( 'section' ) ).forEach( function( vslide, v ) { - vslide.setAttribute( 'data-index-h', h ); - vslide.setAttribute( 'data-index-v', v ); - } ); - } + // Compute slide numbers now, before we start duplicating slides + var doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber ); + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + slide.setAttribute( 'data-slide-number', getSlideNumber( slide ) ); } ); // Slide and slide background layout @@ -936,14 +929,11 @@ } // Inject slide numbers if `slideNumbers` are enabled - if( config.slideNumber && /all|print/i.test( config.showSlideNumber ) ) { - var slideNumberH = parseInt( slide.getAttribute( 'data-index-h' ), 10 ) + 1, - slideNumberV = parseInt( slide.getAttribute( 'data-index-v' ), 10 ) + 1; - + if( doingSlideNumbers ) { var numberElement = document.createElement( 'div' ); numberElement.classList.add( 'slide-number' ); numberElement.classList.add( 'slide-number-pdf' ); - numberElement.innerHTML = formatSlideNumber( slideNumberH, '.', slideNumberV ); + numberElement.innerHTML = slide.getAttribute( 'data-slide-number' ); page.appendChild( numberElement ); } @@ -2657,34 +2647,37 @@ } /** - * Return a hash URL that will resolve to the current slide location. + * Return a hash URL that will resolve to the given slide location. + * + * @param {HTMLElement} [slide=currentSlide] The slide to link to */ - function locationHash() { + function locationHash( slide ) { var url = '/'; // Attempt to create a named link based on the slide's ID - var id = currentSlide ? currentSlide.getAttribute( 'id' ) : null; + var s = slide || currentSlide; + var id = s ? s.getAttribute( 'id' ) : null; if( id ) { id = encodeURIComponent( id ); } - var indexf; - if( config.fragmentInURL ) { - indexf = getIndices().f; + var index = getIndices( slide ); + if( !config.fragmentInURL ) { + index.f = undefined; } // 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 ) { + if( typeof id === 'string' && id.length && index.f === undefined ) { url = '/' + id; } // Otherwise use the /h/v index else { 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; + if( index.h > 0 || index.v > 0 || index.f !== undefined ) url += index.h + hashIndexBase; + if( index.v > 0 || index.f !== undefined ) url += '/' + (index.v + hashIndexBase ); + if( index.f !== undefined ) url += '/' + index.f; } return url; @@ -3428,48 +3421,58 @@ // Update slide number if enabled if( config.slideNumber && dom.slideNumber ) { - - var value; - var format = 'h.v'; - - if( typeof config.slideNumber === 'function' ) { - value = config.slideNumber(); - } - else { - // Check if a custom number format is available - if( typeof config.slideNumber === 'string' ) { - format = config.slideNumber; - } - - // If there are ONLY vertical slides in this deck, always use - // a flattened slide number - if( !/c/.test( format ) && dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length === 1 ) { - format = 'c'; - } - - value = []; - switch( format ) { - case 'c': - value.push( getSlidePastCount() + 1 ); - break; - case 'c/t': - value.push( getSlidePastCount() + 1, '/', getTotalSlides() ); - break; - case 'h/v': - value.push( indexh + 1 ); - if( isVerticalSlide() ) value.push( '/', indexv + 1 ); - break; - default: - value.push( indexh + 1 ); - if( isVerticalSlide() ) value.push( '.', indexv + 1 ); - } - } - - dom.slideNumber.innerHTML = formatSlideNumber( value[0], value[1], value[2] ); + dom.slideNumber.innerHTML = getSlideNumber(); } } + /** + * Returns the HTML string corresponding to the current slide number, + * including formatting. + */ + function getSlideNumber( slide ) { + + var value; + var format = 'h.v'; + if( slide === undefined ) { + slide = currentSlide; + } + + if ( typeof config.slideNumber === 'function' ) { + value = config.slideNumber( slide ); + } else { + // Check if a custom number format is available + if( typeof config.slideNumber === 'string' ) { + format = config.slideNumber; + } + + // If there are ONLY vertical slides in this deck, always use + // a flattened slide number + if( !/c/.test( format ) && dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length === 1 ) { + format = 'c'; + } + + value = []; + switch( format ) { + case 'c': + value.push( getSlidePastCount( slide ) + 1 ); + break; + case 'c/t': + value.push( getSlidePastCount( slide ) + 1, '/', getTotalSlides() ); + break; + default: + var indices = getIndices( slide ); + value.push( indices.h + 1 ); + var sep = format === 'h/v' ? '/' : '.'; + if( isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 ); + } + } + + var url = '#' + locationHash( slide ); + return formatSlideNumber( value[0], value[1], value[2], url ); + + } + /** * Applies HTML formatting to a slide number before it's * written to the DOM. @@ -3477,11 +3480,14 @@ * @param {number} a Current slide * @param {string} delimiter Character to separate slide numbers * @param {(number|*)} b Total slides + * @param {HTMLElement} [url='#'+locationHash()] The url to link to * @return {string} HTML string fragment */ - function formatSlideNumber( a, delimiter, b ) { + function formatSlideNumber( a, delimiter, b, url ) { - var url = '#' + locationHash(); + if( url === undefined ) { + url = '#' + locationHash(); + } if( typeof b === 'number' && !isNaN( b ) ) { return '' + ''+ a +'' + @@ -4232,9 +4238,15 @@ * Returns the number of past slides. This can be used as a global * flattened index for slides. * + * @param {HTMLElement} [slide=currentSlide] The slide we're counting before + * * @return {number} Past slide count */ - function getSlidePastCount() { + function getSlidePastCount( slide ) { + + if( slide === undefined ) { + slide = currentSlide; + } var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); @@ -4250,7 +4262,7 @@ for( var j = 0; j < verticalSlides.length; j++ ) { // Stop as soon as we arrive at the present - if( verticalSlides[j].classList.contains( 'present' ) ) { + if( verticalSlides[j] === slide ) { break mainLoop; } @@ -4259,7 +4271,7 @@ } // Stop as soon as we arrive at the present - if( horizontalSlide.classList.contains( 'present' ) ) { + if( horizontalSlide === slide ) { break; }