1
0
Эх сурвалжийг харах

Merge branch 'dev' into plugin-markdown

Hakim El Hattab 4 жил өмнө
parent
commit
03126c509e

+ 1 - 1
README.md

@@ -25,4 +25,4 @@ Want to create your presentation using a visual editor? Try the official reveal.
 
 MIT licensed
 
-Copyright (C) 2011-2020 Hakim El Hattab, https://hakim.se
+Copyright (C) 2011-2021 Hakim El Hattab, https://hakim.se

+ 19 - 19
css/reveal.scss

@@ -1158,54 +1158,54 @@ $controlsArrowAngleActive: 36deg;
 	}
 
 /* Immediate transition style */
-.reveal[data-background-transition=none]>.backgrounds .slide-background,
+.reveal[data-background-transition=none]>.backgrounds .slide-background:not([data-background-transition]),
 .reveal>.backgrounds .slide-background[data-background-transition=none] {
 	transition: none;
 }
 
 /* Slide */
-.reveal[data-background-transition=slide]>.backgrounds .slide-background,
+.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]),
 .reveal>.backgrounds .slide-background[data-background-transition=slide] {
 	opacity: 1;
 	backface-visibility: hidden;
 }
-	.reveal[data-background-transition=slide]>.backgrounds .slide-background.past,
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]),
 	.reveal>.backgrounds .slide-background.past[data-background-transition=slide] {
 		transform: translate(-100%, 0);
 	}
-	.reveal[data-background-transition=slide]>.backgrounds .slide-background.future,
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background.future:not([data-background-transition]),
 	.reveal>.backgrounds .slide-background.future[data-background-transition=slide] {
 		transform: translate(100%, 0);
 	}
 
-	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past,
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]),
 	.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide] {
 		transform: translate(0, -100%);
 	}
-	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future,
+	.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]),
 	.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide] {
 		transform: translate(0, 100%);
 	}
 
 
 /* Convex */
-.reveal[data-background-transition=convex]>.backgrounds .slide-background.past,
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.past[data-background-transition=convex] {
 	opacity: 0;
 	transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0);
 }
-.reveal[data-background-transition=convex]>.backgrounds .slide-background.future,
+.reveal[data-background-transition=convex]>.backgrounds .slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.future[data-background-transition=convex] {
 	opacity: 0;
 	transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0);
 }
 
-.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past,
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex] {
 	opacity: 0;
 	transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0);
 }
-.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future,
+.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex] {
 	opacity: 0;
 	transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0);
@@ -1213,54 +1213,54 @@ $controlsArrowAngleActive: 36deg;
 
 
 /* Concave */
-.reveal[data-background-transition=concave]>.backgrounds .slide-background.past,
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.past[data-background-transition=concave] {
 	opacity: 0;
 	transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0);
 }
-.reveal[data-background-transition=concave]>.backgrounds .slide-background.future,
+.reveal[data-background-transition=concave]>.backgrounds .slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.future[data-background-transition=concave] {
 	opacity: 0;
 	transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0);
 }
 
-.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past,
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave] {
 	opacity: 0;
 	transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0);
 }
-.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future,
+.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave] {
 	opacity: 0;
 	transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0);
 }
 
 /* Zoom */
-.reveal[data-background-transition=zoom]>.backgrounds .slide-background,
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background:not([data-background-transition]),
 .reveal>.backgrounds .slide-background[data-background-transition=zoom] {
 	transition-timing-function: ease;
 }
 
-.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past,
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.past[data-background-transition=zoom] {
 	opacity: 0;
 	visibility: hidden;
 	transform: scale(16);
 }
-.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future,
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background.future[data-background-transition=zoom] {
 	opacity: 0;
 	visibility: hidden;
 	transform: scale(0.2);
 }
 
-.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past,
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom] {
 	opacity: 0;
 		visibility: hidden;
 		transform: scale(16);
 }
