Skip to content

Commit

Permalink
reader mode; named deeplink support, stay on same slide when reader m…
Browse files Browse the repository at this point in the history
…ode is turned on/off
  • Loading branch information
hakimel committed Oct 6, 2023
1 parent 1f1ca3a commit 1871824
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 67 deletions.
2 changes: 1 addition & 1 deletion dist/reveal.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/reveal.js.map

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions examples/reader-mode.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ <h2>Scroll triggers</h2>
<li class="fragment">Fragment three</li>
</ul>
</section>
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)">
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)" id="gradient-bg">
<h2>Gradient Backgrounds</h2>
</section>
<section data-auto-animate>
Expand Down Expand Up @@ -89,13 +89,15 @@ <h2 data-id="code-title">Scroll triggered code highlights</h2>
}
</script></code></pre>
</section>
<section data-background="https://static.slid.es/reveal/image-placeholder.png">
<h2>Image Backgrounds</h2>
<pre><code class="hljs html">&lt;section data-background="image.png"&gt;</code></pre>
</section>
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm">
<h2>Video background</h2>
</section>
<section class="stack">
<section data-background="https://static.slid.es/reveal/image-placeholder.png" id="image-bg">
<h2>Image Backgrounds</h2>
<pre><code class="hljs html">&lt;section data-background="image.png"&gt;</code></pre>
</section>
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm">
<h2>Video background</h2>
</section>
</section>
<section><h2>The end</h2></section>

