2 Commits

Author SHA1 Message Date
c2b09ece24 magic-python add one-line code 2021-07-29 21:56:50 +08:00
47df4cda71 magic-python 2021-07-29 21:23:41 +08:00
74 changed files with 1107 additions and 1872 deletions

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ log/*.log
tmp/** tmp/**
node_modules/ node_modules/
.sass-cache .sass-cache
dist/*.map

View File

@@ -1,9 +1,10 @@
## Contributing ## Contributing
Please keep the [issue tracker](https://github.com/hakimel/reveal.js/issues) limited to **bug reports**.
Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**.
### General Questions and Support ### Personal Support
If you have questions about how to use reveal.js the best place to ask is in the [Discussions](https://github.com/hakimel/reveal.js/discussions). Anything that isn't a bug report should be posted as a dicussion instead. If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
### Bug Reports ### Bug Reports
@@ -11,10 +12,11 @@ When reporting a bug make sure to include information about which browser and op
### Pull Requests ### Pull Requests
- Should be submitted from a feature/topic branch (not your master)
- Should follow the coding style of the file you work in, most importantly: - Should follow the coding style of the file you work in, most importantly:
- Tabs to indent - Tabs to indent
- Single-quoted strings - Single-quoted strings
- Should be made towards the **dev branch**
- Should be submitted from a feature/topic branch (not your master)
### Plugins ### Plugins

View File

@@ -1,4 +1,4 @@
Copyright (C) 2011-2022 Hakim El Hattab, http://hakim.se, and reveal.js contributors Copyright (C) 2020 Hakim El Hattab, http://hakim.se, and reveal.js contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,50 +1,28 @@
<p align="center"> <p align="center">
<a href="https://revealjs.com"> <a href="https://revealjs.com">
<img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text-sticker.png" alt="reveal.js" width="500"> <img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text.svg" alt="reveal.js" width="450">
</a> </a>
<br><br> <br><br>
<a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a> <a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a>
<a href="https://slides.com/"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a> <a href="https://slides.com/"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
</p> </p>
reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create beautiful presentations for free. Check out the live demo at [revealjs.com](https://revealjs.com/). reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create fully featured and beautiful presentations for free. [Check out the live demo](https://revealjs.com/).
The framework comes with a powerful feature set including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX typesetting](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and an [extensive API](https://revealjs.com/api/). The framework comes with a broad range of features including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX support](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and much more.
--- <h1>
<a href="https://revealjs.com/installation" style="font-size: 3em;">Get Started</a>
</h1>
Want to create reveal.js presentation in a graphical editor? Try <https://slides.com>. It's made by the same people behind reveal.js. ## Documentation
The full reveal.js documentation is available at [revealjs.com](https://revealjs.com).
--- ## Online Editor
Want to create your presentation using a visual editor? Try the official reveal.js presentation platform for free at [Slides.com](https://slides.com). It's made by the same people behind reveal.js.
### Sponsors ## License
Hakim's open source work is supported by <a href="https://github.com/sponsors/hakimel">GitHub sponsors</a>. Special thanks to:
<div align="center">
<table>
<td align="center">
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=revealjs&utm_source=github">
<div>
<img src="https://user-images.githubusercontent.com/629429/151508669-efb4c3b3-8fe3-45eb-8e47-e9510b5f0af1.svg" width="290" alt="WorkOS">
</div>
<b>Your app, enterprise-ready.</b>
<div>
<sub>Start selling to enterprise customers with just a few lines of code. Add Single Sign-On (and more) in minutes instead of months.</sup>
</div>
</a>
</td>
</table>
</div>
--- MIT licensed
### Getting started Copyright (C) 2011-2021 Hakim El Hattab, https://hakim.se
- 🚀 [Install reveal.js](https://revealjs.com/installation)
- 👀 [View the demo presentation](https://revealjs.com/demo)
- 📖 [Read the documentation](https://revealjs.com/markup/)
- 🖌 [Try the visual editor for reveal.js at Slides.com](https://slides.com/)
- 🎬 [Watch the reveal.js video course (paid)](https://revealjs.com/course)
---
<div align="center">
MIT licensed | Copyright © 2011-2022 Hakim El Hattab, https://hakim.se
</div>

View File

@@ -16,7 +16,7 @@
box-sizing: border-box; box-sizing: border-box;
} }
// Text that auto-fits its container // Text that auto-fits it's container
.reveal .r-fit-text { .reveal .r-fit-text {
display: inline-block; // https://github.com/rikschennink/fitty#performance display: inline-block; // https://github.com/rikschennink/fitty#performance
white-space: nowrap; white-space: nowrap;

View File

@@ -141,11 +141,6 @@
transform: none !important; transform: none !important;
} }
.reveal .r-fit-text {
white-space: normal !important;
}
.reveal section img { .reveal section img {
display: block; display: block;
margin: 15px 0px; margin: 15px 0px;

View File

@@ -100,6 +100,7 @@ html.print-pdf {
box-shadow: none; box-shadow: none;
} }
/* Slide backgrounds are placed inside of their slide when exporting to PDF */ /* Slide backgrounds are placed inside of their slide when exporting to PDF */
.reveal .backgrounds { .reveal .backgrounds {
display: none; display: none;

View File

@@ -1,5 +1,3 @@
@use "sass:math";
/** /**
* reveal.js * reveal.js
* http://revealjs.com * http://revealjs.com
@@ -33,16 +31,6 @@ html.reveal-full-page {
color: #000; color: #000;
} }
// Force the presentation to cover the full viewport when we
// enter fullscreen mode. Fixes sizing issues in Safari.
.reveal-viewport:fullscreen {
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
transform: none !important;
}
/********************************************* /*********************************************
* VIEW FRAGMENTS * VIEW FRAGMENTS
@@ -259,11 +247,11 @@ $controlsArrowAngleActive: 36deg;
@mixin controlsArrowTransform( $angle ) { @mixin controlsArrowTransform( $angle ) {
&:before { &:before {
transform: translateX(($controlArrowSize - $controlArrowLength)*0.5) translateY(($controlArrowSize - $controlArrowThickness)*0.5) rotate( $angle ); transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( $angle );
} }
&:after { &:after {
transform: translateX(($controlArrowSize - $controlArrowLength)*0.5) translateY(($controlArrowSize - $controlArrowThickness)*0.5) rotate( -$angle ); transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( -$angle );
} }
} }
@@ -312,11 +300,11 @@ $controlsArrowAngleActive: 36deg;
left: 0; left: 0;
width: $controlArrowLength; width: $controlArrowLength;
height: $controlArrowThickness; height: $controlArrowThickness;
border-radius: $controlArrowThickness*0.5; border-radius: $controlArrowThickness/2;
background-color: currentColor; background-color: currentColor;
transition: all 0.15s ease, background-color 0.8s ease; transition: all 0.15s ease, background-color 0.8s ease;
transform-origin: math.div(floor(($controlArrowThickness*0.5)*10), 10) 50%; transform-origin: floor(($controlArrowThickness/2)*10)/10 50%;
will-change: transform; will-change: transform;
} }
@@ -338,7 +326,7 @@ $controlsArrowAngleActive: 36deg;
.navigate-left { .navigate-left {
right: $controlArrowSize + $controlArrowSpacing*2; right: $controlArrowSize + $controlArrowSpacing*2;
bottom: $controlArrowSpacing + $controlArrowSize*0.5; bottom: $controlArrowSpacing + $controlArrowSize/2;
transform: translateX( -10px ); transform: translateX( -10px );
&.highlight { &.highlight {
@@ -348,7 +336,7 @@ $controlsArrowAngleActive: 36deg;
.navigate-right { .navigate-right {
right: 0; right: 0;
bottom: $controlArrowSpacing + $controlArrowSize*0.5; bottom: $controlArrowSpacing + $controlArrowSize/2;
transform: translateX( 10px ); transform: translateX( 10px );
.controls-arrow { .controls-arrow {
@@ -361,7 +349,7 @@ $controlsArrowAngleActive: 36deg;
} }
.navigate-up { .navigate-up {
right: $controlArrowSpacing + $controlArrowSize*0.5; right: $controlArrowSpacing + $controlArrowSize/2;
bottom: $controlArrowSpacing*2 + $controlArrowSize; bottom: $controlArrowSpacing*2 + $controlArrowSize;
transform: translateY( -10px ); transform: translateY( -10px );
@@ -371,7 +359,7 @@ $controlsArrowAngleActive: 36deg;
} }
.navigate-down { .navigate-down {
right: $controlArrowSpacing + $controlArrowSize*0.5; right: $controlArrowSpacing + $controlArrowSize/2;
bottom: -$controlArrowSpacing; bottom: -$controlArrowSpacing;
padding-bottom: $controlArrowSpacing; padding-bottom: $controlArrowSpacing;
transform: translateY( 10px ); transform: translateY( 10px );
@@ -527,25 +515,25 @@ $controlsArrowAngleActive: 36deg;
.navigate-left { .navigate-left {
top: 50%; top: 50%;
left: $spacing; left: $spacing;
margin-top: -$controlArrowSize*0.5; margin-top: -$controlArrowSize/2;
} }
.navigate-right { .navigate-right {
top: 50%; top: 50%;
right: $spacing; right: $spacing;
margin-top: -$controlArrowSize*0.5; margin-top: -$controlArrowSize/2;
} }
.navigate-up { .navigate-up {
top: $spacing; top: $spacing;
left: 50%; left: 50%;
margin-left: -$controlArrowSize*0.5; margin-left: -$controlArrowSize/2;
} }
.navigate-down { .navigate-down {
bottom: $spacing - $controlArrowSpacing + 0.3em; bottom: $spacing - $controlArrowSpacing + 0.3em;
left: 50%; left: 50%;
margin-left: -$controlArrowSize*0.5; margin-left: -$controlArrowSize/2;
} }
} }
@@ -723,8 +711,6 @@ $controlsArrowAngleActive: 36deg;
.reveal .slides>section.past, .reveal .slides>section.past,
.reveal .slides>section.future, .reveal .slides>section.future,
.reveal .slides>section.past>section,
.reveal .slides>section.future>section,
.reveal .slides>section>section.past, .reveal .slides>section>section.past,
.reveal .slides>section>section.future { .reveal .slides>section>section.future {
opacity: 0; opacity: 0;
@@ -783,6 +769,9 @@ $controlsArrowAngleActive: 36deg;
*********************************************/ *********************************************/
@each $stylename in slide, linear { @each $stylename in slide, linear {
.reveal.#{$stylename} section {
backface-visibility: hidden;
}
@include transition-horizontal-past(#{$stylename}) { @include transition-horizontal-past(#{$stylename}) {
transform: translate(-150%, 0); transform: translate(-150%, 0);
} }
@@ -1178,6 +1167,7 @@ $controlsArrowAngleActive: 36deg;
.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]), .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;
} }
.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]), .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] {
@@ -1711,7 +1701,7 @@ $notesWidthPercent: 25%;
.reveal .speaker-notes { .reveal .speaker-notes {
display: none; display: none;
position: absolute; position: absolute;
width: math.div($notesWidthPercent, (1 - math.div($notesWidthPercent,100))) * 1%; width: $notesWidthPercent / (1-$notesWidthPercent/100) * 1%;
height: 100%; height: 100%;
top: 0; top: 0;
left: 100%; left: 100%;
@@ -1774,6 +1764,7 @@ $notesWidthPercent: 25%;
top: 100%; top: 100%;
left: 0; left: 0;
width: 100%; width: 100%;
height: (30/0.7)*1%;
height: 30vh; height: 30vh;
border: 0; border: 0;
} }
@@ -1787,6 +1778,7 @@ $notesWidthPercent: 25%;
.reveal.show-notes .speaker-notes { .reveal.show-notes .speaker-notes {
top: 100%; top: 100%;
height: (40/0.6)*1%;
height: 40vh; height: 40vh;
} }

View File

@@ -52,7 +52,7 @@
<p>Slides can be nested inside of each other.</p> <p>Slides can be nested inside of each other.</p>
<p>Use the <em>Space</em> key to navigate through all slides.</p> <p>Use the <em>Space</em> key to navigate through all slides.</p>
<br> <br>
<a href="#/2/1" class="navigate-down"> <a href="#" class="navigate-down">
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow"> <img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
</a> </a>
</section> </section>
@@ -273,11 +273,6 @@
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow"> <img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
</a> </a>
</section> </section>
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)">
<h2>Gradient Backgrounds</h2>
<pre><code class="hljs html wrap">&lt;section data-background-gradient=
"linear-gradient(to bottom, #ddd, #191919)"&gt;</code></pre>
</section>
<section data-background="https://static.slid.es/reveal/image-placeholder.png"> <section data-background="https://static.slid.es/reveal/image-placeholder.png">
<h2>Image Backgrounds</h2> <h2>Image Backgrounds</h2>
<pre><code class="hljs html">&lt;section data-background="image.png"&gt;</code></pre> <pre><code class="hljs html">&lt;section data-background="image.png"&gt;</code></pre>
@@ -286,7 +281,7 @@
<h2>Tiled Backgrounds</h2> <h2>Tiled Backgrounds</h2>
<pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre> <pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
</section> </section>
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000"> <section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000">
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;"> <div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
<h2>Video Backgrounds</h2> <h2>Video Backgrounds</h2>
<pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre> <pre><code class="hljs html" style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre>

6
dist/reveal.css vendored

File diff suppressed because one or more lines are too long

6
dist/reveal.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
dist/reveal.js vendored

File diff suppressed because one or more lines are too long

1
dist/reveal.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -125,7 +125,7 @@
</section> </section>
<section data-auto-animate style="height: 600px"> <section data-auto-animate style="height: 600px">
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h3> <h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h2>
<h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2> <h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2>
<div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div> <div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div>
<div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div> <div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div>
@@ -133,7 +133,7 @@
<div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div> <div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div>
</section> </section>
<section data-auto-animate style="height: 600px"> <section data-auto-animate style="height: 600px">
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h3> <h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h2>
<h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2> <h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2>
<div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div> <div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div>
<div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div> <div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div>
@@ -141,7 +141,7 @@
<div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div> <div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div>
</section> </section>
<section data-auto-animate style="height: 600px"> <section data-auto-animate style="height: 600px">
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3> <h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2> <h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
<div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div> <div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div>
<div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div> <div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div>
@@ -149,7 +149,7 @@
<div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div> <div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div>
</section> </section>
<section data-auto-animate style="height: 600px"> <section data-auto-animate style="height: 600px">
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3> <h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2> <h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
<div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div> <div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div>
<div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div> <div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div>
@@ -176,37 +176,6 @@
<h3>B2</h3> <h3>B2</h3>
</section> </section>
<section>
<section id="stacked-slide-1" data-auto-animate>
<a href="#/stacked-slide-1">Slide 1</a><br>
<a href="#/stacked-slide-2">Slide 2</a><br>
<a href="#/stacked-slide-3">Slide 3</a><br>
<a href="#/stacked-slide-4">Slide 4</a><br>
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 0px;">A</div>
</section>
<section id="stacked-slide-2" data-auto-animate>
<a href="#/stacked-slide-1">Slide 1</a><br>
<a href="#/stacked-slide-2">Slide 2</a><br>
<a href="#/stacked-slide-3">Slide 3</a><br>
<a href="#/stacked-slide-4">Slide 4</a><br>
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 25%;">A</div>
</section>
<section id="stacked-slide-3" data-auto-animate>
<a href="#/stacked-slide-1">Slide 1</a><br>
<a href="#/stacked-slide-2">Slide 2</a><br>
<a href="#/stacked-slide-3">Slide 3</a><br>
<a href="#/stacked-slide-4">Slide 4</a><br>
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 50%;">A</div>
</section>
<section id="stacked-slide-4" data-auto-animate>
<a href="#/stacked-slide-1">Slide 1</a><br>
<a href="#/stacked-slide-2">Slide 2</a><br>
<a href="#/stacked-slide-3">Slide 3</a><br>
<a href="#/stacked-slide-4">Slide 4</a><br>
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 75%;">A</div>
</section>
</section>
</div> </div>
</div> </div>

View File

@@ -123,7 +123,7 @@
<section id="vstack"> <section id="vstack">
<h2>VStack</h2> <h2>VStack</h2>
<p>Stacks multiple elements vertically.</p> <p>Stacks multiple elements horizontally.</p>
<pre><code class="html" data-trim data-line-numbers> <pre><code class="html" data-trim data-line-numbers>
<div class="r-vstack"> <div class="r-vstack">
&lt;img width="450" height="300" src="..."&gt; &lt;img width="450" height="300" src="..."&gt;

View File

@@ -21,8 +21,8 @@
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines --> <!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
<section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section> <section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
<!-- Slides are separated by three dashes (the default) --> <!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
<section data-markdown> <section data-markdown data-separator="---">
<script type="text/template"> <script type="text/template">
## Demo 1 ## Demo 1
Slide 1 Slide 1
@@ -35,7 +35,7 @@
</script> </script>
</section> </section>
<!-- Slides are separated by regexp matching newline + three dashes + newline, vertical slides identical but two dashes --> <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$"> <section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
<script type="text/template"> <script type="text/template">
## Demo 2 ## Demo 2
@@ -53,8 +53,8 @@
</script> </script>
</section> </section>
<!-- No "extra" slides, since the separator can't be matched ("---" will become horizontal rulers) --> <!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
<section data-markdown data-separator="$x"> <section data-markdown>
<script type="text/template"> <script type="text/template">
A A
@@ -106,16 +106,6 @@
</script> </script>
</section> </section>
<!-- Math -->
<section data-markdown>
## The Lorenz Equations
`\[\begin{aligned}
\dot{x} &amp; = \sigma(y-x) \\
\dot{y} &amp; = \rho x - y - xz \\
\dot{z} &amp; = -\beta z + xy
\end{aligned} \]`
</section>
</div> </div>
</div> </div>
@@ -123,7 +113,6 @@
<script src="../plugin/markdown/markdown.js"></script> <script src="../plugin/markdown/markdown.js"></script>
<script src="../plugin/highlight/highlight.js"></script> <script src="../plugin/highlight/highlight.js"></script>
<script src="../plugin/notes/notes.js"></script> <script src="../plugin/notes/notes.js"></script>
<script src="../plugin/math/math.js"></script>
<script> <script>
@@ -133,7 +122,7 @@
history: true, history: true,
center: true, center: true,
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes, RevealMath.KaTeX ] plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
}); });
</script> </script>