-.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future,
+.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]),
 .reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom] {
 	opacity: 0;
 	visibility: hidden;

+ 1 - 0
css/theme/template/theme.scss

@@ -185,6 +185,7 @@
 .reveal code {
 	font-family: $codeFont;
 	text-transform: none;
+	tab-size: 2;
 }
 
 .reveal pre code {

+ 13 - 13
demo.html

@@ -19,7 +19,7 @@
 		<link rel="stylesheet" href="dist/theme/black.css" id="theme">
 
 		<!-- Theme used for syntax highlighting of code -->
-		<link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">
+		<link rel="stylesheet" href="plugin/highlight/monokai.css">
 	</head>
 
 	<body>
@@ -186,7 +186,7 @@
 						Write content using inline or external Markdown.
 						Instructions and more info available in the [docs](https://revealjs.com/markdown/).
 
-						```[]
+						```html []
 						<section data-markdown>
 						  ## Markdown support
 
@@ -249,17 +249,17 @@
 					<p>
 						reveal.js comes with a few themes built in: <br>
 						<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/black.css'); return false;">Black (default)</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/white.css'); return false;">White</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/league.css'); return false;">League</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/sky.css'); return false;">Sky</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/beige.css'); return false;">Beige</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/simple.css'); return false;">Simple</a> <br>
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/serif.css'); return false;">Serif</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/blood.css'); return false;">Blood</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/night.css'); return false;">Night</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/moon.css'); return false;">Moon</a> -
-						<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/solarized.css'); return false;">Solarized</a>
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/black.css'); return false;">Black (default)</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/white.css'); return false;">White</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/league.css'); return false;">League</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/sky.css'); return false;">Sky</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/beige.css'); return false;">Beige</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/simple.css'); return false;">Simple</a> <br>
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/serif.css'); return false;">Serif</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/blood.css'); return false;">Blood</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/night.css'); return false;">Night</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/moon.css'); return false;">Moon</a> -
+						<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
 					</p>
 				</section>
 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
dist/reveal.css


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
dist/reveal.esm.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
dist/reveal.js


+ 2 - 1
dist/theme/beige.css

@@ -194,7 +194,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/black.css

@@ -187,7 +187,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/blood.css

@@ -193,7 +193,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/league.css

@@ -196,7 +196,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/moon.css

@@ -194,7 +194,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/night.css

@@ -188,7 +188,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/serif.css

@@ -190,7 +190,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/simple.css

@@ -190,7 +190,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/sky.css

@@ -197,7 +197,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/solarized.css