</div>
Expand All @@ -109,6 +111,7 @@ <h2>Video background</h2>
<script>
Reveal.initialize({
view: 'reader',
hash: true,

plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
});
Expand Down
2 changes: 1 addition & 1 deletion js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export default {

// Responsively activate the reader mode when we reach the specified
// width (in pixels)
readerActivationWidth: null,
readerActivationWidth: 800,

// The maximum number of pages a single slide can expand onto when printing
// to PDF, unlimited by default
Expand Down
2 changes: 1 addition & 1 deletion js/controllers/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default class Location {
try {
slide = document
.getElementById( decodeURIComponent( name ) )
.closest('.slides>section, .slides>section>section');
.closest('.slides section');
}
catch ( error ) { }

Expand Down
96 changes: 61 additions & 35 deletions js/controllers/reader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SLIDES_SELECTOR } from '../utils/constants.js'
import { HORIZONTAL_SLIDES_SELECTOR, SLIDES_SELECTOR } from '../utils/constants.js'
import { queryAll, createStyleSheet } from '../utils/util.js'

/**
Expand Down Expand Up @@ -26,12 +26,14 @@ export default class Reader {

if( this.active ) return;

const state = this.Reveal.getState();

this.active = true;

this.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;

const viewportElement = this.Reveal.getViewportElement();
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR );
const horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );

viewportElement.classList.add( 'loading-scroll-mode', 'reveal-reader' );
viewportElement.addEventListener( 'scroll', this.onScroll );
Expand All @@ -44,42 +46,53 @@ export default class Reader {
}

const pageElements = [];
const pageContainer = slides[0].parentNode;
const pageContainer = horizontalSlides[0].parentNode;

// Slide and slide background layout
slides.forEach( function( slide ) {

// Vertical stacks are not centred since their section
// children will be
if( slide.classList.contains( 'stack' ) === false ) {
// Wrap the slide in a page element and hide its overflow
// so that no page ever flows onto another
const page = document.createElement( 'div' );
page.className = 'reader-page';
pageElements.push( page );

// Copy the presentation-wide background to each page
if( presentationBackground ) {
page.style.background = presentationBackground;
}
function createPage( slide, h, v ) {

const stickyContainer = document.createElement( 'div' );
stickyContainer.className = 'reader-page-sticky';
page.appendChild( stickyContainer );
// Wrap the slide in a page element and hide its overflow
// so that no page ever flows onto another
const page = document.createElement( 'div' );
page.className = 'reader-page';
pageElements.push( page );

const contentContainer = document.createElement( 'div' );
contentContainer.className = 'reader-page-content';
stickyContainer.appendChild( contentContainer );
// Copy the presentation-wide background to each page
if( presentationBackground ) {
page.style.background = presentationBackground;
}

contentContainer.appendChild( slide );
const stickyContainer = document.createElement( 'div' );
stickyContainer.className = 'reader-page-sticky';
page.appendChild( stickyContainer );

slide.classList.remove( 'past', 'future' );
const contentContainer = document.createElement( 'div' );
contentContainer.className = 'reader-page-content';
stickyContainer.appendChild( contentContainer );

if( slide.slideBackgroundElement ) {
slide.slideBackgroundElement.remove( 'past', 'future' );
contentContainer.insertBefore( slide.slideBackgroundElement, slide );
}
contentContainer.appendChild( slide );

slide.classList.remove( 'past', 'future' );

if( typeof h === 'number' ) slide.setAttribute( 'data-index-h', h );
if( typeof v === 'number' ) slide.setAttribute( 'data-index-v', v );

if( slide.slideBackgroundElement ) {
slide.slideBackgroundElement.remove( 'past', 'future' );
contentContainer.insertBefore( slide.slideBackgroundElement, slide );
}

}

// Slide and slide background layout
horizontalSlides.forEach( ( horizontalSlide, h ) => {

if( this.Reveal.isVerticalStack( horizontalSlide ) ) {
horizontalSlide.querySelectorAll( 'section' ).forEach( ( verticalSlide, v ) => {
createPage( verticalSlide, h, v );
});
}
else {
createPage( horizontalSlide, h, 0 );
}

}, this );
Expand All @@ -93,6 +106,7 @@ export default class Reader {
this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );

this.Reveal.layout();
this.Reveal.setState( state );

viewportElement.classList.remove( 'loading-scroll-mode' );

Expand All @@ -109,6 +123,8 @@ export default class Reader {

if( !this.active ) return;

const state = this.Reveal.getState();

this.active = false;

const viewportElement = this.Reveal.getViewportElement();
Expand All @@ -119,8 +135,7 @@ export default class Reader {
this.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;
this.Reveal.sync();

// TODO Navigate to the slide that is currently scrolled into view
this.Reveal.slide( 0 );
this.Reveal.setState( state );

}

Expand All @@ -144,6 +159,14 @@ export default class Reader {

}

getSlideByIndices( h, v ) {

const page = this.pages.find( page => page.indexh === h && page.indexv === v );

return page ? page.slideElement : null;

}

/**
* Updates our reader pages to match the latest configuration and
* presentation size.
Expand Down Expand Up @@ -177,9 +200,12 @@ export default class Reader {
slideElement: pageElement.querySelector( 'section' ),
backgroundElement: pageElement.querySelector( '.slide-background' ),
top: pageElement.offsetTop,
scrollTriggers: []
scrollTriggers: [],
};

page.indexh = parseInt( page.slideElement.getAttribute( 'data-index-h' ), 10 );
page.indexv = parseInt( page.slideElement.getAttribute( 'data-index-v' ), 10 );

page.slideElement.style.width = slideSize.width + 'px';
page.slideElement.style.height = config.center === true ? '' : slideSize.height + 'px';

Expand Down Expand Up @@ -302,7 +328,7 @@ export default class Reader {
page.pageElement.classList.add( 'present' );
page.slideElement.classList.add( 'present' );

this.Reveal.setCurrentReaderPage( pageIndex, page.pageElement );
this.Reveal.setCurrentReaderPage( page.pageElement, page.indexh, page.indexv );
this.Reveal.slideContent.startEmbeddedContent( page.slideElement );

if( page.backgroundElement ) {
Expand Down
60 changes: 42 additions & 18 deletions js/reveal.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,15 @@ export default function( revealElement, options ) {
// Updates the presentation to match the current configuration values
configure();

// Read the initial hash
location.readURL();

// Create slide backgrounds
backgrounds.update( true );

// Activate the print/reader mode if configured
activateInitialView();

// Read the initial hash
location.readURL();

// Notify listeners that the presentation is ready but use a 1ms
// timeout to ensure it's not fired synchronously after #initialize()
setTimeout( () => {
Expand Down Expand Up @@ -1160,6 +1161,19 @@ export default function( revealElement, options ) {

}

/**
* Checks if the current or specified slide is a stack containing
* vertical slides.
*
* @param {HTMLElement} [slide=currentSlide]
* @return {Boolean}
*/
function isVerticalStack( slide = currentSlide ) {

return slide.classList.contains( '.stack' ) || slide.querySelector( 'section' ) !== null;

}

/**
* Returns true if we're on the last slide in the current
* vertical stack.
Expand Down Expand Up @@ -1348,7 +1362,7 @@ export default function( revealElement, options ) {
// If we're in reader mode we scroll the target slide into view
// instead of running our standard slide transition
if( reader.isActive() ) {
const scrollToSlide = dom.wrapper.querySelectorAll( SLIDES_SELECTOR )[ h ];
const scrollToSlide = reader.getSlideByIndices( h, v );
if( scrollToSlide ) reader.scrollToSlide( scrollToSlide );
return;
}
Expand Down Expand Up @@ -1541,12 +1555,12 @@ export default function( revealElement, options ) {
* @param {number} pageIndex
* @param {HTMLElement} pageElement
*/
function setCurrentReaderPage( pageIndex, pageElement ) {
function setCurrentReaderPage( pageElement, h, v ) {

let indexhBefore = indexh || 0;

indexh = pageIndex;
indexv = 0;
indexh = h;
indexv = v;

previousSlide = currentSlide;
currentSlide = pageElement.querySelector( 'section' );
Expand Down Expand Up @@ -2098,21 +2112,30 @@ export default function( revealElement, options ) {

// If a slide is specified, return the indices of that slide
if( slide ) {
let isVertical = isVerticalSlide( slide );
let slideh = isVertical ? slide.parentNode : slide;
if( reader.isActive() ) {
h = parseInt( slide.getAttribute( 'data-index-h' ), 10 );

// Select all horizontal slides
let horizontalSlides = getHorizontalSlides();
if( slide.getAttribute( 'data-index-v' ) ) {
v = parseInt( slide.getAttribute( 'data-index-v' ), 10 );
}
}
else {
let isVertical = isVerticalSlide( slide );
let slideh = isVertical ? slide.parentNode : slide;

// Now that we know which the horizontal slide is, get its index
h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
// Select all horizontal slides
let horizontalSlides = getHorizontalSlides();

// Assume we're not vertical
v = undefined;
// Now that we know which the horizontal slide is, get its index
h = Math.max( horizontalSlides.indexOf( slideh ), 0 );

// If this is a vertical slide, grab the vertical index
if( isVertical ) {
v = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );
// Assume we're not vertical
v = undefined;

// If this is a vertical slide, grab the vertical index
if( isVertical ) {
v = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );
}
}
}

Expand Down Expand Up @@ -2802,6 +2825,7 @@ export default function( revealElement, options ) {
isLastSlide,
isLastVerticalSlide,
isVerticalSlide,
isVerticalStack,

// State checks
isPaused,
Expand Down

0 comments on commit 1871824

Please sign in to comment.