View File

@@ -31,11 +31,6 @@ Content 3.1
Content 3.2 Content 3.2
## External 3.3 (Image) ## External 3.3
![External Image](https://s3.amazonaws.com/static.slid.es/logo/v2/slides-symbol-512x512.png) ![External Image](https://s3.amazonaws.com/static.slid.es/logo/v2/slides-symbol-512x512.png)
## External 3.4 (Math)
`\[ J(\theta_0,\theta_1) = \sum_{i=0} \]`

View File

@@ -20,7 +20,7 @@
<section> <section>
<h2>reveal.js Math Plugin</h2> <h2>reveal.js Math Plugin</h2>
<p>Render math with KaTeX, MathJax 2 or MathJax 3</p> <p>A thin wrapper for MathJax</p>
</section> </section>
<section> <section>
@@ -182,7 +182,8 @@
history: true, history: true,
transition: 'linear', transition: 'linear',
mathjax2: { math: {
// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
config: 'TeX-AMS_HTML-full', config: 'TeX-AMS_HTML-full',
TeX: { TeX: {
Macros: { Macros: {
@@ -192,13 +193,7 @@
} }
}, },
// There are three typesetters available plugins: [ RevealMath ]
// RevealMath.MathJax2 (default)
// RevealMath.MathJax3
// RevealMath.KaTeX
//
// More info at https://revealjs.com/math/
plugins: [ RevealMath.MathJax2 ]
}); });
</script> </script>

View File