@@ -191,7 +191,8 @@ html * {
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 1
dist/theme/white.css

@@ -187,7 +187,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
 
 .reveal code {
   font-family: monospace;
-  text-transform: none; }
+  text-transform: none;
+  tab-size: 2; }
 
 .reveal pre code {
   display: block;

+ 2 - 0
gulpfile.js

@@ -32,6 +32,8 @@ const banner = `/*!
 * Copyright (C) 2020 Hakim El Hattab, https://hakim.se
 */\n`
 
+sass.compiler = require('node-sass');
+
 // Prevents warnings from opening too many test pages
 process.setMaxListeners(20);
 

+ 2 - 2
index.html

@@ -8,10 +8,10 @@
 
 		<link rel="stylesheet" href="dist/reset.css">
 		<link rel="stylesheet" href="dist/reveal.css">
-		<link rel="stylesheet" href="dist/theme/black.css" id="theme">
+		<link rel="stylesheet" href="dist/theme/black.css">
 
 		<!-- Theme used for syntax highlighted code -->
-		<link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">
+		<link rel="stylesheet" href="plugin/highlight/monokai.css">
 	</head>
 	<body>
 		<div class="reveal">

+ 3 - 3
js/config.js

@@ -73,8 +73,8 @@ export default {
 
 	// Optional function that blocks keyboard events when retuning false
 	//
-	// If you set this to 'foucsed', we will only capture keyboard events
-	// for embdedded decks when they are in focus
+	// If you set this to 'focused', we will only capture keyboard events
+	// for embedded decks when they are in focus
 	keyboardCondition: null,
 
 	// Disables the default reveal.js slide layout (scaling and centering)
@@ -149,7 +149,7 @@ export default {
 	// Flags if slides with data-visibility="hidden" should be kep visible
 	showHiddenSlides: false,
 
-	// Global override for autolaying embedded media (video/audio/iframe)
+	// Global override for autoplaying embedded media (video/audio/iframe)
 	// - null:   Media will only autoplay if data-autoplay is present
 	// - true:   All media will autoplay, regardless of individual setting
 	// - false:  No media will autoplay, regardless of individual setting

+ 21 - 21
js/controllers/backgrounds.js

@@ -27,8 +27,6 @@ export default class Backgrounds {
 	 */
 	create() {
 
-		let printMode = this.Reveal.isPrintingPDF();
-
 		// Clear prior backgrounds
 		this.element.innerHTML = '';
 		this.element.classList.add( 'no-transition' );
@@ -114,9 +112,24 @@ export default class Backgrounds {
 	 */
 	sync( slide ) {
 
-		let element = slide.slideBackgroundElement,
+		const element = slide.slideBackgroundElement,
 			contentElement = slide.slideBackgroundContentElement;
 
+		const data = {
+			background: slide.getAttribute( 'data-background' ),
+			backgroundSize: slide.getAttribute( 'data-background-size' ),
+			backgroundImage: slide.getAttribute( 'data-background-image' ),
+			backgroundVideo: slide.getAttribute( 'data-background-video' ),
+			backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
+			backgroundColor: slide.getAttribute( 'data-background-color' ),
+			backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
+			backgroundPosition: slide.getAttribute( 'data-background-position' ),
+			backgroundTransition: slide.getAttribute( 'data-background-transition' ),
+			backgroundOpacity: slide.getAttribute( 'data-background-opacity' ),
+		};
+
+		const dataPreload = slide.hasAttribute( 'data-preload' );
+
 		// Reset the prior background state in case this is not the
 		// initial sync
 		slide.classList.remove( 'has-dark-background' );
@@ -135,19 +148,6 @@ export default class Backgrounds {
 		contentElement.style.opacity = '';
 		contentElement.innerHTML = '';
 
-		let data = {
-			background: slide.getAttribute( 'data-background' ),
-			backgroundSize: slide.getAttribute( 'data-background-size' ),
-			backgroundImage: slide.getAttribute( 'data-background-image' ),
-			backgroundVideo: slide.getAttribute( 'data-background-video' ),
-			backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
-			backgroundColor: slide.getAttribute( 'data-background-color' ),
-			backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
-			backgroundPosition: slide.getAttribute( 'data-background-position' ),
-			backgroundTransition: slide.getAttribute( 'data-background-transition' ),
-			backgroundOpacity: slide.getAttribute( 'data-background-opacity' )
-		};
-
 		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 ) ) {
@@ -179,7 +179,7 @@ export default class Backgrounds {
 		if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
 		if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
 
-		if( slide.hasAttribute( 'data-preload' ) ) element.setAttribute( 'data-preload', '' );
+		if( dataPreload ) element.setAttribute( 'data-preload', '' );
 
 		// Background image options are set on the content wrapper
 		if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;
@@ -192,8 +192,8 @@ export default class Backgrounds {
 		// color, no class will be added
 		let contrastColor = data.backgroundColor;
 
-		// If no bg color was found, check the computed background
-		if( !contrastColor ) {
+		// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
+		if( !contrastColor || !colorToRgb( contrastColor ) ) {
 			let computedBackgroundStyle = window.getComputedStyle( element );
 			if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {
 				contrastColor = computedBackgroundStyle.backgroundColor;
@@ -201,7 +201,7 @@ export default class Backgrounds {
 		}
 
 		if( contrastColor ) {
-			let rgb = colorToRgb( contrastColor );
+			const rgb = colorToRgb( contrastColor );
 
 			// Ignore fully transparent backgrounds. Some browsers return
 			// rgba(0,0,0,0) when reading the computed background color of
@@ -394,4 +394,4 @@ export default class Backgrounds {
 
 	}
 
-}
+}

+ 1 - 0
js/controllers/fragments.js

@@ -235,6 +235,7 @@ export default class Fragments {
 						el.classList.remove( 'current-fragment' );
 
 						if( wasVisible ) {
+							this.Reveal.slideContent.stopEmbeddedContent( el );
 							changedFragments.hidden.push( el );
 							this.Reveal.dispatchEvent({
 								target: el,

+ 46 - 29
js/controllers/print.js

@@ -16,20 +16,26 @@ export default class Print {
 	 * Configures the presentation for printing to a static
 	 * PDF.
 	 */
-	setupPDF() {
+	async setupPDF() {
 
-		let config = this.Reveal.getConfig();
+		const config = this.Reveal.getConfig();
+		const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
 
-		let slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
+		// Compute slide numbers now, before we start duplicating slides
+		const doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
+
+		const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
 
 		// Dimensions of the PDF pages
-		let pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),
+		const pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),
 			pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );
 
 		// Dimensions of slides within the pages
-		let slideWidth = slideSize.width,
+		const slideWidth = slideSize.width,
 			slideHeight = slideSize.height;
 
+		await new Promise( requestAnimationFrame );
+
 		// Let the browser know what page size we want to print
 		createStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );
 
@@ -41,25 +47,32 @@ export default class Print {
 		document.body.style.height = pageHeight + 'px';
 
 		// Make sure stretch elements fit on slide
+		await new Promise( requestAnimationFrame );
 		this.Reveal.layoutSlideContents( slideWidth, slideHeight );
 
-		// Compute slide numbers now, before we start duplicating slides
-		let doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
-		queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( function( slide ) {
-			slide.setAttribute( 'data-slide-number', this.Reveal.slideNumber.getSlideNumber( slide ) );
-		}, this );
+		// Re-run the slide layout so that r-fit-text is applied based on
+		// the printed slide size
+		slides.forEach( slide => this.Reveal.slideContent.layout( slide ) );
+
+		// Batch scrollHeight access to prevent layout thrashing
+		await new Promise( requestAnimationFrame );
+
+		const slideScrollHeights = slides.map( slide => slide.scrollHeight );
+
+		const pages = [];
+		const pageContainer = slides[0].parentNode;
 
 		// Slide and slide background layout
-		queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( function( slide ) {
+		slides.forEach( function( slide, index ) {
 
 			// Vertical stacks are not centred since their section
 			// children will be
 			if( slide.classList.contains( 'stack' ) === false ) {
 				// Center the slide inside of the page, giving the slide some margin
-				let left = ( pageWidth - slideWidth ) / 2,
-					top = ( pageHeight - slideHeight ) / 2;
+				let left = ( pageWidth - slideWidth ) / 2;
+				let top = ( pageHeight - slideHeight ) / 2;
 
-				let contentHeight = slide.scrollHeight;
+				const contentHeight = slideScrollHeights[ index ];
 				let numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );
 
 				// Adhere to configured pages per slide limit
@@ -72,10 +85,11 @@ export default class Print {
 
 				// Wrap the slide in a page element and hide its overflow
 				// so that no page ever flows onto another
-				let page = document.createElement( 'div' );
+				const page = document.createElement( 'div' );
+				pages.push( page );
+
 				page.className = 'pdf-page';
 				page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
-				slide.parentNode.insertBefore( page, slide );
 				page.appendChild( slide );
 
 				// Position the slide inside of the page
@@ -91,19 +105,19 @@ export default class Print {
 				if( config.showNotes ) {
 
 					// Are there notes for this slide?
-					let notes = this.Reveal.getSlideNotes( slide );
+					const notes = this.Reveal.getSlideNotes( slide );
 					if( notes ) {
 
-						let notesSpacing = 8;
-						let notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';
-						let notesElement = document.createElement( 'div' );
+						const notesSpacing = 8;
+						const notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';
+						const notesElement = document.createElement( 'div' );
 						notesElement.classList.add( 'speaker-notes' );
 						notesElement.classList.add( 'speaker-notes-pdf' );
 						notesElement.setAttribute( 'data-layout', notesLayout );
 						notesElement.innerHTML = notes;
 
 						if( notesLayout === 'separate-page' ) {
-							page.parentNode.insertBefore( notesElement, page.nextSibling );
+							pages.push( notesElement );
 						}
 						else {
 							notesElement.style.left = notesSpacing + 'px';
@@ -118,10 +132,11 @@ export default class Print {
 
 				// Inject slide numbers if `slideNumbers` are enabled
 				if( doingSlideNumbers ) {
-					let numberElement = document.createElement( 'div' );
+					const slideNumber = index + 1;
+					const numberElement = document.createElement( 'div' );
 					numberElement.classList.add( 'slide-number' );
 					numberElement.classList.add( 'slide-number-pdf' );
-					numberElement.innerHTML = slide.getAttribute( 'data-slide-number' );
+					numberElement.innerHTML = slideNumber;
 					page.appendChild( numberElement );
 				}
 
@@ -131,10 +146,9 @@ export default class Print {
 					// 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.
-					let fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );
+					const fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );
 
 					let previousFragmentStep;
-					let previousPage;
 
 					fragmentGroups.forEach( function( fragments ) {
 
@@ -151,11 +165,10 @@ export default class Print {
 						}, this );
 
 						// Create a separate page for the current fragment state
-						let clonedPage = page.cloneNode( true );
-						page.parentNode.insertBefore( clonedPage, ( previousPage || page ).nextSibling );
+						const clonedPage = page.cloneNode( true );
+						pages.push( clonedPage );
 
 						previousFragmentStep = fragments;
-						previousPage = clonedPage;
 
 					}, this );
 
@@ -178,6 +191,10 @@ export default class Print {
 
 		}, this );
 
+		await new Promise( requestAnimationFrame );
+
+		pages.forEach( page => pageContainer.appendChild( page ) );
+
 		// Notify subscribers that the PDF layout is good to go
 		this.Reveal.dispatchEvent({ type: 'pdf-ready' });
 
@@ -192,4 +209,4 @@ export default class Print {
 
 	}
 
-}
+}

+ 4 - 2
js/controllers/progress.js

@@ -88,14 +88,16 @@ export default class Progress {
 
 		event.preventDefault();
 
-		let slidesTotal = this.Reveal.getHorizontalSlides().length;
+		let slides = this.Reveal.getSlides();
+		let slidesTotal = slides.length;
 		let slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );
 
 		if( this.Reveal.getConfig().rtl ) {
 			slideIndex = slidesTotal - slideIndex;
 		}
 
-		this.Reveal.slide( slideIndex );
+		let targetIndices = this.Reveal.getIndices(slides[slideIndex]);
+		this.Reveal.slide( targetIndices.h, targetIndices.v );
 
 	}
 

+ 14 - 3
js/controllers/slidecontent.js

@@ -102,7 +102,9 @@ export default class SlideContent {
 
 				// Images
 				if( backgroundImage ) {
-					backgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')';
+					backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
+						return `url(${encodeURI(background.trim())})`;
+					}).join( ',' );
 				}
 				// Videos
 				else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
@@ -167,11 +169,20 @@ export default class SlideContent {
 
 		}
 
+		this.layout( slide );
+
+	}
+
+	/**
+	 * Applies JS-dependent layout helpers for the given slide,
+	 * if there are any.
+	 */
+	layout( slide ) {
+
 		// Autosize text with the r-fit-text class based on the
 		// size of its container. This needs to happen after the
 		// slide is visible in order to measure the text.
-		Array.from( slide.querySelectorAll( '.r-fit-text:not([data-fitted])' ) ).forEach( element => {
-			element.dataset.fitted = '';
+		Array.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
 			fitty( element, {
 				minSize: 24,
 				maxSize: this.Reveal.getConfig().height * 0.8,

+ 4 - 0
js/controllers/touch.js

@@ -1,4 +1,5 @@
 import { isAndroid } from '../utils/device.js'
+import { matches } from '../utils/util.js'
 
 const SWIPE_THRESHOLD = 40;
 
@@ -82,6 +83,9 @@ export default class Touch {
 	 */
 	isSwipePrevented( target ) {
 
+		// Prevent accidental swipes when scrubbing timelines
+		if( matches( target, 'video, audio' ) ) return true;
+
 		while( target && typeof target.hasAttribute === 'function' ) {
 			if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
 			target = target.parentNode;

+ 10 - 2
js/reveal.js

@@ -1335,7 +1335,11 @@ export default function( revealElement, options ) {
 		}
 
 		// Announce the current slide contents to screen readers
-		announceStatus( getStatusText( currentSlide ) );
+		// Use animation frame to prevent getComputedStyle in getStatusText
+		// from triggering layout mid-frame
+		requestAnimationFrame( () => {
+			announceStatus( getStatusText( currentSlide ) );
+		});
 
 		progress.update();
 		controls.update();
@@ -2290,7 +2294,7 @@ export default function( revealElement, options ) {
 			// 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 && isLastVerticalSlide( currentSlide ) ) {
+			if( routes.down && routes.right && config.loop && isLastVerticalSlide() ) {
 				routes.down = false;
 			}
 
@@ -2500,6 +2504,10 @@ export default function( revealElement, options ) {
 		loadSlide: slideContent.load.bind( slideContent ),
 		unloadSlide: slideContent.unload.bind( slideContent ),
 
+		// Preview management
+		showPreview,
+		hidePreview: closeOverlay,
+
 		// Adds or removes all internal event listeners
 		addEventListeners,
 		removeEventListeners,

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 688 - 583
package-lock.json


+ 3 - 2
package.json

@@ -47,12 +47,13 @@
     "gulp-connect": "^5.7.0",
     "gulp-eslint": "^6.0.0",
     "gulp-header": "^2.0.9",
-    "gulp-sass": "^4.0.2",
+    "gulp-sass": "^4.1.0",
     "gulp-tap": "^2.0.0",
     "gulp-zip": "^5.0.1",
     "highlight.js": "^10.0.3",
-    "marked": "^1.1.0",
+    "marked": "^2.0.3",
     "node-qunit-puppeteer": "^2.0.1",
+    "node-sass": "^5.0.0",
     "qunit": "^2.10.0",
     "rollup": "^2.26.4",
     "rollup-plugin-terser": "^7.0.0",

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/highlight/highlight.esm.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/highlight/highlight.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/markdown/markdown.esm.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/markdown/markdown.js


+ 2 - 5
plugin/markdown/plugin.js

@@ -6,7 +6,7 @@
 
 import marked from 'marked'
 
-const DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
+const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
 	  DEFAULT_NOTES_SEPARATOR = 'notes?:',
 	  DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
 	  DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
@@ -234,7 +234,7 @@ const Plugin = () => {
 					) );
 
 				}
-				else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
+				else {
 
 					section.outerHTML = slidify( getMarkdownFromSlide( section ), {
 						separator: section.getAttribute( 'data-separator' ),
@@ -244,9 +244,6 @@ const Plugin = () => {
 					});
 
 				}
-				else {
-					section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
-				}
 
 			});
 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/notes/notes.esm.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/notes/notes.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/search/search.esm.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
plugin/search/search.js


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно