import { SLIDE_NUMBER_FORMAT_CURRENT, SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL, SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL, SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL } from "../utils/constants"; /** * Handles the display of reveal.js' optional slide number. */ export default class SlideNumber { constructor( Reveal ) { this.Reveal = Reveal; } render() { this.element = document.createElement( 'div' ); this.element.className = 'slide-number'; this.Reveal.getRevealElement().appendChild( this.element ); } /** * Called when the reveal.js config is updated. */ configure( config, oldConfig ) { let slideNumberDisplay = 'none'; if( config.slideNumber && !this.Reveal.isPrintView() ) { if( config.showSlideNumber === 'all' ) { slideNumberDisplay = 'block'; } else if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) { slideNumberDisplay = 'block'; } } this.element.style.display = slideNumberDisplay; } /** * Updates the slide number to match the current slide. */ update() { // Update slide number if enabled if( this.Reveal.getConfig().slideNumber && this.element ) { this.element.innerHTML = this.getSlideNumber(); } } /** * Returns the HTML string corresponding to the current slide * number, including formatting. */ getSlideNumber( slide = this.Reveal.getCurrentSlide() ) { let config = this.Reveal.getConfig(); let value; let format = SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL; 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 ) && this.Reveal.getHorizontalSlides().length === 1 ) { format = SLIDE_NUMBER_FORMAT_CURRENT; } // Offset the current slide number by 1 to make it 1-indexed let horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1; value = []; switch( format ) { case SLIDE_NUMBER_FORMAT_CURRENT: value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset ); break; case SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL: value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() ); break; default: let indices = this.Reveal.getIndices( slide ); value.push( indices.h + horizontalOffset ); let sep = format === SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL ? '/' : '.'; if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 ); } } let url = '#' + this.Reveal.location.getHash( slide ); return this.formatNumber( value[0], value[1], value[2], url ); } /** * Applies HTML formatting to a slide number before it's * written to the DOM. * * @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 */ formatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) { if( typeof b === 'number' && !isNaN( b ) ) { return ` ${a} ${delimiter} ${b} `; } else { return ` ${a} `; } } destroy() { this.element.remove(); } }