Merge branch 'dev' into plugin-markdown

edit
Hakim El Hattab 2021-05-17 09:54:01 +02:00 committed by GitHub
commit 03126c509e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 5373 additions and 5488 deletions

View File

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

View File

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

View File

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

View File

@ -19,7 +19,7 @@
<link rel="stylesheet" href="dist/theme/black.css" id="theme"> <link rel="stylesheet" href="dist/theme/black.css" id="theme">
<!-- Theme used for syntax highlighting of code --> <!-- 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> </head>
<body> <body>
@ -186,7 +186,7 @@
Write content using inline or external Markdown. Write content using inline or external Markdown.
Instructions and more info available in the [docs](https://revealjs.com/markdown/). Instructions and more info available in the [docs](https://revealjs.com/markdown/).
```[] ```html []
<section data-markdown> <section data-markdown>
## Markdown support ## Markdown support
@ -249,17 +249,17 @@
<p> <p>
reveal.js comes with a few themes built in: <br> 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. --> <!-- 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','dist/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','dist/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','dist/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','dist/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','dist/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','dist/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','dist/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','dist/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','dist/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','dist/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/solarized.css'); return false;">Solarized</a>
</p> </p>
</section> </section>

4
dist/reveal.css vendored

File diff suppressed because one or more lines are too long

4
dist/reveal.esm.js vendored

File diff suppressed because one or more lines are too long

4
dist/reveal.js vendored

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

3
dist/theme/moon.css vendored
View File

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

View File

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

View File

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

View File

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

3
dist/theme/sky.css vendored
View File

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

View File

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

View File

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

View File

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

View File

@ -8,10 +8,10 @@
<link rel="stylesheet" href="dist/reset.css"> <link rel="stylesheet" href="dist/reset.css">
<link rel="stylesheet" href="dist/reveal.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 --> <!-- 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> </head>
<body> <body>
<div class="reveal"> <div class="reveal">

View File

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

View File

@ -27,8 +27,6 @@ export default class Backgrounds {
*/ */
create() { create() {
let printMode = this.Reveal.isPrintingPDF();
// Clear prior backgrounds // Clear prior backgrounds
this.element.innerHTML = ''; this.element.innerHTML = '';
this.element.classList.add( 'no-transition' ); this.element.classList.add( 'no-transition' );
@ -114,9 +112,24 @@ export default class Backgrounds {
*/ */
sync( slide ) { sync( slide ) {
let element = slide.slideBackgroundElement, const element = slide.slideBackgroundElement,
contentElement = slide.slideBackgroundContentElement; 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 // Reset the prior background state in case this is not the
// initial sync // initial sync
slide.classList.remove( 'has-dark-background' ); slide.classList.remove( 'has-dark-background' );
@ -135,19 +148,6 @@ export default class Backgrounds {
contentElement.style.opacity = ''; contentElement.style.opacity = '';
contentElement.innerHTML = ''; 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 ) { if( data.background ) {
// Auto-wrap image urls in url(...) // Auto-wrap image urls in url(...)
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { 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.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); 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 // Background image options are set on the content wrapper
if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize; if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;
@ -192,8 +192,8 @@ export default class Backgrounds {
// color, no class will be added // color, no class will be added
let contrastColor = data.backgroundColor; let contrastColor = data.backgroundColor;
// If no bg color was found, check the computed background // If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
if( !contrastColor ) { if( !contrastColor || !colorToRgb( contrastColor ) ) {
let computedBackgroundStyle = window.getComputedStyle( element ); let computedBackgroundStyle = window.getComputedStyle( element );
if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) { if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {
contrastColor = computedBackgroundStyle.backgroundColor; contrastColor = computedBackgroundStyle.backgroundColor;
@ -201,7 +201,7 @@ export default class Backgrounds {
} }
if( contrastColor ) { if( contrastColor ) {
let rgb = colorToRgb( contrastColor ); const rgb = colorToRgb( contrastColor );
// Ignore fully transparent backgrounds. Some browsers return // Ignore fully transparent backgrounds. Some browsers return
// rgba(0,0,0,0) when reading the computed background color of // rgba(0,0,0,0) when reading the computed background color of

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1335,7 +1335,11 @@ export default function( revealElement, options ) {
} }
// Announce the current slide contents to screen readers // Announce the current slide contents to screen readers
// Use animation frame to prevent getComputedStyle in getStatusText
// from triggering layout mid-frame
requestAnimationFrame( () => {
announceStatus( getStatusText( currentSlide ) ); announceStatus( getStatusText( currentSlide ) );
});
progress.update(); progress.update();
controls.update(); controls.update();
@ -2290,7 +2294,7 @@ export default function( revealElement, options ) {
// When looping is enabled `routes.down` is always available // When looping is enabled `routes.down` is always available
// so we need a separate check for when we've reached the // so we need a separate check for when we've reached the
// end of a stack and should move horizontally // 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; routes.down = false;
} }
@ -2500,6 +2504,10 @@ export default function( revealElement, options ) {
loadSlide: slideContent.load.bind( slideContent ), loadSlide: slideContent.load.bind( slideContent ),
unloadSlide: slideContent.unload.bind( slideContent ), unloadSlide: slideContent.unload.bind( slideContent ),
// Preview management
showPreview,
hidePreview: closeOverlay,
// Adds or removes all internal event listeners // Adds or removes all internal event listeners
addEventListeners, addEventListeners,
removeEventListeners, removeEventListeners,

10520
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
import marked from 'marked' 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_NOTES_SEPARATOR = 'notes?:',
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$', DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\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 ), { section.outerHTML = slidify( getMarkdownFromSlide( section ), {
separator: section.getAttribute( 'data-separator' ), separator: section.getAttribute( 'data-separator' ),
@ -244,9 +244,6 @@ const Plugin = () => {
}); });
} }
else {
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
}
}); });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long