@@ -24,14 +24,13 @@ const autoprefixer = require('gulp-autoprefixer')
const root = yargs.argv.root || '.' const root = yargs.argv.root || '.'
const port = yargs.argv.port || 8000 const port = yargs.argv.port || 8000
const host = yargs.argv.host || 'localhost'
const banner = `/*! const banner = `/*!
* reveal.js ${pkg.version} * reveal.js ${pkg.version}
* ${pkg.homepage} * ${pkg.homepage}
* MIT licensed * MIT licensed
* *
* Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se * Copyright (C) 2020 Hakim El Hattab, https://hakim.se
*/\n` */\n`
// Prevents warnings from opening too many test pages // Prevents warnings from opening too many test pages
@@ -61,11 +60,11 @@ const babelConfig = {
// polyfilling older browsers and a larger bundle. // polyfilling older browsers and a larger bundle.
const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) ); const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) );
babelConfigESM.presets[0][1].targets = { browsers: [ babelConfigESM.presets[0][1].targets = { browsers: [
'last 2 Chrome versions', 'last 2 Chrome versions', 'not Chrome < 60',
'last 2 Safari versions', 'last 2 Safari versions', 'not Safari < 10.1',
'last 2 iOS versions', 'last 2 iOS versions', 'not iOS < 10.3',
'last 2 Firefox versions', 'last 2 Firefox versions', 'not Firefox < 60',
'last 2 Edge versions', 'last 2 Edge versions', 'not Edge < 16',
] }; ] };
let cache = {}; let cache = {};
@@ -197,7 +196,7 @@ gulp.task('qunit', () => {
let serverConfig = { let serverConfig = {
root, root,
port: 8009, port: 8009,
host: 'localhost', host: '0.0.0.0',
name: 'test-server' name: 'test-server'
} }
@@ -269,20 +268,16 @@ gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test'))
gulp.task('build', gulp.parallel('js', 'css', 'plugins')) gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
gulp.task('package', gulp.series(() => gulp.task('package', gulp.series('default', () =>
gulp.src( gulp.src([
[
'./index.html', './index.html',
'./dist/**', './dist/**',
'./lib/**', './lib/**',
'./images/**', './images/**',
'./plugin/**', './plugin/**',
'./**.md' './**.md'
], ]).pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
{ base: './' }
)
.pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
)) ))
@@ -294,15 +289,15 @@ gulp.task('serve', () => {
connect.server({ connect.server({
root: root, root: root,
port: port, port: port,
host: host, host: '0.0.0.0',
livereload: true livereload: true
}) })
gulp.watch(['*.html', '*.md'], gulp.series('reload')) gulp.watch(['*.html', '*.md'], gulp.series('reload'))
gulp.watch(['js/**'], gulp.series('js', 'reload', 'eslint')) gulp.watch(['js/**'], gulp.series('js', 'reload', 'test'))
gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload')) gulp.watch(['plugin/**/plugin.js'], gulp.series('plugins', 'reload'))
gulp.watch([ gulp.watch([
'css/theme/source/*.{sass,scss}', 'css/theme/source/*.{sass,scss}',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

View File

@@ -1,196 +1,317 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8">
<meta <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>reveal.js</title> <title>reveal.js</title>
<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/serif.css" /> <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" /> <link rel="stylesheet" href="plugin/highlight/monokai.css">
<style>
big {
font-size: 139%;
}
</style>
</head> </head>
<body> <body>
<div class="reveal"> <div class="reveal">
<div class="slides"> <div class="slides">
<section data-markdown>
![logo](./images/logo.png)
### Accounting Internship Report
- Author: CHEN Yongyuan (Walter)
- Report date: 2022-11-09
Note:
My name is Walter.
First of all, I am very happy that I can share my accounting internship experience here.
During last summer holiday, I took an internship at Grant Thornton.
</section>
<section data-markdown>
### Agenda
1. About the accounting internship
2. Details of the internship project
3. Key lessons learned
4. Suggestion
</section>
<section> <section>
<section
data-background-image="./images/haiyoulogo.png"
data-background-size="contain"
data-background-opacity="0.139"
>
<h3>Accounting Internship Overview</h3>
<ul>
<li class="fragment">
🏠 Company: China National Offshore Oil Corp
(<b>CNOOC Guangdong Sales Co. Ltd</b>)
</li>
<aside class="notes">
<p>
The company we audited was CNOOC which this is a huge group coporation.
Our team is focusing on the CNOOC Guangdong sales company.
</p>
</aside>
<li class="fragment">👨 Supervisor: FU Kaijun</li>
<aside class="notes">
<p>
My supervisor, also our team leader, is FU kaijun.
</p>
</aside>
<li class="fragment">👕 Role: Audit assistant of Guangdong audit team</li>
<aside class="notes">
<p>
My role in the audit team is audit assistant.
I assist the team to do some of the perform substantive procedures.
Also, I check for errors in the subsidiary's financial reports and parent's consolidated financial statements.
Then I summarize my work into audit working paper.
</p>
</aside>
<li class="fragment">🌍 Location: Guangdong area (Zhanjiang, Zhuhai, Jiangmen, and Guangzhou)</li>
<aside class="notes">
<p>
There are many subsidiaries in Guangdong, and our team is mainly responsible for (these places).
and finally, we returned to the parent company in Guangzhou to do the work related to consolidation.
</p>
</aside>
</ul>
<p class="fragment" style="text-align: left;">
My job is to perform
<span class="fragment highlight-red">substantive procedures</span>,
<span class="fragment highlight-green">prepare audit working paper</span>,
and <span class="fragment highlight-blue">write programs</span> to reduce repetitive work.
</p>
</section>
<section data-background-image="./images/guquanjiegou.png" data-background-size="contain">
<aside class="notes">
This is the equity strcture.
Our team is focusing on the CNOOC Guangdong sales company which has more than 27 subsidiaries.
</aside>
</section>
<section data-background-image="./images/oil.jpg" data-background-size="contain">
<aside class="notes">
We go to each subsidiary's gas station to check fixed assets and oil inventory.
</aside>
</section>
<section data-background-image="./images/paper.jpg" data-background-size="contain">
<aside class="notes">
In this photo, we use sampling method to get a checklist, and then we go to the office to look for the corresponding accounting documents according to the checklist.
</aside>
</section>
<section data-background-image="./images/report.png" data-background-size="contain">
<aside class="notes">
And another of my job, which is probably why I got hired, is to write a computer program to automatically transfer some data from excel to word report.
Because during the interview they asked my lots of question about the PDF and excel processing.
</aside>
</section>
<section data-background-image="./images/highlight.png" data-background-size="contain"></section>
<section data-background-image="./images/excel.png" data-background-size="contain"></section>
</section>
<section> <section>
<section data-markdown> <h2>代码如诗</h2>
### Key Lessons Learned <small>Python 代码风格规范 (PEP8)</small>
> If there is anything unsure, be sure to ask.
Notes:
Although I had not taken any auditing course when I start the internship, I still manage to learn some basic concept before I went to workplace.
During the internship, I learned a lot, not just accounting and auditing standard such as consolidated financial statement.
Also include work etiquette, communication methods, etc.
The first lessons I learned, also the first thing my supervisor told my in the work, is if there anything unsure, be sure to ask.
Let me explain.
Our audit schedule is very tight.
We spent most of our time in reviewing and correcting errors in financial statements.
After we audit the subsidiaries individual financial statement, then we will put them together and review the consolidated financial statement.
At the same time, we will also prepare audit papers.
So that means if there are errors in subsidiary's statement, but found it during the consolidated process, that means we need to go back to readjust the consolidated statement and audit worksheet.
This will not only slow down the entire audit project, but also add extra workload to other team members.
</section>
<section data-markdown>
### Key Lessons Learned
> Don't work hard, work smart!
Notes:
The difference between work hard and work smart is how much time you spend in completing tasks. Hard work tends to be when someone spends a great amout of time completing many things, while smart work is when they spend more time to find the right way to complete right things.
A very typically example during my internship is. Once we use scanner to scan hundreds of documents and needed to rename those file in certain order. On of my co-worker said "Okey, just give me one hour I will rename them one by one". However the correct way to do that is simply select all files, and press F2 then you can rename all files at once.
At that time I didn't know that F2 is the shortcut to rename files, but I am sure there must be some way to do this task quickly, so I spent two minutes seaerching on Baidu, and spend one minute to complete the task.
In general, if you find yourself doing a very repetitive task, there may be a smater way to accomplish the task. Never stop learning new knowledge.
</section> </section>
</section> </section>
<section> <section>
<section data-markdown> <section data-markdown>
## Suggestion ### 一般注释
```python
some_code()
more_code_here()
# One sentence explaining
if not data:
do_something_here()
other_code()
```
</section> </section>
<section data-markdown> <section data-markdown>
## For the Company ### 行内注释
> Information Island: Data in system that has no external connectivity. ```python
words = 'Hello, World!' # Some comment here
- Can't sync/compare data between systems something = 'Hahaha' # 注释不需要对齐
- Require manually input data ```
- Involve more errors
- Increase complexity
Invest on developing a all-in-one solution system or pipeline between system, and traning employee to use the system.
Notes:
SAP, 久其报表,海油卡
</section> </section>
<section data-markdown> <section data-markdown>
## For the Accounting Program #### 块注释
- Set a file naming standard ```python
- Instead of something like `Water final ver.2 (1).docx` # 通常在需要 review 的晦涩难懂的代码前
- Set a version control system for the files # 留下 TODO、待 review 的说明
- Automate repetitive tasks # 不要在这里流水帐式描述你的代码
# 如: 「此处判定列表各项均为有效值,然后我们...」
# 要假定 reviewer 比你更懂 Python
if 0 in [!int(node) for node in li]: # 恰到好处的注释
```
> 如果代码不够清晰以至于需要一个注释,那么或许它应该被重写。
</section> </section>
<section> <section data-markdown>
<h2>For Future Accounting Interns</h2> #### 函数注释
<ul>
<li class="fragment">Get an accounting certification</li> ```python
<li class="fragment">Be familiar with Chinese tax & laws</li> def print(arg):
<li class="fragment">Learn a programming language (Recommend: <code>Python</code>)</li> """将 arg 打印在屏幕上
</ul>
这个函数会调用内置方法讲 arg 输出到屏幕上,
注意这个函数不是线程安全的。
参数:
arg: 字符串或可以调用 arg.__str__() 的对象
返回值:
返回一个整数,代表输出的字符串长度
抛出异常:
NameError: 参数没有 __str__() 方法供转化成字符串。
"""
do_some_thing()
```
</section>
<section data-markdown>
#### 类注释
```python
class SampleClass:
"""简单描述这个类
详细说明这个类...
可以有很多行说明...
类成员说名:
Blablabla
"""
def __init__(self, *args):
"""类方法说明"""
```
</section> </section>
</section> </section>
<section> <section>
<h1>Thank you</h1> <section><h1><code>String</code></h1></section>
<p>for listining</p> <section data-markdown=>
需要拼接有空格的字符串,运用占位符
```python
x = '%s, %s!' % (a, b)
x = '{}, {}!'.format(a, b)
x = ', '.join([a, b])
```
直接拼接的字符串
```python
x = a + b
```
</section>
<section data-markdown>
> 注意:使用加法循环拼接字符串,可能导致二次而非线性的运行时间。
BAD
```python
li = ['a', 'very', 'long', 'list']
result = ''
for i in li:
result = result + i
print(result)
```
GOOD
```python
result = ''.join(li)
print(result)
```
</section>
<section data-markdown>
当字符串过长时,使用 `\` 漂亮地分割字符串
```python
s = '这是一个' \
'很长的字符串'
```
</section>
</section>
<section>
<section>其他乱七八糟但很重要的东西</section>
<section>
<p>类名以<big></big>写字母开头 <code>ClassName</code></p>
<p>驼峰<big></big>名法 <code>someFunctionName</code></p>
<p>下划线_命名法 <code>some_variable_name</code></p>
</section>
<section data-markdown>
### 遍历同时操作数组
> 不规范的行为
```python
li = list(range(10))
for i in li:
li.append(i)
```
</section>
<section data-markdown>
### 传参传字典或列表
```python
def foo(i, arg=[]): # 正确做法 arg=None
arg.append(i)
print(arg)
foo('a')
# Output: ['a']
foo('b')
# Output: ['a', 'b']
```
</section>
<section data-markdown>
### 文件中读入的字符莫名消失
复现代码
```python
raw = '第一行\n\r第二行'
for i in raw.split('\n'):
print('---start', i, 'end---')
# Output:
# ---start 第一行 end---
# 第二行 end---
```
</section>
<section data-markdown>
GOOD
```python
if age < 18:
return 'You are too small'
do_something_here()
```
BAD
```python
if age > 18:
do_something_here()
else:
return 'You are too small'
```
</section>
<section data-markdown>
#### 善用 if
GOOD
```python
if data:
break
```
BAD
```python
if data != []:
break
```
</section>
</section>
<section>
<section data-markdown>
## 忍者代码
</section>
<section data-markdown>
#### 没人知道这个变量是什么
- a, b, j, k, l
- str, string, number, list, dict
- data
- data1
- data114514
以及见鬼的缩写
- `ObjStuAre_id`: object_student_area_id
</section>
<section data-markdown>
> 一个变量一杯茶一个bug修一天
- `data`
- `date`
- `l`
- `I`
</section>
<section data-markdown>
#### 没人知道这两是不是同一个东西
- `showMessage`
- `displayMessage`
- `printMessage`
</section>
<section data-markdown>
#### 夸张的变量名
- `very_super_powerful_print_function`
- `lovely_variable`
- `nice_list`
</section>
<section data-markdown>
#### 重叠外部命名空间变量
```python
id = 39
def foo():
id += 1
# 一堆代码
print(id)
```
</section>
<section data-markdown>
#### Powerful Function !
例如某个 `check_empty_in_list()`,按字面意思会检查列表中是否有空项,可这个函数在检查到空项的同时还会「智能地」帮你删掉空项。然而使用函数的人对此一无所知,函数作者也忘了有这么回事。
</section>
<section>
<p>一行!展现你的聪明才智!</p>
<code>
result = not os.system(' '.join(['proxychains', '-q', 'pandoc', 'README.md', 'SUMMARY.md', ' '.join([str(i)+'.md' for i in range(3, 109+1)]), '-o', '/tmp/out.epub']) or print("Failed")
</code>
</section>
</section>
<section>
<section style="text-align: left;" data-markdown>
#### References
- [现代 JavaScript 教程 - 忍者代码](https://zh.javascript.infoi/ninja-code)
- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
- [水族馆](https://aquarium39.moe)
- [你所不知道的Python冷知識](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/649905/)
</section>
</section> </section>
</div> </div>
</div> </div>
@@ -199,18 +320,15 @@
<script src="plugin/notes/notes.js"></script> <script src="plugin/notes/notes.js"></script>
<script src="plugin/markdown/markdown.js"></script> <script src="plugin/markdown/markdown.js"></script>
<script src="plugin/highlight/highlight.js"></script> <script src="plugin/highlight/highlight.js"></script>
<script src="plugin/zoom/zoom.js"></script>
<script> <script>
// More info about initialization & config: // More info about initialization & config:
// - https://revealjs.com/initialization/ // - https://revealjs.com/initialization/
// - https://revealjs.com/config/ // - https://revealjs.com/config/
Reveal.initialize({ Reveal.initialize({
hash: true, hash: true,
width: 1920,
height: 1080,
// Learn about plugins: https://revealjs.com/plugins/ // Learn about plugins: https://revealjs.com/plugins/
plugins: [RevealMarkdown, RevealHighlight, RevealNotes, RevealZoom], plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
}); });
</script> </script>
</body> </body>

View File

@@ -50,19 +50,11 @@ export default class AutoAnimate {
// Flag the navigation direction, needed for fragment buildup // Flag the navigation direction, needed for fragment buildup
animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward'; animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
// If the from-slide is hidden because it has moved outside
// the view distance, we need to temporarily show it while
// measuring
let fromSlideIsHidden = fromSlide.style.display === 'none';
if( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;
// Inject our auto-animate styles for this transition // Inject our auto-animate styles for this transition
let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => { let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ ); return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
} ); } );
if( fromSlideIsHidden ) fromSlide.style.display = 'none';
// Animate unmatched elements, if enabled // Animate unmatched elements, if enabled
if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) { if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
@@ -399,15 +391,8 @@ export default class AutoAnimate {
value = { value: style.to, explicitValue: true }; value = { value: style.to, explicitValue: true };
} }
else { else {
// Use a unitless value for line-height so that it inherits properly
if( style.property === 'line-height' ) {
value = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );
}
if( isNaN(value) ) {
value = computedStyles[style.property]; value = computedStyles[style.property];
} }
}
if( value !== '' ) { if( value !== '' ) {
properties.styles[style.property] = value; properties.styles[style.property] = value;
@@ -482,6 +467,7 @@ export default class AutoAnimate {
} ); } );
pairs.forEach( pair => { pairs.forEach( pair => {
// Disable scale transformations on text nodes, we transition // Disable scale transformations on text nodes, we transition
// each individual text property instead // each individual text property instead
if( matches( pair.from, textNodes ) ) { if( matches( pair.from, textNodes ) ) {

View File

@@ -122,7 +122,6 @@ export default class Backgrounds {
backgroundVideo: slide.getAttribute( 'data-background-video' ), backgroundVideo: slide.getAttribute( 'data-background-video' ),
backgroundIframe: slide.getAttribute( 'data-background-iframe' ), backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
backgroundColor: slide.getAttribute( 'data-background-color' ), backgroundColor: slide.getAttribute( 'data-background-color' ),
backgroundGradient: slide.getAttribute( 'data-background-gradient' ),
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
backgroundPosition: slide.getAttribute( 'data-background-position' ), backgroundPosition: slide.getAttribute( 'data-background-position' ),
backgroundTransition: slide.getAttribute( 'data-background-transition' ), backgroundTransition: slide.getAttribute( 'data-background-transition' ),
@@ -151,7 +150,7 @@ export default class Backgrounds {
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|webp)([?#\s]|$)/gi.test( data.background ) ) { if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) {
slide.setAttribute( 'data-background-image', data.background ); slide.setAttribute( 'data-background-image', data.background );
} }
else { else {
@@ -162,14 +161,13 @@ export default class Backgrounds {
// Create a hash for this combination of background settings. // Create a hash for this combination of background settings.
// This is used to determine when two slide backgrounds are // This is used to determine when two slide backgrounds are
// the same. // the same.
if( data.background || data.backgroundColor || data.backgroundGradient || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) { if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
element.setAttribute( 'data-background-hash', data.background + element.setAttribute( 'data-background-hash', data.background +
data.backgroundSize + data.backgroundSize +
data.backgroundImage + data.backgroundImage +
data.backgroundVideo + data.backgroundVideo +
data.backgroundIframe + data.backgroundIframe +
data.backgroundColor + data.backgroundColor +
data.backgroundGradient +
data.backgroundRepeat + data.backgroundRepeat +
data.backgroundPosition + data.backgroundPosition +
data.backgroundTransition + data.backgroundTransition +
@@ -179,7 +177,6 @@ export default class Backgrounds {
// Additional and optional background properties // Additional and optional background properties
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize ); if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
if( data.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
if( dataPreload ) element.setAttribute( 'data-preload', '' ); if( dataPreload ) element.setAttribute( 'data-preload', '' );
@@ -397,10 +394,4 @@ export default class Backgrounds {
} }
destroy() {
this.element.remove();
}
} }

View File

@@ -188,13 +188,6 @@ export default class Controls {
} }
} }
destroy() {
this.unbind();
this.element.remove();
}
/** /**
* Event handlers for navigation control buttons. * Event handlers for navigation control buttons.
*/ */

View File

@@ -79,12 +79,6 @@ export default class Focus {
} }
destroy() {
this.Reveal.getRevealElement().classList.remove( 'focused' );
}
onRevealPointerDown( event ) { onRevealPointerDown( event ) {
this.focus(); this.focus();

View File

@@ -32,15 +32,15 @@ export default class Keyboard {
} }
else { else {
this.shortcuts['N , SPACE'] = 'Next slide'; this.shortcuts['N , SPACE'] = 'Next slide';
this.shortcuts['P , Shift SPACE'] = 'Previous slide'; this.shortcuts['P'] = 'Previous slide';
this.shortcuts['&#8592; , H'] = 'Navigate left'; this.shortcuts['&#8592; , H'] = 'Navigate left';
this.shortcuts['&#8594; , L'] = 'Navigate right'; this.shortcuts['&#8594; , L'] = 'Navigate right';
this.shortcuts['&#8593; , K'] = 'Navigate up'; this.shortcuts['&#8593; , K'] = 'Navigate up';
this.shortcuts['&#8595; , J'] = 'Navigate down'; this.shortcuts['&#8595; , J'] = 'Navigate down';
} }
this.shortcuts['Alt + &#8592;/&#8593/&#8594;/&#8595;'] = 'Navigate without fragments'; this.shortcuts['Home , Shift &#8592;'] = 'First slide';
this.shortcuts['Shift + &#8592;/&#8593/&#8594;/&#8595;'] = 'Jump to first/last slide'; this.shortcuts['End , Shift &#8594;'] = 'Last slide';
this.shortcuts['B , .'] = 'Pause'; this.shortcuts['B , .'] = 'Pause';
this.shortcuts['F'] = 'Fullscreen'; this.shortcuts['F'] = 'Fullscreen';
this.shortcuts['ESC, O'] = 'Slide overview'; this.shortcuts['ESC, O'] = 'Slide overview';
@@ -182,11 +182,13 @@ export default class Keyboard {
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName ); let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className); let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
// Whitelist certain modifiers for slide navigation shortcuts // Whitelist specific modified + keycode combinations
let isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1; let prevSlideShortcut = event.shiftKey && event.keyCode === 32;
let firstSlideShortcut = event.shiftKey && keyCode === 37;
let lastSlideShortcut = event.shiftKey && keyCode === 39;
// Prevent all other events when a modifier is pressed // Prevent all other events when a modifier is pressed
let unusedModifier = !( isNavigationKey && event.shiftKey || event.altKey ) && let unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ); ( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
// Disregard the event if there's a focused element or a // Disregard the event if there's a focused element or a
@@ -275,58 +277,52 @@ export default class Keyboard {
// P, PAGE UP // P, PAGE UP
if( keyCode === 80 || keyCode === 33 ) { if( keyCode === 80 || keyCode === 33 ) {
this.Reveal.prev({skipFragments: event.altKey}); this.Reveal.prev();
} }
// N, PAGE DOWN // N, PAGE DOWN
else if( keyCode === 78 || keyCode === 34 ) { else if( keyCode === 78 || keyCode === 34 ) {
this.Reveal.next({skipFragments: event.altKey}); this.Reveal.next();
} }
// H, LEFT // H, LEFT
else if( keyCode === 72 || keyCode === 37 ) { else if( keyCode === 72 || keyCode === 37 ) {
if( event.shiftKey ) { if( firstSlideShortcut ) {
this.Reveal.slide( 0 ); this.Reveal.slide( 0 );
} }
else if( !this.Reveal.overview.isActive() && useLinearMode ) { else if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.prev({skipFragments: event.altKey}); this.Reveal.prev();
} }
else { else {
this.Reveal.left({skipFragments: event.altKey}); this.Reveal.left();
} }
} }
// L, RIGHT // L, RIGHT
else if( keyCode === 76 || keyCode === 39 ) { else if( keyCode === 76 || keyCode === 39 ) {
if( event.shiftKey ) { if( lastSlideShortcut ) {
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 ); this.Reveal.slide( Number.MAX_VALUE );
} }
else if( !this.Reveal.overview.isActive() && useLinearMode ) { else if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.next({skipFragments: event.altKey}); this.Reveal.next();
} }
else { else {
this.Reveal.right({skipFragments: event.altKey}); this.Reveal.right();
} }
} }
// K, UP // K, UP
else if( keyCode === 75 || keyCode === 38 ) { else if( keyCode === 75 || keyCode === 38 ) {
if( event.shiftKey ) { if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.slide( undefined, 0 ); this.Reveal.prev();
}
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.prev({skipFragments: event.altKey});
} }
else { else {
this.Reveal.up({skipFragments: event.altKey}); this.Reveal.up();
} }
} }
// J, DOWN // J, DOWN
else if( keyCode === 74 || keyCode === 40 ) { else if( keyCode === 74 || keyCode === 40 ) {
if( event.shiftKey ) { if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.slide( undefined, Number.MAX_VALUE ); this.Reveal.next();
}
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
this.Reveal.next({skipFragments: event.altKey});
} }
else { else {
this.Reveal.down({skipFragments: event.altKey}); this.Reveal.down();
} }
} }
// HOME // HOME
@@ -335,7 +331,7 @@ export default class Keyboard {
} }
// END // END
else if( keyCode === 35 ) { else if( keyCode === 35 ) {
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 ); this.Reveal.slide( Number.MAX_VALUE );
} }
// SPACE // SPACE
else if( keyCode === 32 ) { else if( keyCode === 32 ) {
@@ -343,10 +339,10 @@ export default class Keyboard {
this.Reveal.overview.deactivate(); this.Reveal.overview.deactivate();
} }
if( event.shiftKey ) { if( event.shiftKey ) {
this.Reveal.prev({skipFragments: event.altKey}); this.Reveal.prev();
} }
else { else {
this.Reveal.next({skipFragments: event.altKey}); this.Reveal.next();
} }
} }
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON // TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON

View File

@@ -3,10 +3,6 @@
*/ */
export default class Location { export default class Location {
// The minimum number of milliseconds that must pass between
// calls to history.replaceState
MAX_REPLACE_STATE_FREQUENCY = 1000
constructor( Reveal ) { constructor( Reveal ) {
this.Reveal = Reveal; this.Reveal = Reveal;
@@ -14,8 +10,6 @@ export default class Location {
// Delays updates to the URL due to a Chrome thumbnailer bug // Delays updates to the URL due to a Chrome thumbnailer bug
this.writeURLTimeout = 0; this.writeURLTimeout = 0;
this.replaceStateTimestamp = 0;
this.onWindowHashChange = this.onWindowHashChange.bind( this ); this.onWindowHashChange = this.onWindowHashChange.bind( this );
} }
@@ -33,18 +27,19 @@ export default class Location {
} }
/** /**
* Returns the slide indices for the given hash link. * Reads the current URL (hash) and navigates accordingly.
*
* @param {string} [hash] the hash string that we want to
* find the indices for
*
* @returns slide indices or null
*/ */
getIndicesFromHash( hash=window.location.hash ) { readURL() {
let config = this.Reveal.getConfig();
let indices = this.Reveal.getIndices();
let currentSlide = this.Reveal.getCurrentSlide();
let hash = window.location.hash;
// Attempt to parse the hash as either an index or name // Attempt to parse the hash as either an index or name
let name = hash.replace( /^#\/?/, '' ); let bits = hash.slice( 2 ).split( '/' ),
let bits = name.split( '/' ); name = hash.replace( /#\/?/gi, '' );
// If the first bit is not fully numeric and there is a name we // If the first bit is not fully numeric and there is a name we
// can assume that this is a named link // can assume that this is a named link
@@ -66,12 +61,23 @@ export default class Location {
} }
catch ( error ) { } catch ( error ) { }
// Ensure that we're not already on a slide with the same name
let isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false;
if( element ) { if( element ) {
return { ...this.Reveal.getIndices( element ), f }; // If the slide exists and is not the current slide...
if ( !isSameNameAsCurrentSlide || typeof f !== 'undefined' ) {
// ...find the position of the named slide and navigate to it
let slideIndices = this.Reveal.getIndices( element );
this.Reveal.slide( slideIndices.h, slideIndices.v, f );
}
}
// If the slide doesn't exist, navigate to the current slide
else {
this.Reveal.slide( indices.h || 0, indices.v || 0 );
} }
} }
else { else {
const config = this.Reveal.getConfig();
let hashIndexBase = config.hashOneBasedIndex ? 1 : 0; let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
// Read the index components of the hash // Read the index components of the hash
@@ -86,31 +92,9 @@ export default class Location {
} }
} }
return { h, v, f }; if( h !== indices.h || v !== indices.v || f !== undefined ) {
this.Reveal.slide( h, v, f );
} }
// The hash couldn't be parsed or no matching named link was found
return null
}
/**
* Reads the current URL (hash) and navigates accordingly.
*/
readURL() {
const currentIndices = this.Reveal.getIndices();
const newIndices = this.getIndicesFromHash();
if( newIndices ) {
if( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
}
}
// If no new indices are available, we're trying to navigate to
// a slide hash that does not exist
else {
this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
} }
} }
@@ -148,10 +132,10 @@ export default class Location {
else if( config.hash ) { else if( config.hash ) {
// If the hash is empty, don't add it to the URL // If the hash is empty, don't add it to the URL
if( hash === '/' ) { if( hash === '/' ) {
this.debouncedReplaceState( window.location.pathname + window.location.search ); window.history.replaceState( null, null, window.location.pathname + window.location.search );
} }
else { else {
this.debouncedReplaceState( '#' + hash ); window.history.replaceState( null, null, '#' + hash );
} }
} }
// UPDATE: The below nuking of all hash changes breaks // UPDATE: The below nuking of all hash changes breaks
@@ -169,26 +153,6 @@ export default class Location {
} }
replaceState( url ) {
window.history.replaceState( null, null, url );
this.replaceStateTimestamp = Date.now();
}
debouncedReplaceState( url ) {
clearTimeout( this.replaceStateTimeout );
if( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {
this.replaceState( url );
}
else {
this.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );
}
}
/** /**
* Return a hash URL that will resolve to the given slide location. * Return a hash URL that will resolve to the given slide location.
* *

View File

@@ -1,5 +1,5 @@
/** /**
* Handles the showing of speaker notes * Handles the showing and
*/ */
export default class Notes { export default class Notes {
@@ -89,7 +89,7 @@ export default class Notes {
* Retrieves the speaker notes from a slide. Notes can be * Retrieves the speaker notes from a slide. Notes can be
* defined in two ways: * defined in two ways:
* 1. As a data-notes attribute on the slide <section> * 1. As a data-notes attribute on the slide <section>
* 2. With <aside class="notes"> elements inside the slide * 2. As an <aside class="notes"> inside of the slide
* *
* @param {HTMLElement} [slide=currentSlide] * @param {HTMLElement} [slide=currentSlide]
* @return {(string|null)} * @return {(string|null)}
@@ -101,20 +101,14 @@ export default class Notes {
return slide.getAttribute( 'data-notes' ); return slide.getAttribute( 'data-notes' );
} }
// ... or using <aside class="notes"> elements // ... or using an <aside class="notes"> element
let notesElements = slide.querySelectorAll( 'aside.notes' ); let notesElement = slide.querySelector( 'aside.notes' );
if( notesElements ) { if( notesElement ) {
return Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' ); return notesElement.innerHTML;
} }
return null; return null;
} }
destroy() {
this.element.remove();
}
} }

View File

@@ -238,17 +238,4 @@ export default class Plugins {
} }
destroy() {
Object.values( this.registeredPlugins ).forEach( plugin => {
if( typeof plugin.destroy === 'function' ) {
plugin.destroy();
}
} );
this.registeredPlugins = {};
this.asyncDependencies = [];
}
} }

View File

@@ -75,17 +75,6 @@ export default class Pointer {
} }
destroy() {
this.showCursor();
document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false );
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
}
/** /**
* Called whenever there is mouse input at the document level * Called whenever there is mouse input at the document level
* to determine if the cursor is active or not. * to determine if the cursor is active or not.

View File

@@ -22,7 +22,7 @@ export default class Print {
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ) const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
// Compute slide numbers now, before we start duplicating slides // Compute slide numbers now, before we start duplicating slides
const injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber ); const doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight ); const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
@@ -46,19 +46,14 @@ export default class Print {
document.body.style.width = pageWidth + 'px'; document.body.style.width = pageWidth + 'px';
document.body.style.height = pageHeight + 'px'; document.body.style.height = pageHeight + 'px';
const viewportElement = document.querySelector( '.reveal-viewport' );
let presentationBackground;
if( viewportElement ) {
const viewportStyles = window.getComputedStyle( viewportElement );
if( viewportStyles && viewportStyles.background ) {
presentationBackground = viewportStyles.background;
}
}
// Make sure stretch elements fit on slide // Make sure stretch elements fit on slide
await new Promise( requestAnimationFrame ); await new Promise( requestAnimationFrame );
this.Reveal.layoutSlideContents( slideWidth, slideHeight ); this.Reveal.layoutSlideContents( slideWidth, slideHeight );
// 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 // Batch scrollHeight access to prevent layout thrashing
await new Promise( requestAnimationFrame ); await new Promise( requestAnimationFrame );
@@ -66,7 +61,6 @@ export default class Print {
const pages = []; const pages = [];
const pageContainer = slides[0].parentNode; const pageContainer = slides[0].parentNode;
let slideNumber = 1;
// Slide and slide background layout // Slide and slide background layout
slides.forEach( function( slide, index ) { slides.forEach( function( slide, index ) {
@@ -96,13 +90,6 @@ export default class Print {
page.className = 'pdf-page'; page.className = 'pdf-page';
page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px'; page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
// Copy the presentation-wide background to each individual
// page when printing
if( presentationBackground ) {
page.style.background = presentationBackground;
}
page.appendChild( slide ); page.appendChild( slide );
// Position the slide inside of the page // Position the slide inside of the page
@@ -110,8 +97,6 @@ export default class Print {
slide.style.top = top + 'px'; slide.style.top = top + 'px';
slide.style.width = slideWidth + 'px'; slide.style.width = slideWidth + 'px';
this.Reveal.slideContent.layout( slide );
if( slide.slideBackgroundElement ) { if( slide.slideBackgroundElement ) {
page.insertBefore( slide.slideBackgroundElement, slide ); page.insertBefore( slide.slideBackgroundElement, slide );
} }
@@ -145,12 +130,13 @@ export default class Print {
} }
// Inject page numbers if `slideNumbers` are enabled // Inject slide numbers if `slideNumbers` are enabled
if( injectPageNumbers ) { if( doingSlideNumbers ) {
const slideNumber = index + 1;
const numberElement = document.createElement( 'div' ); 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 = slideNumber++; numberElement.innerHTML = slideNumber;
page.appendChild( numberElement ); page.appendChild( numberElement );
} }
@@ -164,7 +150,7 @@ export default class Print {
let previousFragmentStep; let previousFragmentStep;
fragmentGroups.forEach( function( fragments, index ) { fragmentGroups.forEach( function( fragments ) {
// Remove 'current-fragment' from the previous group // Remove 'current-fragment' from the previous group
if( previousFragmentStep ) { if( previousFragmentStep ) {
@@ -180,14 +166,6 @@ export default class Print {
// Create a separate page for the current fragment state // Create a separate page for the current fragment state
const clonedPage = page.cloneNode( true ); const clonedPage = page.cloneNode( true );
// Inject unique page numbers for fragments
if( injectPageNumbers ) {
const numberElement = clonedPage.querySelector( '.slide-number-pdf' );
const fragmentNumber = index + 1;
numberElement.innerHTML += '.' + fragmentNumber;
}
pages.push( clonedPage ); pages.push( clonedPage );
previousFragmentStep = fragments; previousFragmentStep = fragments;
@@ -217,9 +195,6 @@ export default class Print {
pages.forEach( page => pageContainer.appendChild( page ) ); pages.forEach( page => pageContainer.appendChild( page ) );
// Re-run JS-based content layout after the slide is added to page DOM
this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
// 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

@@ -101,10 +101,5 @@ export default class Progress {
} }
destroy() {
this.element.remove();
}
} }

View File

@@ -1,4 +1,5 @@
import { extend, queryAll, closest, getMimeTypeFromFile } from '../utils/util.js' import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'
import { extend, queryAll, closest } from '../utils/util.js'
import { isMobile } from '../utils/device.js' import { isMobile } from '../utils/device.js'
import fitty from 'fitty'; import fitty from 'fitty';
@@ -101,17 +102,10 @@ export default class SlideContent {
// Images // Images
if( backgroundImage ) { if( backgroundImage ) {
// base64
if( /^data:/.test( backgroundImage.trim() ) ) {
backgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;
}
// URL(s)
else {
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => { backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
return `url(${encodeURI(background.trim())})`; return `url(${encodeURI(background.trim())})`;
}).join( ',' ); }).join( ',' );
} }
}
// Videos // Videos
else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) { else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
let video = document.createElement( 'video' ); let video = document.createElement( 'video' );
@@ -136,13 +130,7 @@ export default class SlideContent {
// Support comma separated lists of video sources // Support comma separated lists of video sources
backgroundVideo.split( ',' ).forEach( source => { backgroundVideo.split( ',' ).forEach( source => {
let type = getMimeTypeFromFile( source ); video.innerHTML += '<source src="'+ source +'">';
if( type ) {
video.innerHTML += `<source src="${source}" type="${type}">`;
}
else {
video.innerHTML += `<source src="${source}">`;
}
} ); } );
backgroundContent.appendChild( video ); backgroundContent.appendChild( video );
@@ -186,14 +174,15 @@ export default class SlideContent {
} }
/** /**
* Applies JS-dependent layout helpers for the scope. * Applies JS-dependent layout helpers for the given slide,
* if there are any.
*/ */
layout( scopeElement ) { 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( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => { Array.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
fitty( element, { fitty( element, {
minSize: 24, minSize: 24,
maxSize: this.Reveal.getConfig().height * 0.8, maxSize: this.Reveal.getConfig().height * 0.8,

View File

@@ -123,10 +123,4 @@ export default class SlideNumber {
} }
destroy() {
this.element.remove();
}
} }

View File

@@ -26,14 +26,14 @@ import {
} from './utils/constants.js' } from './utils/constants.js'
// The reveal.js version // The reveal.js version
export const VERSION = '4.4.0'; export const VERSION = '4.1.3';
/** /**
* reveal.js * reveal.js
* https://revealjs.com * https://revealjs.com
* MIT licensed * MIT licensed
* *
* Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se * Copyright (C) 2020 Hakim El Hattab, https://hakim.se
*/ */
export default function( revealElement, options ) { export default function( revealElement, options ) {
@@ -121,14 +121,10 @@ export default function( revealElement, options ) {
*/ */
function initialize( initOptions ) { function initialize( initOptions ) {
if( !revealElement ) throw 'Unable to find presentation root (<div class="reveal">).';
// Cache references to key DOM elements // Cache references to key DOM elements
dom.wrapper = revealElement; dom.wrapper = revealElement;
dom.slides = revealElement.querySelector( '.slides' ); dom.slides = revealElement.querySelector( '.slides' );
if( !dom.slides ) throw 'Unable to find slides container (<div class="slides">).';
// Compose our config object in order of increasing precedence: // Compose our config object in order of increasing precedence:
// 1. Default reveal.js options // 1. Default reveal.js options
// 2. Options provided via Reveal.configure() prior to // 2. Options provided via Reveal.configure() prior to
@@ -190,9 +186,6 @@ export default function( revealElement, options ) {
// Prevent the slides from being scrolled out of view // Prevent the slides from being scrolled out of view
setupScrollPrevention(); setupScrollPrevention();
// Adds bindings for fullscreen mode
setupFullscreen();
// Resets all vertical slides so that only the first is visible // Resets all vertical slides so that only the first is visible
resetVerticalSlides(); resetVerticalSlides();
@@ -379,19 +372,6 @@ export default function( revealElement, options ) {
} }
/**
* After entering fullscreen we need to force a layout to
* get our presentations to scale correctly. This behavior
* is inconsistent across browsers but a force layout seems
* to normalize it.
*/
function setupFullscreen() {
document.addEventListener( 'fullscreenchange', onFullscreenChange );
document.addEventListener( 'webkitfullscreenchange', onFullscreenChange );
}
/** /**
* Registers a listener to postMessage events, this makes it * Registers a listener to postMessage events, this makes it
* possible to call all reveal.js API methods from another * possible to call all reveal.js API methods from another
@@ -405,7 +385,32 @@ export default function( revealElement, options ) {
function setupPostMessage() { function setupPostMessage() {
if( config.postMessage ) { if( config.postMessage ) {
window.addEventListener( 'message', onPostMessage, false ); window.addEventListener( 'message', event => {
let data = event.data;
// Make sure we're dealing with JSON
if( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {
data = JSON.parse( data );
// Check if the requested method can be found
if( data.method && typeof Reveal[data.method] === 'function' ) {
if( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {
const result = Reveal[data.method].apply( Reveal, data.args );
// Dispatch a postMessage event with the returned value from
// our method invocation for getter functions
dispatchPostMessage( 'callback', { method: data.method, result: result } );
}
else {
console.warn( 'reveal.js: "'+ data.method +'" is is blacklisted from the postMessage API' );
}
}
}
}, false );
} }
} }
@@ -520,7 +525,6 @@ export default function( revealElement, options ) {
controls.bind(); controls.bind();
focus.bind(); focus.bind();
dom.slides.addEventListener( 'click', onSlidesClicked, false );
dom.slides.addEventListener( 'transitionend', onTransitionEnd, false ); dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
dom.pauseOverlay.addEventListener( 'click', resume, false ); dom.pauseOverlay.addEventListener( 'click', resume, false );
@@ -546,71 +550,11 @@ export default function( revealElement, options ) {
window.removeEventListener( 'resize', onWindowResize, false ); window.removeEventListener( 'resize', onWindowResize, false );
dom.slides.removeEventListener( 'click', onSlidesClicked, false );
dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false ); dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );
dom.pauseOverlay.removeEventListener( 'click', resume, false ); dom.pauseOverlay.removeEventListener( 'click', resume, false );
} }
/**
* Uninitializes reveal.js by undoing changes made to the
* DOM and removing all event listeners.
*/
function destroy() {
removeEventListeners();
cancelAutoSlide();
disablePreviewLinks();
// Destroy controllers
notes.destroy();
focus.destroy();
plugins.destroy();
pointer.destroy();
controls.destroy();
progress.destroy();
backgrounds.destroy();
slideNumber.destroy();
// Remove event listeners
document.removeEventListener( 'fullscreenchange', onFullscreenChange );
document.removeEventListener( 'webkitfullscreenchange', onFullscreenChange );
document.removeEventListener( 'visibilitychange', onPageVisibilityChange, false );
window.removeEventListener( 'message', onPostMessage, false );
window.removeEventListener( 'load', layout, false );
// Undo DOM changes
if( dom.pauseOverlay ) dom.pauseOverlay.remove();
if( dom.statusElement ) dom.statusElement.remove();
document.documentElement.classList.remove( 'reveal-full-page' );
dom.wrapper.classList.remove( 'ready', 'center', 'has-horizontal-slides', 'has-vertical-slides' );
dom.wrapper.removeAttribute( 'data-transition-speed' );
dom.wrapper.removeAttribute( 'data-background-transition' );
dom.viewport.classList.remove( 'reveal-viewport' );
dom.viewport.style.removeProperty( '--slide-width' );
dom.viewport.style.removeProperty( '--slide-height' );
dom.slides.style.removeProperty( 'width' );
dom.slides.style.removeProperty( 'height' );
dom.slides.style.removeProperty( 'zoom' );
dom.slides.style.removeProperty( 'left' );
dom.slides.style.removeProperty( 'top' );
dom.slides.style.removeProperty( 'bottom' );
dom.slides.style.removeProperty( 'right' );
dom.slides.style.removeProperty( 'transform' );
Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
slide.style.removeProperty( 'display' );
slide.style.removeProperty( 'top' );
slide.removeAttribute( 'hidden' );
slide.removeAttribute( 'aria-hidden' );
} );
}
/** /**
* Adds a listener to one of our custom reveal.js events, * Adds a listener to one of our custom reveal.js events,
* like slidechanged. * like slidechanged.
@@ -670,8 +614,6 @@ export default function( revealElement, options ) {
dispatchPostMessage( type ); dispatchPostMessage( type );
} }
return event;
} }
/** /**
@@ -897,6 +839,24 @@ export default function( revealElement, options ) {
dom.slides.style.right = ''; dom.slides.style.right = '';
transformSlides( { layout: '' } ); transformSlides( { layout: '' } );
} }
else {
// Zoom Scaling
// Content remains crisp no matter how much we scale. Side
// effects are minor differences in text layout and iframe
// viewports changing size. A 200x200 iframe viewport in a
// 2x zoomed presentation ends up having a 400x400 viewport.
if( scale > 1 && Device.supportsZoom && window.devicePixelRatio < 2 ) {
dom.slides.style.zoom = scale;
dom.slides.style.left = '';
dom.slides.style.top = '';
dom.slides.style.bottom = '';
dom.slides.style.right = '';
transformSlides( { layout: '' } );
}
// Transform Scaling
// Content layout remains the exact same when scaled up.
// Side effect is content becoming blurred, especially with
// high scale values on ldpi screens.
else { else {
dom.slides.style.zoom = ''; dom.slides.style.zoom = '';
dom.slides.style.left = '50%'; dom.slides.style.left = '50%';
@@ -905,6 +865,7 @@ export default function( revealElement, options ) {
dom.slides.style.right = 'auto'; dom.slides.style.right = 'auto';
transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } ); transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );
} }
}
// Select all slides, vertical and horizontal // Select all slides, vertical and horizontal
const slides = Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ); const slides = Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) );
@@ -945,8 +906,6 @@ export default function( revealElement, options ) {
} }
} }
dom.viewport.style.setProperty( '--slide-scale', scale );
progress.update(); progress.update();
backgrounds.updateParallax(); backgrounds.updateParallax();
@@ -1229,22 +1188,9 @@ export default function( revealElement, options ) {
* @param {number} [v=indexv] Vertical index of the target slide * @param {number} [v=indexv] Vertical index of the target slide
* @param {number} [f] Index of a fragment within the * @param {number} [f] Index of a fragment within the
* target slide to activate * target slide to activate
* @param {number} [origin] Origin for use in multimaster environments * @param {number} [o] Origin for use in multimaster environments
*/ */
function slide( h, v, f, origin ) { function slide( h, v, f, o ) {
// Dispatch an event before hte slide
const slidechange = dispatchEvent({
type: 'beforeslidechange',
data: {
indexh: h === undefined ? indexh : h,
indexv: v === undefined ? indexv : v,
origin
}
});
// Abort if this slide change was prevented by an event listener
if( slidechange.defaultPrevented ) return;
// Remember where we were at before // Remember where we were at before
previousSlide = currentSlide; previousSlide = currentSlide;
@@ -1380,7 +1326,7 @@ export default function( revealElement, options ) {
indexv, indexv,
previousSlide, previousSlide,
currentSlide, currentSlide,
origin origin: o
} }
}); });
} }
@@ -1571,20 +1517,15 @@ export default function( revealElement, options ) {
slidesLength = slides.length; slidesLength = slides.length;
let printMode = print.isPrintingPDF(); let printMode = print.isPrintingPDF();
let loopedForwards = false;
let loopedBackwards = false;
if( slidesLength ) { if( slidesLength ) {
// Should the index loop? // Should the index loop?
if( config.loop ) { if( config.loop ) {
if( index >= slidesLength ) loopedForwards = true;
index %= slidesLength; index %= slidesLength;
if( index < 0 ) { if( index < 0 ) {
index = slidesLength + index; index = slidesLength + index;
loopedBackwards = true;
} }
} }
@@ -1622,7 +1563,10 @@ export default function( revealElement, options ) {
if( config.fragments ) { if( config.fragments ) {
// Show all fragments in prior slides // Show all fragments in prior slides
showFragmentsIn( element ); Util.queryAll( element, '.fragment' ).forEach( fragment => {
fragment.classList.add( 'visible' );
fragment.classList.remove( 'current-fragment' );
} );
} }
} }
else if( i > index ) { else if( i > index ) {
@@ -1631,17 +1575,9 @@ export default function( revealElement, options ) {
if( config.fragments ) { if( config.fragments ) {
// Hide all fragments in future slides // Hide all fragments in future slides
hideFragmentsIn( element ); Util.queryAll( element, '.fragment.visible' ).forEach( fragment => {
} fragment.classList.remove( 'visible', 'current-fragment' );
} } );
// Update the visibility of fragments when a presentation loops
// in either direction
else if( i === index && config.fragments ) {
if( loopedForwards ) {
hideFragmentsIn( element );
}
else if( loopedBackwards ) {
showFragmentsIn( element );
} }
} }
} }
@@ -1681,29 +1617,6 @@ export default function( revealElement, options ) {
} }
/**
* Shows all fragment elements within the given contaienr.
*/
function showFragmentsIn( container ) {
Util.queryAll( container, '.fragment' ).forEach( fragment => {
fragment.classList.add( 'visible' );
fragment.classList.remove( 'current-fragment' );
} );
}
/**
* Hides all fragment elements within the given contaienr.
*/
function hideFragmentsIn( container ) {
Util.queryAll( container, '.fragment.visible' ).forEach( fragment => {
fragment.classList.remove( 'visible', 'current-fragment' );
} );
}
/** /**
* Optimization method; hide all slides that are far away * Optimization method; hide all slides that are far away
* from the present slide. * from the present slide.
@@ -2280,55 +2193,55 @@ export default function( revealElement, options ) {
} }
function navigateLeft({skipFragments=false}={}) { function navigateLeft() {
navigationHistory.hasNavigatedHorizontally = true; navigationHistory.hasNavigatedHorizontally = true;
// Reverse for RTL // Reverse for RTL
if( config.rtl ) { if( config.rtl ) {
if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().left ) { if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().left ) {
slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
// Normal navigation // Normal navigation
else if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().left ) { else if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().left ) {
slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
function navigateRight({skipFragments=false}={}) { function navigateRight() {
navigationHistory.hasNavigatedHorizontally = true; navigationHistory.hasNavigatedHorizontally = true;
// Reverse for RTL // Reverse for RTL
if( config.rtl ) { if( config.rtl ) {
if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().right ) { if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().right ) {
slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
// Normal navigation // Normal navigation
else if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().right ) { else if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().right ) {
slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
function navigateUp({skipFragments=false}={}) { function navigateUp() {
// Prioritize hiding fragments // Prioritize hiding fragments
if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().up ) { if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().up ) {
slide( indexh, indexv - 1 ); slide( indexh, indexv - 1 );
} }
} }
function navigateDown({skipFragments=false}={}) { function navigateDown() {
navigationHistory.hasNavigatedVertically = true; navigationHistory.hasNavigatedVertically = true;
// Prioritize revealing fragments // Prioritize revealing fragments
if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().down ) { if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {
slide( indexh, indexv + 1 ); slide( indexh, indexv + 1 );
} }
@@ -2340,12 +2253,12 @@ export default function( revealElement, options ) {
* 2) Previous vertical slide * 2) Previous vertical slide
* 3) Previous horizontal slide * 3) Previous horizontal slide
*/ */
function navigatePrev({skipFragments=false}={}) { function navigatePrev() {
// Prioritize revealing fragments // Prioritize revealing fragments
if( skipFragments || fragments.prev() === false ) { if( fragments.prev() === false ) {
if( availableRoutes().up ) { if( availableRoutes().up ) {
navigateUp({skipFragments}); navigateUp();
} }
else { else {
// Fetch the previous horizontal slide, if there is one // Fetch the previous horizontal slide, if there is one
@@ -2358,16 +2271,11 @@ export default function( revealElement, options ) {
previousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.past' ).pop(); previousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.past' ).pop();
} }
// When going backwards and arriving on a stack we start if( previousSlide ) {
// at the bottom of the stack
if( previousSlide && previousSlide.classList.contains( 'stack' ) ) {
let v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined; let v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
let h = indexh - 1; let h = indexh - 1;
slide( h, v ); slide( h, v );
} }
else {
navigateLeft({skipFragments});
}
} }
} }
@@ -2376,13 +2284,13 @@ export default function( revealElement, options ) {
/** /**
* The reverse of #navigatePrev(). * The reverse of #navigatePrev().
*/ */
function navigateNext({skipFragments=false}={}) { function navigateNext() {
navigationHistory.hasNavigatedHorizontally = true; navigationHistory.hasNavigatedHorizontally = true;
navigationHistory.hasNavigatedVertically = true; navigationHistory.hasNavigatedVertically = true;
// Prioritize revealing fragments // Prioritize revealing fragments
if( skipFragments || fragments.next() === false ) { if( fragments.next() === false ) {
let routes = availableRoutes(); let routes = availableRoutes();
@@ -2394,13 +2302,13 @@ export default function( revealElement, options ) {
} }
if( routes.down ) { if( routes.down ) {
navigateDown({skipFragments}); navigateDown();
} }
else if( config.rtl ) { else if( config.rtl ) {
navigateLeft({skipFragments}); navigateLeft();
} }
else { else {
navigateRight({skipFragments}); navigateRight();
} }
} }
@@ -2425,38 +2333,6 @@ export default function( revealElement, options ) {
} }
/**
* Listener for post message events posted to this window.
*/
function onPostMessage( event ) {
let data = event.data;
// Make sure we're dealing with JSON
if( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {
data = JSON.parse( data );
// Check if the requested method can be found
if( data.method && typeof Reveal[data.method] === 'function' ) {
if( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {
const result = Reveal[data.method].apply( Reveal, data.args );
// Dispatch a postMessage event with the returned value from
// our method invocation for getter functions
dispatchPostMessage( 'callback', { method: data.method, result: result } );
}
else {
console.warn( 'reveal.js: "'+ data.method +'" is is blacklisted from the postMessage API' );
}
}
}
}
/** /**
* Event listener for transition end on the current slide. * Event listener for transition end on the current slide.
* *
@@ -2474,33 +2350,6 @@ export default function( revealElement, options ) {
} }
/**
* A global listener for all click events inside of the
* .slides container.
*
* @param {object} [event]
*/
function onSlidesClicked( event ) {
const anchor = Util.closest( event.target, 'a[href^="#"]' );
// If a hash link is clicked, we find the target slide
// and navigate to it. We previously relied on 'hashchange'
// for links like these but that prevented media with
// audio tracks from playing in mobile browsers since it
// wasn't considered a direct interaction with the document.
if( anchor ) {
const hash = anchor.getAttribute( 'href' );
const indices = location.getIndicesFromHash( hash );
if( indices ) {
Reveal.slide( indices.h, indices.v, indices.f );
event.preventDefault();
}
}
}
/** /**
* Handler for the window level 'resize' event. * Handler for the window level 'resize' event.
* *
@@ -2531,26 +2380,6 @@ export default function( revealElement, options ) {
} }
/**
* Handler for the document level 'fullscreenchange' event.
*
* @param {object} [event]
*/
function onFullscreenChange( event ) {
let element = document.fullscreenElement || document.webkitFullscreenElement;
if( element === dom.wrapper ) {
event.stopImmediatePropagation();
// Timeout to avoid layout shift in Safari
setTimeout( () => {
Reveal.layout();
Reveal.focus.focus(); // focus.focus :'(
}, 1 );
}
}
/** /**
* Handles clicks on links that are set to preview in the * Handles clicks on links that are set to preview in the
* iframe overlay. * iframe overlay.
@@ -2603,7 +2432,6 @@ export default function( revealElement, options ) {
initialize, initialize,
configure, configure,
destroy,
sync, sync,
syncSlide, syncSlide,
@@ -2760,9 +2588,6 @@ export default function( revealElement, options ) {
// Helper method, retrieves query string as a key:value map // Helper method, retrieves query string as a key:value map
getQueryHash: Util.getQueryHash, getQueryHash: Util.getQueryHash,
// Returns the path to the current slide as represented in the URL
getSlidePath: location.getHash.bind( location ),
// Returns reveal.js DOM elements // Returns reveal.js DOM elements
getRevealElement: () => revealElement, getRevealElement: () => revealElement,
getSlidesElement: () => dom.slides, getSlidesElement: () => dom.slides,

View File

@@ -29,9 +29,9 @@ export const colorToRgb = ( color ) => {
if( hex6 && hex6[1] ) { if( hex6 && hex6[1] ) {
hex6 = hex6[1]; hex6 = hex6[1];
return { return {
r: parseInt( hex6.slice( 0, 2 ), 16 ), r: parseInt( hex6.substr( 0, 2 ), 16 ),
g: parseInt( hex6.slice( 2, 4 ), 16 ), g: parseInt( hex6.substr( 2, 2 ), 16 ),
b: parseInt( hex6.slice( 4, 6 ), 16 ) b: parseInt( hex6.substr( 4, 2 ), 16 )
}; };
} }

View File

@@ -4,7 +4,7 @@ export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section'; export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
// Methods that may not be invoked via the postMessage API // Methods that may not be invoked via the postMessage API
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/; export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
// Regex for retrieving the fragment style from a class attribute // Regex for retrieving the fragment style from a class attribute
export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/; export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;

View File

@@ -1,4 +1,5 @@
const UA = navigator.userAgent; const UA = navigator.userAgent;
const testElement = document.createElement( 'div' );
export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) || export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS ( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
@@ -6,3 +7,9 @@ export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA ); export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
export const isAndroid = /android/gi.test( UA ); export const isAndroid = /android/gi.test( UA );
// Flags if we should use zoom instead of transform to scale
// up slides. Zoom produces crisper results but has a lot of
// xbrowser quirks so we only use it in whitelisted browsers.
export const supportsZoom = 'zoom' in testElement.style && !isMobile &&
( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) );

View File

@@ -280,18 +280,3 @@ export const getRemainingHeight = ( element, height = 0 ) => {
return height; return height;
} }
const fileExtensionToMimeMap = {
'mp4': 'video/mp4',
'm4a': 'video/mp4',
'ogv': 'video/ogg',
'mpeg': 'video/mpeg',
'webm': 'video/webm'
}
/**
* Guess the MIME type for common file formats.
*/
export const getMimeTypeFromFile = ( filename='' ) => {
return fileExtensionToMimeMap[filename.split('.').pop()]
}

538
package-lock.json generated
View File

@@ -1,12 +1,11 @@
{ {
"name": "reveal.js", "name": "reveal.js",
"version": "4.4.0", "version": "4.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "reveal.js", "version": "4.1.0",
"version": "4.4.0",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.3", "@babel/core": "^7.14.3",
@@ -21,7 +20,7 @@
"fitty": "^2.3.0", "fitty": "^2.3.0",
"glob": "^7.1.7", "glob": "^7.1.7",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-autoprefixer": "^8.0.0", "gulp-autoprefixer": "^5.0.0",
"gulp-clean-css": "^4.2.0", "gulp-clean-css": "^4.2.0",
"gulp-connect": "^5.7.0", "gulp-connect": "^5.7.0",
"gulp-eslint": "^6.0.0", "gulp-eslint": "^6.0.0",
@@ -29,12 +28,12 @@
"gulp-tap": "^2.0.0", "gulp-tap": "^2.0.0",
"gulp-zip": "^4.2.0", "gulp-zip": "^4.2.0",
"highlight.js": "^10.0.3", "highlight.js": "^10.0.3",
"marked": "^4.0.12", "marked": "^2.0.3",
"node-qunit-puppeteer": "^2.1.0", "node-qunit-puppeteer": "^2.0.1",
"qunit": "^2.17.2", "qunit": "^2.10.0",
"rollup": "^2.48.0", "rollup": "^2.48.0",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"sass": "^1.39.2", "sass": "^1.32.13",
"yargs": "^15.1.0" "yargs": "^15.1.0"
}, },
"engines": { "engines": {
@@ -1620,9 +1619,9 @@
} }
}, },
"node_modules/ansi-regex": { "node_modules/ansi-regex": {
"version": "5.0.1", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -1904,30 +1903,33 @@
} }
}, },
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "10.4.2", "version": "8.6.5",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz",
"integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==", "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"browserslist": "^4.19.1", "browserslist": "^3.2.8",
"caniuse-lite": "^1.0.30001297", "caniuse-lite": "^1.0.30000864",
"fraction.js": "^4.1.2",
"normalize-range": "^0.1.2", "normalize-range": "^0.1.2",
"picocolors": "^1.0.0", "num2fraction": "^1.2.2",
"postcss-value-parser": "^4.2.0" "postcss": "^6.0.23",
"postcss-value-parser": "^3.2.3"
}, },
"bin": { "bin": {
"autoprefixer": "bin/autoprefixer" "autoprefixer": "bin/autoprefixer"
}
}, },
"engines": { "node_modules/autoprefixer/node_modules/browserslist": {
"node": "^10 || ^12 || >=14" "version": "3.2.8",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
"integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
"dev": true,
"dependencies": {
"caniuse-lite": "^1.0.30000844",
"electron-to-chromium": "^1.3.47"
}, },
"funding": { "bin": {
"type": "opencollective", "browserslist": "cli.js"
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
"postcss": "^8.1.0"
} }
}, },
"node_modules/babel-plugin-dynamic-import-node": { "node_modules/babel-plugin-dynamic-import-node": {
@@ -2109,16 +2111,16 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.19.3", "version": "4.16.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
"integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001312", "caniuse-lite": "^1.0.30001219",
"electron-to-chromium": "^1.4.71", "colorette": "^1.2.2",
"electron-to-chromium": "^1.3.723",
"escalade": "^3.1.1", "escalade": "^3.1.1",
"node-releases": "^2.0.2", "node-releases": "^1.1.71"
"picocolors": "^1.0.0"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@@ -2225,20 +2227,14 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001374", "version": "1.0.30001228",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz",
"integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==", "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==",
"dev": true, "dev": true,
"funding": [ "funding": {
{
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/browserslist" "url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
} }
]
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "2.4.2", "version": "2.4.2",
@@ -2542,6 +2538,12 @@
"color-support": "bin.js" "color-support": "bin.js"
} }
}, },
"node_modules/colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
"dev": true
},
"node_modules/colors": { "node_modules/colors": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
@@ -2552,9 +2554,9 @@
} }
}, },
"node_modules/commander": { "node_modules/commander": {
"version": "7.2.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">= 10" "node": ">= 10"
@@ -2922,9 +2924,9 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.73", "version": "1.3.732",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.73.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz",
"integrity": "sha512-RlCffXkE/LliqfA5m29+dVDPB2r72y2D2egMMfIy3Le8ODrxjuZNVo4NIC2yPL01N4xb4nZQLwzi6Z5tGIGLnA==", "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==",
"dev": true "dev": true
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
@@ -3884,19 +3886,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/fraction.js": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz",
"integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==",
"dev": true,
"engines": {
"node": "*"
},
"funding": {
"type": "patreon",
"url": "https://www.patreon.com/infusion"
}
},
"node_modules/fragment-cache": { "node_modules/fragment-cache": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -4211,52 +4200,20 @@
} }
}, },
"node_modules/gulp-autoprefixer": { "node_modules/gulp-autoprefixer": {
"version": "8.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz",
"integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"autoprefixer": "^10.2.6", "autoprefixer": "^8.0.0",
"fancy-log": "^1.3.3", "fancy-log": "^1.3.2",
"plugin-error": "^1.0.1", "plugin-error": "^1.0.1",
"postcss": "^8.3.0", "postcss": "^6.0.1",
"through2": "^4.0.2", "through2": "^2.0.0",
"vinyl-sourcemaps-apply": "^0.2.1" "vinyl-sourcemaps-apply": "^0.2.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=4.5"
},
"peerDependencies": {
"gulp": ">=4"
},
"peerDependenciesMeta": {
"gulp": {
"optional": true
}
}
},
"node_modules/gulp-autoprefixer/node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/gulp-autoprefixer/node_modules/through2": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
"dev": true,
"dependencies": {
"readable-stream": "3"
} }
}, },
"node_modules/gulp-clean-css": { "node_modules/gulp-clean-css": {
@@ -5622,6 +5579,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/js-reporters": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-2.0.0.tgz",
"integrity": "sha512-VJd/86niT7GzsaVc+Yxrs8QPrYl1orzv8bYZPuSOtxU6rk/pv8aOXTcIa7HaANvtvdLMTsZspAiucNQ6T2QFHw==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -5945,15 +5911,15 @@
} }
}, },
"node_modules/marked": { "node_modules/marked": {
"version": "4.0.12", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
"integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==",
"dev": true, "dev": true,
"bin": { "bin": {
"marked": "bin/marked.js" "marked": "bin/marked"
}, },
"engines": { "engines": {
"node": ">= 12" "node": ">= 8.16.2"
} }
}, },
"node_modules/matchdep": { "node_modules/matchdep": {
@@ -6211,18 +6177,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"node_modules/nanoid": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/nanomatch": { "node_modules/nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -6319,9 +6273,9 @@
"dev": true "dev": true
}, },
"node_modules/node-qunit-puppeteer": { "node_modules/node-qunit-puppeteer": {
"version": "2.1.0", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/node-qunit-puppeteer/-/node-qunit-puppeteer-2.1.0.tgz", "resolved": "https://registry.npmjs.org/node-qunit-puppeteer/-/node-qunit-puppeteer-2.0.3.tgz",
"integrity": "sha512-53ytjfu+t51r9qbOsek5D9biAlGO808Pp6b1gGdg/fcGJGFZIJNHoVpFF3OLRe7IUXA9QjhsQL9IkK4NGenHCA==", "integrity": "sha512-G4mWn3RBQ+JPzCNWzFQ4r6RUUZqj52D5E3Z7wxqRi5b4daph0Alk/mgBpAQqZq7TVR1oV2emnN0Bk0EgYz/4gw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"colors": "^1.4.0", "colors": "^1.4.0",
@@ -6332,15 +6286,15 @@
} }
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.2", "version": "1.1.72",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
"integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
"dev": true "dev": true
}, },
"node_modules/node-watch": { "node_modules/node-watch": {
"version": "0.7.2", "version": "0.7.1",
"resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.2.tgz", "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.1.tgz",
"integrity": "sha512-g53VjSARRv1JdST0LZRIg8RiuLr1TaBbVPsVvxh0/0Ymvi0xYUjDuoqQQAWtHJQUXhiShowPT/aXKNeHBcyQsw==", "integrity": "sha512-UWblPYuZYrkCQCW5PxAwYSxaELNBLUckrTBBk8xr1/bUgyOkYYTsUcV4e3ytcazFEOyiRyiUrsG37pu6I0I05g==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@@ -6397,6 +6351,12 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
"integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
"dev": true
},
"node_modules/number-is-nan": { "node_modules/number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
@@ -6830,9 +6790,9 @@
} }
}, },
"node_modules/path-parse": { "node_modules/path-parse": {
"version": "1.0.7", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true "dev": true
}, },
"node_modules/path-root": { "node_modules/path-root": {
@@ -6876,12 +6836,6 @@
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true "dev": true
}, },
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/picomatch": { "node_modules/picomatch": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
@@ -6998,29 +6952,34 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.7", "version": "6.0.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
"integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==", "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"nanoid": "^3.3.1", "chalk": "^2.4.1",
"picocolors": "^1.0.0", "source-map": "^0.6.1",
"source-map-js": "^1.0.2" "supports-color": "^5.4.0"
}, },
"engines": { "engines": {
"node": "^10 || ^12 || >=14" "node": ">=4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
} }
}, },
"node_modules/postcss-value-parser": { "node_modules/postcss-value-parser": {
"version": "4.2.0", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
"dev": true "dev": true
}, },
"node_modules/postcss/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prelude-ls": { "node_modules/prelude-ls": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7141,14 +7100,15 @@
} }
}, },
"node_modules/qunit": { "node_modules/qunit": {
"version": "2.17.2", "version": "2.15.0",
"resolved": "https://registry.npmjs.org/qunit/-/qunit-2.17.2.tgz", "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.15.0.tgz",
"integrity": "sha512-17isVvuOmALzsPjiV7wFg/6O5vJYXBrQZPwocfQSSh0I/rXvfX7bKMFJ4GMVW3U4P8r2mBeUy8EAngti4QD2Vw==", "integrity": "sha512-9ZoOILeyRZzrdvy2m7M4S76bneGD75Bh4B2aot3uKRKZuoEvA9gevvzU339L805Ys0AN2C7cnAV9nIBD5t72IQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"commander": "7.2.0", "commander": "7.1.0",
"node-watch": "0.7.2", "js-reporters": "2.0.0",
"tiny-glob": "0.2.9" "node-watch": "0.7.1",
"tiny-glob": "0.2.8"
}, },
"bin": { "bin": {
"qunit": "bin/qunit.js" "qunit": "bin/qunit.js"
@@ -7711,9 +7671,9 @@
"dev": true "dev": true
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.42.1", "version": "1.32.13",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.42.1.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.13.tgz",
"integrity": "sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg==", "integrity": "sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"chokidar": ">=3.0.0 <4.0.0" "chokidar": ">=3.0.0 <4.0.0"
@@ -8368,15 +8328,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-resolve": { "node_modules/source-map-resolve": {
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@@ -8837,9 +8788,9 @@
} }
}, },
"node_modules/tiny-glob": { "node_modules/tiny-glob": {
"version": "0.2.9", "version": "0.2.8",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz",
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", "integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"globalyzer": "0.1.0", "globalyzer": "0.1.0",
@@ -9511,9 +9462,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "6.2.2", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"
@@ -10873,9 +10824,9 @@
} }
}, },
"ansi-regex": { "ansi-regex": {
"version": "5.0.1", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true "dev": true
}, },
"ansi-styles": { "ansi-styles": {
@@ -11091,17 +11042,29 @@
"dev": true "dev": true
}, },
"autoprefixer": { "autoprefixer": {
"version": "10.4.2", "version": "8.6.5",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz",
"integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==", "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.19.1", "browserslist": "^3.2.8",
"caniuse-lite": "^1.0.30001297", "caniuse-lite": "^1.0.30000864",
"fraction.js": "^4.1.2",
"normalize-range": "^0.1.2", "normalize-range": "^0.1.2",
"picocolors": "^1.0.0", "num2fraction": "^1.2.2",
"postcss-value-parser": "^4.2.0" "postcss": "^6.0.23",
"postcss-value-parser": "^3.2.3"
},
"dependencies": {
"browserslist": {
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
"integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30000844",
"electron-to-chromium": "^1.3.47"
}
}
} }
}, },
"babel-plugin-dynamic-import-node": { "babel-plugin-dynamic-import-node": {
@@ -11261,16 +11224,16 @@
} }
}, },
"browserslist": { "browserslist": {
"version": "4.19.3", "version": "4.16.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
"integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"caniuse-lite": "^1.0.30001312", "caniuse-lite": "^1.0.30001219",
"electron-to-chromium": "^1.4.71", "colorette": "^1.2.2",
"electron-to-chromium": "^1.3.723",
"escalade": "^3.1.1", "escalade": "^3.1.1",
"node-releases": "^2.0.2", "node-releases": "^1.1.71"
"picocolors": "^1.0.0"
} }
}, },
"buffer-crc32": { "buffer-crc32": {
@@ -11343,9 +11306,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001374", "version": "1.0.30001228",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz",
"integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==", "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==",
"dev": true "dev": true
}, },
"chalk": { "chalk": {
@@ -11602,6 +11565,12 @@
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true "dev": true
}, },
"colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
"dev": true
},
"colors": { "colors": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
@@ -11609,9 +11578,9 @@
"dev": true "dev": true
}, },
"commander": { "commander": {
"version": "7.2.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==",
"dev": true "dev": true
}, },
"commondir": { "commondir": {
@@ -11913,9 +11882,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.4.73", "version": "1.3.732",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.73.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz",
"integrity": "sha512-RlCffXkE/LliqfA5m29+dVDPB2r72y2D2egMMfIy3Le8ODrxjuZNVo4NIC2yPL01N4xb4nZQLwzi6Z5tGIGLnA==", "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==",
"dev": true "dev": true
}, },
"emoji-regex": { "emoji-regex": {
@@ -12708,12 +12677,6 @@
"for-in": "^1.0.1" "for-in": "^1.0.1"
} }
}, },
"fraction.js": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz",
"integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==",
"dev": true
},
"fragment-cache": { "fragment-cache": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -12961,39 +12924,17 @@
} }
}, },
"gulp-autoprefixer": { "gulp-autoprefixer": {
"version": "8.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz",
"integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=",
"dev": true, "dev": true,
"requires": { "requires": {
"autoprefixer": "^10.2.6", "autoprefixer": "^8.0.0",
"fancy-log": "^1.3.3", "fancy-log": "^1.3.2",
"plugin-error": "^1.0.1", "plugin-error": "^1.0.1",
"postcss": "^8.3.0", "postcss": "^6.0.1",
"through2": "^4.0.2", "through2": "^2.0.0",
"vinyl-sourcemaps-apply": "^0.2.1" "vinyl-sourcemaps-apply": "^0.2.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"through2": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
"dev": true,
"requires": {
"readable-stream": "3"
}
}
} }
}, },
"gulp-clean-css": { "gulp-clean-css": {
@@ -14092,6 +14033,12 @@
} }
} }
}, },
"js-reporters": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-2.0.0.tgz",
"integrity": "sha512-VJd/86niT7GzsaVc+Yxrs8QPrYl1orzv8bYZPuSOtxU6rk/pv8aOXTcIa7HaANvtvdLMTsZspAiucNQ6T2QFHw==",
"dev": true
},
"js-tokens": { "js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -14359,9 +14306,9 @@
} }
}, },
"marked": { "marked": {
"version": "4.0.12", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
"integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==",
"dev": true "dev": true
}, },
"matchdep": { "matchdep": {
@@ -14568,12 +14515,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"nanoid": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
"dev": true
},
"nanomatch": { "nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -14654,9 +14595,9 @@
"dev": true "dev": true
}, },
"node-qunit-puppeteer": { "node-qunit-puppeteer": {
"version": "2.1.0", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/node-qunit-puppeteer/-/node-qunit-puppeteer-2.1.0.tgz", "resolved": "https://registry.npmjs.org/node-qunit-puppeteer/-/node-qunit-puppeteer-2.0.3.tgz",
"integrity": "sha512-53ytjfu+t51r9qbOsek5D9biAlGO808Pp6b1gGdg/fcGJGFZIJNHoVpFF3OLRe7IUXA9QjhsQL9IkK4NGenHCA==", "integrity": "sha512-G4mWn3RBQ+JPzCNWzFQ4r6RUUZqj52D5E3Z7wxqRi5b4daph0Alk/mgBpAQqZq7TVR1oV2emnN0Bk0EgYz/4gw==",
"dev": true, "dev": true,
"requires": { "requires": {
"colors": "^1.4.0", "colors": "^1.4.0",
@@ -14664,15 +14605,15 @@
} }
}, },
"node-releases": { "node-releases": {
"version": "2.0.2", "version": "1.1.72",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
"integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
"dev": true "dev": true
}, },
"node-watch": { "node-watch": {
"version": "0.7.2", "version": "0.7.1",
"resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.2.tgz", "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.1.tgz",
"integrity": "sha512-g53VjSARRv1JdST0LZRIg8RiuLr1TaBbVPsVvxh0/0Ymvi0xYUjDuoqQQAWtHJQUXhiShowPT/aXKNeHBcyQsw==", "integrity": "sha512-UWblPYuZYrkCQCW5PxAwYSxaELNBLUckrTBBk8xr1/bUgyOkYYTsUcV4e3ytcazFEOyiRyiUrsG37pu6I0I05g==",
"dev": true "dev": true
}, },
"normalize-package-data": { "normalize-package-data": {
@@ -14716,6 +14657,12 @@
"once": "^1.3.2" "once": "^1.3.2"
} }
}, },
"num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
"integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
"dev": true
},
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
@@ -15039,9 +14986,9 @@
"peer": true "peer": true
}, },
"path-parse": { "path-parse": {
"version": "1.0.7", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true "dev": true
}, },
"path-root": { "path-root": {
@@ -15076,12 +15023,6 @@
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true "dev": true
}, },
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"picomatch": { "picomatch": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
@@ -15167,20 +15108,28 @@
"dev": true "dev": true
}, },
"postcss": { "postcss": {
"version": "8.4.7", "version": "6.0.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
"integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==", "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
"dev": true, "dev": true,
"requires": { "requires": {
"nanoid": "^3.3.1", "chalk": "^2.4.1",
"picocolors": "^1.0.0", "source-map": "^0.6.1",
"source-map-js": "^1.0.2" "supports-color": "^5.4.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
} }
}, },
"postcss-value-parser": { "postcss-value-parser": {
"version": "4.2.0", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
"dev": true "dev": true
}, },
"prelude-ls": { "prelude-ls": {
@@ -15280,14 +15229,15 @@
} }
}, },
"qunit": { "qunit": {
"version": "2.17.2", "version": "2.15.0",
"resolved": "https://registry.npmjs.org/qunit/-/qunit-2.17.2.tgz", "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.15.0.tgz",
"integrity": "sha512-17isVvuOmALzsPjiV7wFg/6O5vJYXBrQZPwocfQSSh0I/rXvfX7bKMFJ4GMVW3U4P8r2mBeUy8EAngti4QD2Vw==", "integrity": "sha512-9ZoOILeyRZzrdvy2m7M4S76bneGD75Bh4B2aot3uKRKZuoEvA9gevvzU339L805Ys0AN2C7cnAV9nIBD5t72IQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"commander": "7.2.0", "commander": "7.1.0",
"node-watch": "0.7.2", "js-reporters": "2.0.0",
"tiny-glob": "0.2.9" "node-watch": "0.7.1",
"tiny-glob": "0.2.8"
} }
}, },
"randombytes": { "randombytes": {
@@ -15729,9 +15679,9 @@
"dev": true "dev": true
}, },
"sass": { "sass": {
"version": "1.42.1", "version": "1.32.13",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.42.1.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.13.tgz",
"integrity": "sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg==", "integrity": "sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==",
"dev": true, "dev": true,
"requires": { "requires": {
"chokidar": ">=3.0.0 <4.0.0" "chokidar": ">=3.0.0 <4.0.0"
@@ -16269,12 +16219,6 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true "dev": true
}, },
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true
},
"source-map-resolve": { "source-map-resolve": {
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@@ -16667,9 +16611,9 @@
"dev": true "dev": true
}, },
"tiny-glob": { "tiny-glob": {
"version": "0.2.9", "version": "0.2.8",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz",
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", "integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==",
"dev": true, "dev": true,
"requires": { "requires": {
"globalyzer": "0.1.0", "globalyzer": "0.1.0",
@@ -17217,9 +17161,9 @@
} }
}, },
"ws": { "ws": {
"version": "6.2.2", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"dev": true, "dev": true,
"requires": { "requires": {
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"

View File

@@ -1,6 +1,6 @@
{ {
"name": "reveal.js", "name": "reveal.js",
"version": "4.4.0", "version": "4.1.3",
"description": "The HTML Presentation Framework", "description": "The HTML Presentation Framework",
"homepage": "https://revealjs.com", "homepage": "https://revealjs.com",
"subdomain": "revealjs", "subdomain": "revealjs",
@@ -42,7 +42,7 @@
"fitty": "^2.3.0", "fitty": "^2.3.0",
"glob": "^7.1.7", "glob": "^7.1.7",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-autoprefixer": "^8.0.0", "gulp-autoprefixer": "^5.0.0",
"gulp-clean-css": "^4.2.0", "gulp-clean-css": "^4.2.0",
"gulp-connect": "^5.7.0", "gulp-connect": "^5.7.0",
"gulp-eslint": "^6.0.0", "gulp-eslint": "^6.0.0",
@@ -50,15 +50,15 @@
"gulp-tap": "^2.0.0", "gulp-tap": "^2.0.0",
"gulp-zip": "^4.2.0", "gulp-zip": "^4.2.0",
"highlight.js": "^10.0.3", "highlight.js": "^10.0.3",
"marked": "^4.0.12", "marked": "^2.0.3",
"node-qunit-puppeteer": "^2.1.0", "node-qunit-puppeteer": "^2.0.1",
"qunit": "^2.17.2", "qunit": "^2.10.0",
"rollup": "^2.48.0", "rollup": "^2.48.0",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"sass": "^1.39.2", "sass": "^1.32.13",
"yargs": "^15.1.0" "yargs": "^15.1.0"
}, },
"browserslist": "> 2%, not dead", "browserslist": "> 0.5%, IE 11, not dead",
"eslintConfig": { "eslintConfig": {
"env": { "env": {
"browser": true, "browser": true,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,8 @@
import hljs from 'highlight.js'; import hljs from 'highlight.js'
/* highlightjs-line-numbers.js 2.8.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
!function(r,o){"use strict";var e,i="hljs-ln",l="hljs-ln-line",h="hljs-ln-code",s="hljs-ln-numbers",c="hljs-ln-n",m="data-line-number",a=/\r\n|\r|\n/g;function u(e){for(var n=e.toString(),t=e.anchorNode;"TD"!==t.nodeName;)t=t.parentNode;for(var r=e.focusNode;"TD"!==r.nodeName;)r=r.parentNode;var o=parseInt(t.dataset.lineNumber),a=parseInt(r.dataset.lineNumber);if(o==a)return n;var i,l=t.textContent,s=r.textContent;for(a<o&&(i=o,o=a,a=i,i=l,l=s,s=i);0!==n.indexOf(l);)l=l.slice(1);for(;-1===n.lastIndexOf(s);)s=s.slice(0,-1);for(var c=l,u=function(e){for(var n=e;"TABLE"!==n.nodeName;)n=n.parentNode;return n}(t),d=o+1;d<a;++d){var f=p('.{0}[{1}="{2}"]',[h,m,d]);c+="\n"+u.querySelector(f).textContent}return c+="\n"+s}function n(e){try{var n=o.querySelectorAll("code.hljs,code.nohighlight");for(var t in n)n.hasOwnProperty(t)&&(n[t].classList.contains("nohljsln")||d(n[t],e))}catch(e){r.console.error("LineNumbers error: ",e)}}function d(e,n){if("object"==typeof e)e.innerHTML=f(e,n)}function f(e,n){var t,r,o=(t=e,{singleLine:function(e){return!!e.singleLine&&e.singleLine}(r=(r=n)||{}),startFrom:function(e,n){var t=1;isFinite(n.startFrom)&&(t=n.startFrom);var r=function(e,n){return e.hasAttribute(n)?e.getAttribute(n):null}(e,"data-ln-start-from");return null!==r&&(t=function(e,n){if(!e)return n;var t=Number(e);return isFinite(t)?t:n}(r,1)),t}(t,r)});return function e(n){var t=n.childNodes;for(var r in t){var o;t.hasOwnProperty(r)&&(o=t[r],0<(o.textContent.trim().match(a)||[]).length&&(0<o.childNodes.length?e(o):v(o.parentNode)))}}(e),function(e,n){var t=g(e);""===t[t.length-1].trim()&&t.pop();if(1<t.length||n.singleLine){for(var r="",o=0,a=t.length;o<a;o++)r+=p('<tr><td class="{0} {1}" {3}="{5}"><div class="{2}" {3}="{5}"></div></td><td class="{0} {4}" {3}="{5}">{6}</td></tr>',[l,s,c,m,h,o+n.startFrom,0<t[o].length?t[o]:" "]);return p('<table class="{0}">{1}</table>',[i,r])}return e}(e.innerHTML,o)}function v(e){var n=e.className;if(/hljs-/.test(n)){for(var t=g(e.innerHTML),r=0,o="";r<t.length;r++){o+=p('<span class="{0}">{1}</span>\n',[n,0<t[r].length?t[r]:" "])}e.innerHTML=o.trim()}}function g(e){return 0===e.length?[]:e.split(a)}function p(e,t){return e.replace(/\{(\d+)\}/g,function(e,n){return void 0!==t[n]?t[n]:e})}hljs?(hljs.initLineNumbersOnLoad=function(e){"interactive"===o.readyState||"complete"===o.readyState?n(e):r.addEventListener("DOMContentLoaded",function(){n(e)})},hljs.lineNumbersBlock=d,hljs.lineNumbersValue=function(e,n){if("string"!=typeof e)return;var t=document.createElement("code");return t.innerHTML=e,f(t,n)},(e=o.createElement("style")).type="text/css",e.innerHTML=p(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[i,c,m]),o.getElementsByTagName("head")[0].appendChild(e)):r.console.error("highlight.js not detected!"),document.addEventListener("copy",function(e){var n,t=window.getSelection();!function(e){for(var n=e;n;){if(n.className&&-1!==n.className.indexOf("hljs-ln-code"))return 1;n=n.parentNode}}(t.anchorNode)||(n=-1!==window.navigator.userAgent.indexOf("Edge")?u(t):t.toString(),e.clipboardData.setData("text/plain",n),e.preventDefault())})}(window,document);
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
/* Edited by Hakim for reveal.js; removed async timeout */
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=g(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[v,L,b]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"interactive"===e.readyState||"complete"===e.readyState?i(t):n.addEventListener("DOMContentLoaded",function(){i(t)})}function i(t){try{var r=e.querySelectorAll("code.hljs,code.nohighlight");for(var i in r)r.hasOwnProperty(i)&&l(r[i],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function l(n,e){"object"==typeof n&&f(function(){n.innerHTML=s(n,e)})}function o(n,e){if("string"==typeof n){var t=document.createElement("code");return t.innerHTML=n,s(t,e)}}function s(n,e){e=e||{singleLine:!1};var t=e.singleLine?0:1;return c(n),a(n.innerHTML,t)}function a(n,e){var t=u(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",i=0,l=t.length;i<l;i++)r+=g('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[j,m,L,b,p,i+1,t[i].length>0?t[i]:" "]);return g('<table class="{0}">{1}</table>',[v,r])}return n}function c(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];h(r.textContent)>0&&(r.childNodes.length>0?c(r):d(r.parentNode))}}function d(n){var e=n.className;if(/hljs-/.test(e)){for(var t=u(n.innerHTML),r=0,i="";r<t.length;r++){var l=t[r].length>0?t[r]:" ";i+=g('<span class="{0}">{1}</span>\n',[e,l])}n.innerHTML=i.trim()}}function u(n){return 0===n.length?[]:n.split(y)}function h(n){return(n.trim().match(y)||[]).length}function f(e){e()}function g(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var v="hljs-ln",m="hljs-ln-line",p="hljs-ln-code",j="hljs-ln-numbers",L="hljs-ln-n",b="data-line-number",y=/\r\n|\r|\n/g;hljs?(hljs.initLineNumbersOnLoad=r,hljs.lineNumbersBlock=l,hljs.lineNumbersValue=o,t()):n.console.error("highlight.js not detected!")}(window,document);
/*! /*!
* reveal.js plugin that adds syntax highlight support. * reveal.js plugin that adds syntax highlight support.
@@ -16,10 +16,10 @@ const Plugin = {
HIGHLIGHT_LINE_DELIMITER: ',', HIGHLIGHT_LINE_DELIMITER: ',',
HIGHLIGHT_LINE_RANGE_DELIMITER: '-', HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
hljs, hljs: hljs,
/** /**
* Highlights code blocks within the given deck. * Highlights code blocks withing the given deck.
* *
* Note that this can be called multiple times if * Note that this can be called multiple times if
* there are multiple presentations on one page. * there are multiple presentations on one page.
@@ -30,7 +30,6 @@ const Plugin = {
// Read the plugin config options and provide fallbacks // Read the plugin config options and provide fallbacks
let config = reveal.getConfig().highlight || {}; let config = reveal.getConfig().highlight || {};
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true; config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true; config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
@@ -62,20 +61,12 @@ const Plugin = {
hljs.highlightElement( event.currentTarget ); hljs.highlightElement( event.currentTarget );
}, false ); }, false );
} );
// Triggers a callback function before we trigger highlighting
if( typeof config.beforeHighlight === 'function' ) {
config.beforeHighlight( hljs );
}
// Run initial highlighting for all code
if( config.highlightOnLoad ) { if( config.highlightOnLoad ) {
Array.from( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( block => {
Plugin.highlightBlock( block ); Plugin.highlightBlock( block );
} );
} }
} );
// If we're printing to PDF, scroll the code highlights of // If we're printing to PDF, scroll the code highlights of
// all blocks in the deck into view at once // all blocks in the deck into view at once
reveal.on( 'pdf-ready', function() { reveal.on( 'pdf-ready', function() {
@@ -106,7 +97,7 @@ const Plugin = {
var scrollState = { currentBlock: block }; var scrollState = { currentBlock: block };
// If there is more than one highlight step, generate // If there is at least one highlight step, generate
// fragments // fragments
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) ); var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
if( highlightSteps.length > 1 ) { if( highlightSteps.length > 1 ) {
@@ -142,7 +133,7 @@ const Plugin = {
} ); } );
block.removeAttribute( 'data-fragment-index' ); block.removeAttribute( 'data-fragment-index' )
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) ); block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
* of external markdown documents. * of external markdown documents.
*/ */
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?:',

View File

@@ -1,96 +0,0 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for KaTeX.
*
* @author Hakim El Hattab
* @author Gerhard Burger
*/
export const KaTeX = () => {
let deck;
let defaultOptions = {
version: 'latest',
delimiters: [
{left: '$$', right: '$$', display: true}, // Note: $$ has to come before $
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre']
}
const loadCss = src => {
let link = document.createElement('link');
link.rel = 'stylesheet';
link.href = src;
document.head.appendChild(link);
};
/**
* Loads a JavaScript file and returns a Promise for when it is loaded
* Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/
*/
const loadScript = src => {
return new Promise((resolve, reject) => {
const script = document.createElement('script')
script.type = 'text/javascript'
script.onload = resolve
script.onerror = reject
script.src = src
document.head.append(script)
})
};
async function loadScripts(urls) {
for(const url of urls) {
await loadScript(url);
}
}
return {
id: 'katex',
init: function (reveal) {
deck = reveal;
let revealOptions = deck.getConfig().katex || {};
let options = {...defaultOptions, ...revealOptions};
const {local, version, extensions, ...katexOptions} = options;
let baseUrl = options.local || 'https://cdn.jsdelivr.net/npm/katex';
let versionString = options.local ? '' : '@' + options.version;
let cssUrl = baseUrl + versionString + '/dist/katex.min.css';
let katexUrl = baseUrl + versionString + '/dist/katex.min.js';
let mhchemUrl = baseUrl + versionString + '/dist/contrib/mhchem.min.js'
let karUrl = baseUrl + versionString + '/dist/contrib/auto-render.min.js';
let katexScripts = [katexUrl];
if(options.extensions && options.extensions.includes("mhchem")) {
katexScripts.push(mhchemUrl);
}
katexScripts.push(karUrl);
const renderMath = () => {
renderMathInElement(reveal.getSlidesElement(), katexOptions);
deck.layout();
}
loadCss(cssUrl);
// For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does
loadScripts(katexScripts).then(() => {
if( deck.isReady() ) {
renderMath();
}
else {
deck.on( 'ready', renderMath.bind( this ) );
}
});
}
}
};

View File

@@ -1,6 +1 @@
const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(a){t=a;let n=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...n},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...n.tex2jax},i.mathjax=i.config=null,function(t,e){let a=document.querySelector("head"),n=document.createElement("script");n.type="text/javascript",n.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};n.onload=i,n.onreadystatechange=()=>{"loaded"===this.readyState&&i()},a.appendChild(n)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t; function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?e(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):e(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}export default function(){var e,n={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=t(t({},n),a),c=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=t(t({},n.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(c,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}
/*!
* This plugin is a wrapper for the MathJax2,
* MathJax3 and KaTeX typesetter plugins.
*/
var a=Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const a=t=>new Promise(((e,a)=>{const n=document.createElement("script");n.type="text/javascript",n.onload=e,n.onerror=a,n.src=t,document.head.append(n)}));return{id:"katex",init:function(n){t=n;let i=t.getConfig().katex||{},s={...e,...i};const{local:l,version:o,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",p=s.local?"":"@"+s.version,u=d+p+"/dist/katex.min.css",h=d+p+"/dist/contrib/mhchem.min.js",x=d+p+"/dist/contrib/auto-render.min.js",m=[d+p+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(n.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(u),async function(t){for(const e of t)await a(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(a){t=a;let n=t.getConfig().mathjax3||{},i={...e,...n};i.tex={...e.tex,...n.tex},i.options={...e.options,...n.options},i.startup={...e.startup,...n.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let a=document.createElement("script");a.type="text/javascript",a.id="MathJax-script",a.src=t,a.async=!0,a.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(a)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export default a;

View File

@@ -1 +1 @@
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).RevealMath=e()}(this,(function(){"use strict";const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(n){t=n;let a=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...a},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...a.tex2jax},i.mathjax=i.config=null,function(t,e){let n=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};a.onload=i,a.onreadystatechange=()=>{"loaded"===this.readyState&&i()},n.appendChild(a)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t;return Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const n=t=>new Promise(((e,n)=>{const a=document.createElement("script");a.type="text/javascript",a.onload=e,a.onerror=n,a.src=t,document.head.append(a)}));return{id:"katex",init:function(a){t=a;let i=t.getConfig().katex||{},s={...e,...i};const{local:o,version:l,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",u=s.local?"":"@"+s.version,p=d+u+"/dist/katex.min.css",h=d+u+"/dist/contrib/mhchem.min.js",x=d+u+"/dist/contrib/auto-render.min.js",m=[d+u+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(a.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(p),async function(t){for(const e of t)await n(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(n){t=n;let a=t.getConfig().mathjax3||{},i={...e,...a};i.tex={...e.tex,...a.tex},i.options={...e.options,...a.options},i.startup={...e.startup,...a.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let n=document.createElement("script");n.type="text/javascript",n.id="MathJax-script",n.src=t,n.async=!0,n.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(n)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}})})); !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealMath=t()}(this,(function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?e(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):e(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}return function(){var e,n={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=t(t({},n),a),i=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=t(t({},n.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(i,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}}));

View File

@@ -1,89 +0,0 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for MathJax.
*
* @author Hakim El Hattab
*/
export const MathJax2 = () => {
// The reveal.js instance this plugin is attached to
let deck;
let defaultOptions = {
messageStyle: 'none',
tex2jax: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
skipStartupTypeset: true
};
function loadScript( url, callback ) {
let head = document.querySelector( 'head' );
let script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
// Wrapper for callback to make sure it only fires once
let finish = () => {
if( typeof callback === 'function' ) {
callback.call();
callback = null;
}
}
script.onload = finish;
// IE
script.onreadystatechange = () => {
if ( this.readyState === 'loaded' ) {
finish();
}
}
// Normal browsers
head.appendChild( script );
}
return {
id: 'mathjax2',
init: function( reveal ) {
deck = reveal;
let revealOptions = deck.getConfig().mathjax2 || deck.getConfig().math || {};
let options = { ...defaultOptions, ...revealOptions };
let mathjax = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js';
let config = options.config || 'TeX-AMS_HTML-full';
let url = mathjax + '?config=' + config;
options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
options.mathjax = options.config = null;
loadScript( url, function() {
MathJax.Hub.Config( options );
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
MathJax.Hub.Queue( deck.layout );
// Reprocess equations in slides when they turn visible
deck.on( 'slidechanged', function( event ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
} );
} );
}
}
};

View File

@@ -1,77 +0,0 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for MathJax 3
*
* @author Hakim El Hattab
* @author Gerhard Burger
*/
export const MathJax3 = () => {
// The reveal.js instance this plugin is attached to
let deck;
let defaultOptions = {
tex: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ]
},
options: {
skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
startup: {
ready: () => {
MathJax.startup.defaultReady();
MathJax.startup.promise.then(() => {
Reveal.layout();
});
}
}
};
function loadScript( url, callback ) {
let script = document.createElement( 'script' );
script.type = "text/javascript"
script.id = "MathJax-script"
script.src = url;
script.async = true
// Wrapper for callback to make sure it only fires once
script.onload = () => {
if (typeof callback === 'function') {
callback.call();
callback = null;
}
};
document.head.appendChild( script );
}
return {
id: 'mathjax3',
init: function(reveal) {
deck = reveal;
let revealOptions = deck.getConfig().mathjax3 || {};
let options = {...defaultOptions, ...revealOptions};
options.tex = {...defaultOptions.tex, ...revealOptions.tex}
options.options = {...defaultOptions.options, ...revealOptions.options}
options.startup = {...defaultOptions.startup, ...revealOptions.startup}
let url = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
options.mathjax = null;
window.MathJax = options;
loadScript( url, function() {
// Reprocess equations in slides when they turn visible
Reveal.addEventListener( 'slidechanged', function( event ) {
MathJax.typeset();
} );
} );
}
}
};

104
plugin/math/plugin.js Normal file → Executable file
View File

@@ -1,15 +1,91 @@
import {KaTeX} from "./katex"; /**
import {MathJax2} from "./mathjax2"; * A plugin which enables rendering of math equations inside
import {MathJax3} from "./mathjax3"; * of reveal.js slides. Essentially a thin wrapper for MathJax.
*
const defaultTypesetter = MathJax2; * @author Hakim El Hattab
/*!
* This plugin is a wrapper for the MathJax2,
* MathJax3 and KaTeX typesetter plugins.
*/ */
export default Plugin = Object.assign( defaultTypesetter(), { const Plugin = () => {
KaTeX,
MathJax2, // The reveal.js instance this plugin is attached to
MathJax3 let deck;
} );
let defaultOptions = {
messageStyle: 'none',
tex2jax: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
skipStartupTypeset: true
};
function loadScript( url, callback ) {
let head = document.querySelector( 'head' );
let script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
// Wrapper for callback to make sure it only fires once
let finish = () => {
if( typeof callback === 'function' ) {
callback.call();
callback = null;
}
}
script.onload = finish;
// IE
script.onreadystatechange = () => {
if ( this.readyState === 'loaded' ) {
finish();
}
}
// Normal browsers
head.appendChild( script );
}
return {
id: 'math',
init: function( reveal ) {
deck = reveal;
let revealOptions = deck.getConfig().math || {};
let options = { ...defaultOptions, ...revealOptions };
let mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
let config = options.config || 'TeX-AMS_HTML-full';
let url = mathjax + '?config=' + config;
options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
options.mathjax = options.config = null;
loadScript( url, function() {
MathJax.Hub.Config( options );
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
MathJax.Hub.Queue( deck.layout );
// Reprocess equations in slides when they turn visible
deck.on( 'slidechanged', function( event ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
} );
} );
}
}
};
export default Plugin;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import speakerViewHTML from './speaker-view.html' import speakerViewHTML from './speaker-view.html';
import { marked } from 'marked'; import marked from 'marked';
/** /**
* Handles opening of and synchronization with the reveal.js * Handles opening of and synchronization with the reveal.js
@@ -15,48 +15,24 @@ import { marked } from 'marked';
*/ */
const Plugin = () => { const Plugin = () => {
let connectInterval; let popup = null;
let speakerWindow = null;
let deck; let deck;
/** function openNotes() {
* Opens a new speaker view window.
*/
function openSpeakerWindow() {
// If a window is already open, focus it if (popup && !popup.closed) {
if( speakerWindow && !speakerWindow.closed ) { popup.focus();
speakerWindow.focus();
}
else {
speakerWindow = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
speakerWindow.marked = marked;
speakerWindow.document.write( speakerViewHTML );
if( !speakerWindow ) {
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
return; return;
} }
connect(); popup = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
} popup.marked = marked;
popup.document.write( speakerViewHTML );
}
/**
* Reconnect with an existing speaker view window.
*/
function reconnectSpeakerWindow( reconnectWindow ) {
if( speakerWindow && !speakerWindow.closed ) {
speakerWindow.focus();
}
else {
speakerWindow = reconnectWindow;
window.addEventListener( 'message', onPostMessage );
onConnected();
}
if( !popup ) {
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
return;
} }
/** /**
@@ -66,24 +42,26 @@ const Plugin = () => {
* file system. * file system.
*/ */
function connect() { function connect() {
const presentationURL = deck.getConfig().url;
const url = typeof presentationURL === 'string' ? presentationURL :
window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search;
// Keep trying to connect until we get a 'connected' message back // Keep trying to connect until we get a 'connected' message back
connectInterval = setInterval( function() { let connectInterval = setInterval( function() {
speakerWindow.postMessage( JSON.stringify( { popup.postMessage( JSON.stringify( {
namespace: 'reveal-notes', namespace: 'reveal-notes',
type: 'connect', type: 'connect',
state: deck.getState(), url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search,
url state: deck.getState()
} ), '*' ); } ), '*' );
}, 500 ); }, 500 );
window.addEventListener( 'message', onPostMessage ); window.addEventListener( 'message', function( event ) {
let data = JSON.parse( event.data );
if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
clearInterval( connectInterval );
onConnected();
}
if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
callRevealApi( data.methodName, data.arguments, data.callId );
}
} );
} }
/** /**
@@ -93,22 +71,22 @@ const Plugin = () => {
function callRevealApi( methodName, methodArguments, callId ) { function callRevealApi( methodName, methodArguments, callId ) {
let result = deck[methodName].apply( deck, methodArguments ); let result = deck[methodName].apply( deck, methodArguments );
speakerWindow.postMessage( JSON.stringify( { popup.postMessage( JSON.stringify( {
namespace: 'reveal-notes', namespace: 'reveal-notes',
type: 'return', type: 'return',
result, result: result,
callId callId: callId
} ), '*' ); } ), '*' );
} }
/** /**
* Posts the current slide data to the notes window. * Posts the current slide data to the notes window
*/ */
function post( event ) { function post( event ) {
let slideElement = deck.getCurrentSlide(), let slideElement = deck.getCurrentSlide(),
notesElements = slideElement.querySelectorAll( 'aside.notes' ), notesElement = slideElement.querySelector( 'aside.notes' ),
fragmentElement = slideElement.querySelector( '.current-fragment' ); fragmentElement = slideElement.querySelector( '.current-fragment' );
let messageData = { let messageData = {
@@ -130,62 +108,24 @@ const Plugin = () => {
if( fragmentElement ) { if( fragmentElement ) {
let fragmentNotes = fragmentElement.querySelector( 'aside.notes' ); let fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
if( fragmentNotes ) { if( fragmentNotes ) {
messageData.notes = fragmentNotes.innerHTML; notesElement = fragmentNotes;
messageData.markdown = typeof fragmentNotes.getAttribute( 'data-markdown' ) === 'string';
// Ignore other slide notes
notesElements = null;
} }
else if( fragmentElement.hasAttribute( 'data-notes' ) ) { else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
messageData.notes = fragmentElement.getAttribute( 'data-notes' ); messageData.notes = fragmentElement.getAttribute( 'data-notes' );
messageData.whitespace = 'pre-wrap'; messageData.whitespace = 'pre-wrap';
// In case there are slide notes // In case there are slide notes
notesElements = null; notesElement = null;
} }
} }
// Look for notes defined in an aside element // Look for notes defined in an aside element
if( notesElements ) { if( notesElement ) {
messageData.notes = Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' ); messageData.notes = notesElement.innerHTML;
messageData.markdown = notesElements[0] && typeof notesElements[0].getAttribute( 'data-markdown' ) === 'string'; messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
} }
speakerWindow.postMessage( JSON.stringify( messageData ), '*' ); popup.postMessage( JSON.stringify( messageData ), '*' );
}
/**
* Check if the given event is from the same origin as the
* current window.
*/
function isSameOriginEvent( event ) {
try {
return window.location.origin === event.source.location.origin;
}
catch ( error ) {
return false;
}
}
function onPostMessage( event ) {
// Only allow same-origin messages
// (added 12/5/22 as a XSS safeguard)
if( isSameOriginEvent( event ) ) {
let data = JSON.parse( event.data );
if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
clearInterval( connectInterval );
onConnected();
}
else if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
callRevealApi( data.methodName, data.arguments, data.callId );
}
}
} }
@@ -209,6 +149,10 @@ const Plugin = () => {
} }
connect();
}
return { return {
id: 'notes', id: 'notes',
@@ -220,40 +164,19 @@ const Plugin = () => {
// If the there's a 'notes' query set, open directly // If the there's a 'notes' query set, open directly
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
openSpeakerWindow(); openNotes();
}
else {
// Keep listening for speaker view hearbeats. If we receive a
// heartbeat from an orphaned window, reconnect it. This ensures
// that we remain connected to the notes even if the presentation
// is reloaded.
window.addEventListener( 'message', event => {
if( !speakerWindow && typeof event.data === 'string' ) {
let data;
try {
data = JSON.parse( event.data );
}
catch( error ) {}
if( data && data.namespace === 'reveal-notes' && data.type === 'heartbeat' ) {
reconnectSpeakerWindow( event.source );
}
}
});
} }
// Open the notes when the 's' key is hit // Open the notes when the 's' key is hit
deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
openSpeakerWindow(); openNotes();
} ); } );
} }
}, },
open: openSpeakerWindow open: openNotes
}; };
}; };

View File

@@ -1,6 +1,3 @@
<!--
NOTE: You need to build the notes plugin after making changes to this file.
-->
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@@ -350,9 +347,7 @@
layoutDropdown, layoutDropdown,
pendingCalls = {}, pendingCalls = {},
lastRevealApiCallId = 0, lastRevealApiCallId = 0,
connected = false connected = false;
var connectionStatus = document.querySelector( '#connection-status' );
var SPEAKER_LAYOUTS = { var SPEAKER_LAYOUTS = {
'default': 'Default', 'default': 'Default',
@@ -363,20 +358,7 @@
setupLayout(); setupLayout();
let openerOrigin; var connectionStatus = document.querySelector( '#connection-status' );
try {
openerOrigin = window.opener.location.origin;
}
catch ( error ) { console.warn( error ) }
// In order to prevent XSS, the speaker view will only run if its
// opener has the same origin as itself
if( window.location.origin !== openerOrigin ) {
connectionStatus.innerHTML = 'Cross origin error.<br>The speaker window can only be opened from the same origin.';
return;
}
var connectionTimeout = setTimeout( function() { var connectionTimeout = setTimeout( function() {
connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.'; connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
}, 5000 ); }, 5000 );
@@ -413,21 +395,13 @@
} }
else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) { else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
dispatchStateToMainWindow( data.state ); window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ]} ), '*' );
} }
} }
} ); } );
/**
* Updates the presentation in the main window to match the state
* of the presentation in the notes window.
*/
const dispatchStateToMainWindow = debounce(( state ) => {
window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ state ]} ), '*' );
}, 500);
/** /**
* Asynchronously calls the Reveal.js API of the main frame. * Asynchronously calls the Reveal.js API of the main frame.
*/ */
@@ -458,7 +432,6 @@
setupKeyboard(); setupKeyboard();
setupNotes(); setupNotes();
setupTimer(); setupTimer();
setupHeartbeat();
} }
} }
@@ -560,18 +533,6 @@
} }
/**
* We send out a heartbeat at all times to ensure we can
* reconnect with the main presentation window after reloads.
*/
function setupHeartbeat() {
setInterval( () => {
window.opener.postMessage( JSON.stringify({ namespace: 'reveal-notes', type: 'heartbeat'} ), '*' );
}, 1000 );
}
function getTimings( callback ) { function getTimings( callback ) {
callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) { callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -25,12 +25,6 @@ const Plugin = {
} }
} ); } );
},
destroy: () => {
zoom.reset();
} }
}; };
@@ -58,11 +52,19 @@ var zoom = (function(){
panUpdateInterval = -1; panUpdateInterval = -1;
// Check for transform support so that we can fallback otherwise // Check for transform support so that we can fallback otherwise
var supportsTransforms = 'transform' in document.body.style; var supportsTransforms = 'WebkitTransform' in document.body.style ||
'MozTransform' in document.body.style ||
'msTransform' in document.body.style ||
'OTransform' in document.body.style ||
'transform' in document.body.style;
if( supportsTransforms ) { if( supportsTransforms ) {
// The easing that will be applied when we zoom in/out // The easing that will be applied when we zoom in/out
document.body.style.transition = 'transform 0.8s ease'; document.body.style.transition = 'transform 0.8s ease';
document.body.style.OTransition = '-o-transform 0.8s ease';
document.body.style.msTransition = '-ms-transform 0.8s ease';
document.body.style.MozTransition = '-moz-transform 0.8s ease';
document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
} }
// Zoom out if the user hits escape // Zoom out if the user hits escape
@@ -103,6 +105,10 @@ var zoom = (function(){
// Reset // Reset
if( scale === 1 ) { if( scale === 1 ) {
document.body.style.transform = ''; document.body.style.transform = '';
document.body.style.OTransform = '';
document.body.style.msTransform = '';
document.body.style.MozTransform = '';
document.body.style.WebkitTransform = '';
} }
// Scale // Scale
else { else {
@@ -110,7 +116,16 @@ var zoom = (function(){
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')'; transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
document.body.style.transformOrigin = origin; document.body.style.transformOrigin = origin;
document.body.style.OTransformOrigin = origin;
document.body.style.msTransformOrigin = origin;
document.body.style.MozTransformOrigin = origin;
document.body.style.WebkitTransformOrigin = origin;
document.body.style.transform = transform; document.body.style.transform = transform;
document.body.style.OTransform = transform;
document.body.style.msTransform = transform;
document.body.style.MozTransform = transform;
document.body.style.WebkitTransform = transform;
} }
} }
else { else {

View File

@@ -1,11 +1,4 @@
/*! /*!
* reveal.js Zoom plugin * reveal.js Zoom plugin
*/ */
const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))},destroy:()=>{t.reset()}};var t=function(){var e=1,o=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=r();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,s(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}(); var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();export default function(){return e}
/*!
* zoom.js 0.3 (modified for use with reveal.js)
* http://lab.hakim.se/zoom-js
* MIT licensed
*
* Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
*/export default()=>e;

View File

@@ -1,11 +1,4 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=t()}(this,(function(){"use strict"; !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=o()}(this,(function(){"use strict";
/*! /*!
* reveal.js Zoom plugin * reveal.js Zoom plugin
*/const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))},destroy:()=>{t.reset()}};var t=function(){var e=1,o=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=r();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,s(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}(); */var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))}},o=function(){var e=1,t=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(o,t){var n=l();if(o.width=o.width||1,o.height=o.height||1,o.x-=(window.innerWidth-o.width*t)/2,o.y-=(window.innerHeight-o.height*t)/2,s)if(1===t)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-o.x+"px,"+-o.y+"px) scale("+t+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===t?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+o.x)/t+"px",document.body.style.top=-(n.y+o.y)/t+"px",document.body.style.width=100*t+"%",document.body.style.height=100*t+"%",document.body.style.zoom=t);e=t,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=l();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),t<o?window.scroll(d.x-14/e*(1-t/o),d.y):t>window.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function l(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,r(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
/*!
* zoom.js 0.3 (modified for use with reveal.js)
* http://lab.hakim.se/zoom-js
* MIT licensed
*
* Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
*/return()=>e}));

View File

@@ -23,19 +23,19 @@
<section data-auto-animate> <section data-auto-animate>
<h1>h1</h1> <h1>h1</h1>
<h2>h2</h2> <h2>h2</h2>
<h3 style="position: absolute; left: 0;">h3</h3> <h3 style="position: absolute; left: 0;">h3</h2>
</section> </section>
<section data-auto-animate> <section data-auto-animate>
<h1 data-auto-animate-duration="0.1">h1</h1> <h1 data-auto-animate-duration="0.1">h1</h1>
<h2 style="opacity: 0;">h2</h2> <h2 style="opacity: 0;">h2</h2>
<h3 style="position: absolute; left: 100px;">h3</h3> <h3 style="position: absolute; left: 100px;">h3</h2>
</section> </section>
<section data-auto-animate data-auto-animate-duration="0.1"> <section data-auto-animate data-auto-animate-duration="0.1">
<h1>h1</h1> <h1>h1</h1>
<h2>h2</h2> <h2>h2</h2>
<h3>h3</h3> <h3>h3</h2>
</section> </section>
<section> <section>

View File

@@ -36,7 +36,7 @@
<section data-background="examples/assets/image2.png" data-notes="speaker notes 2"> <section data-background="examples/assets/image2.png" data-notes="speaker notes 2">
<h1>2.1</h1> <h1>2.1</h1>
</section> </section>
<section data-background-image="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4gIcSUNDX1BST0ZJTEUAAQEAAAIMbGNtcwIQAABtbnRyUkdCIFhZWiAH3AABABkAAwApADlhY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApkZXNjAAAA/"> <section>
<h1>2.2</h1> <h1>2.2</h1>
</section> </section>
<section> <section>
@@ -97,11 +97,6 @@
// 4 // 4
Reveal.initialize().then( function() { Reveal.initialize().then( function() {
// Helper methods
function triggerKeyboardEvent(config) {
document.dispatchEvent( new KeyboardEvent( 'keydown', config ) );
}
// --------------------------------------------------------------- // ---------------------------------------------------------------
// DOM TESTS // DOM TESTS
@@ -341,38 +336,38 @@
Reveal.configure({ hash: true, fragmentInURL: false }); Reveal.configure({ hash: true, fragmentInURL: false });
Reveal.slide( 2, 0 ); Reveal.slide( 2, 0 );
assert.strictEqual( Reveal.getSlidePath(), '/2' ); assert.strictEqual( window.location.hash, '#/2' );
Reveal.slide( 2, 1 ); Reveal.slide( 2, 1 );
assert.strictEqual( Reveal.getSlidePath(), '/2/1' ); assert.strictEqual( window.location.hash, '#/2/1' );
Reveal.slide( 2, 0, 1 ); Reveal.slide( 2, 0, 1 );
assert.strictEqual( Reveal.getSlidePath(), '/2' ); assert.strictEqual( window.location.hash, '#/2' );
Reveal.slide( 2, 2, 0 ); Reveal.slide( 2, 2, 0 );
assert.strictEqual( Reveal.getSlidePath(), '/fragments3' ); assert.strictEqual( window.location.hash, '#/fragments3' );
Reveal.slide( 2, 2, 1 ); Reveal.slide( 2, 2, 1 );
assert.strictEqual( Reveal.getSlidePath(), '/fragments3' ); assert.strictEqual( window.location.hash, '#/fragments3' );
}); });
QUnit.test( 'Write (fragmentInURL: true)', function( assert ) { QUnit.test( 'Write (fragmentInURL: true)', function( assert ) {
Reveal.configure({ hash: true, fragmentInURL: true }); Reveal.configure({ hash: true, fragmentInURL: true });
Reveal.slide( 2, 0, -1 ); Reveal.slide( 2, 0, -1 );
assert.strictEqual( Reveal.getSlidePath(), '/2' ); assert.strictEqual( window.location.hash, '#/2' );
Reveal.slide( 2, 1, -1 ); Reveal.slide( 2, 1, -1 );
assert.strictEqual( Reveal.getSlidePath(), '/2/1' ); assert.strictEqual( window.location.hash, '#/2/1' );
Reveal.slide( 2, 0, 1 ); Reveal.slide( 2, 0, 1 );
assert.strictEqual( Reveal.getSlidePath(), '/2/0/1' ); assert.strictEqual( window.location.hash, '#/2/0/1' );
Reveal.slide( 2, 2, -1 ); Reveal.slide( 2, 2, -1 );
assert.strictEqual( Reveal.getSlidePath(), '/fragments3' ); assert.strictEqual( window.location.hash, '#/fragments3' );
Reveal.slide( 2, 2, 1 ); Reveal.slide( 2, 2, 1 );
assert.strictEqual( Reveal.getSlidePath(), '/fragments3/1' ); assert.strictEqual( window.location.hash, '#/fragments3/1' );
}); });
QUnit.test( 'Read', async function( assert ) { QUnit.test( 'Read', async function( assert ) {
@@ -412,41 +407,13 @@
assert.ok( /X\-SHORTCUT\-X/.test( document.body.innerHTML ), 'binding is added to help overlay' ); assert.ok( /X\-SHORTCUT\-X/.test( document.body.innerHTML ), 'binding is added to help overlay' );
Reveal.toggleHelp( false ); Reveal.toggleHelp( false );
triggerKeyboardEvent({ keyCode: 88 }); let event = new KeyboardEvent( 'keydown', { 'keyCode':88 } );
document.dispatchEvent( event );
Reveal.removeKeyBinding( 88 ); Reveal.removeKeyBinding( 88 );
// should do nothing // should do nothing
triggerKeyboardEvent({ keyCode: 88 }); document.dispatchEvent( event );
});
QUnit.test( 'Navigation bindings', function( assert ) {
Reveal.slide( 0 );
// right arrow
triggerKeyboardEvent({ keyCode: 39 });
assert.strictEqual( Reveal.getIndices().h, 1 );
// down arrow + shift
triggerKeyboardEvent({ keyCode: 40, shiftKey: true });
assert.strictEqual( Reveal.getIndices().v, 2, 'shift + down arrow goes to last vertical slide' );
// up arrow
triggerKeyboardEvent({ keyCode: 38 });
assert.strictEqual( Reveal.getIndices().v, 1 );
// right arrow + shift
triggerKeyboardEvent({ keyCode: 39, shiftKey: true });
assert.ok( Reveal.isLastSlide(), 'shift + right arrow goes to last horizontal slide' );
// right arrow on slide with fragments
Reveal.slide( 2, 0, -1 );
triggerKeyboardEvent({ keyCode: 39 });
assert.deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'right arrow shows fragment' );
triggerKeyboardEvent({ keyCode: 39, altKey: true });
assert.strictEqual( Reveal.getIndices().h, 3, 'right arrow skips fragments when alt key is pressed' );
}); });
// --------------------------------------------------------------- // ---------------------------------------------------------------
@@ -727,16 +694,7 @@
Reveal.right(); Reveal.right();
assert.equal( Reveal.getIndices().h, 0, 'looped from end to start' ); assert.equal( Reveal.getIndices().h, 0, 'looped from end to start' );
Reveal.configure({ navigationMode: 'linear' }); Reveal.configure({ loop: false });
Reveal.slide( 0, 0 );
Reveal.prev();
assert.notEqual( Reveal.getIndices().h, 0, 'looped from start to end in linear mode' );
Reveal.next();
assert.equal( Reveal.getIndices().h, 0, 'looped from end to start in linear mode' );
Reveal.configure({ loop: false, navigationMode: 'default' });
}); });
@@ -769,12 +727,10 @@
QUnit.test( 'background images', function( assert ) { QUnit.test( 'background images', function( assert ) {
var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' ); var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' );
var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' ); var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
var imageSource3 = Reveal.getSlide( 1, 1 ).getAttribute( 'data-background-image' );
// check that the images are applied to the background elements // check that the images are applied to the background elements
assert.ok( Reveal.getSlideBackground( 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' ); assert.ok( Reveal.getSlideBackground( 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' );
assert.ok( Reveal.getSlideBackground( 1, 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' ); assert.ok( Reveal.getSlideBackground( 1, 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
assert.ok( Reveal.getSlideBackground( 1, 1 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource3 ) !== -1, 'data-background worked' );
}); });
@@ -783,31 +739,6 @@
QUnit.module( 'Events' ); QUnit.module( 'Events' );
QUnit.test( 'beforeslidechange', function( assert ) {
var done = assert.async( 2 );
var normalEvent = function( event ) {
assert.ok( true, 'event fired' );
done();
}
var blockingEvent = function( event ) {
event.preventDefault();
assert.ok( true, 'event fired' );
done();
}
Reveal.on( 'beforeslidechange', normalEvent );
Reveal.slide( 2, 0 );
Reveal.off( 'beforeslidechange', normalEvent );
Reveal.on( 'beforeslidechange', blockingEvent );
Reveal.slide( 3, 0 );
Reveal.off( 'beforeslidechange', blockingEvent );
assert.strictEqual( Reveal.getIndices().h, 2, 'preventing "beforeslidechange" blocks navigation ' );
});
QUnit.test( 'slidechanged', function( assert ) { QUnit.test( 'slidechanged', function( assert ) {
assert.expect( 3 ); assert.expect( 3 );
var done = assert.async( 3 ); var done = assert.async( 3 );