Compare commits
301 Commits
internship
...
it-writing
| Author | SHA1 | Date | |
|---|---|---|---|
|
8cad2b0b5a
|
|||
|
|
becc9bd19e | ||
|
|
662c73453e | ||
|
|
6dbfd7e718 | ||
|
|
363bb3e6e6 | ||
|
|
c9d6785df2 | ||
|
|
8bb6674303 | ||
|
|
1427059378 | ||
|
|
5e7848fbcd | ||
|
|
4cf184924d | ||
|
|
e8cd04da83 | ||
|
|
b502bb6faa | ||
|
|
5412639a54 | ||
|
|
8003efe030 | ||
|
|
2fd7f83a1a | ||
|
|
eb95b14531 | ||
|
|
dfc5690c6d | ||
|
|
b03a94c6fc | ||
|
|
23926edb87 | ||
|
|
70daf8fce6 | ||
|
|
25e52e26af | ||
|
|
7e96e9ce0a | ||
|
|
2f76a34897 | ||
|
|
9612f7bde0 | ||
|
|
722b14b89f | ||
|
|
1923a5c7a4 | ||
|
|
aa9dfc7eb8 | ||
|
|
ac4064b64d | ||
|
|
9f7256fe78 | ||
|
|
5c77e86301 | ||
|
|
0121173213 | ||
|
|
7a62643c6a | ||
|
|
198e206ad0 | ||
|
|
1e0a2a7d4a | ||
|
|
47ee25dd19 | ||
|
|
94716f9e51 | ||
|
|
b3fd27d071 | ||
|
|
edb69c840c | ||
|
|
f11812e0a2 | ||
|
|
d5d292f70a | ||
|
|
a7b4bb4946 | ||
|
|
659472f8a4 | ||
|
|
2ac0566941 | ||
|
|
657543ac96 | ||
|
|
e7456847c6 | ||
|
|
255d55ab8f | ||
|
|
60401a2740 | ||
|
|
9c6bd42939 | ||
|
|
36daed927e | ||
|
|
2059d388f7 | ||
|
|
fe67bad092 | ||
|
|
9af726b606 | ||
|
|
0950590300 | ||
|
|
087eed8dc3 | ||
|
|
8f19e13ab1 | ||
|
|
1b2c39a86e | ||
|
|
0524ae855d | ||
|
|
3ceac9402d | ||
|
|
6cebb771ee | ||
|
|
31ba65ce86 | ||
|
|
983c6248f7 | ||
|
|
6527f4d912 | ||
|
|
3751715414 | ||
|
|
e15cf92ccd | ||
|
|
6dea2a5094 | ||
|
|
0d02d8a303 | ||
|
|
fe4a6e82b0 | ||
|
|
5a275f223b | ||
|
|
f979ff68e9 | ||
|
|
a6417ae747 | ||
|
|
c9ad332057 | ||
|
|
16ac4b0067 | ||
|
|
96ca819770 | ||
|
|
95946b4ec6 | ||
|
|
8d7b03c886 | ||
|
|
b8bb94f788 | ||
|
|
8e58d1b7db | ||
|
|
669cc25e55 | ||
|
|
2dcbf2745e | ||
|
|
472535065c | ||
|
|
7cab93baab | ||
|
|
15d9b650a5 | ||
|
|
ab760babb7 | ||
|
|
2d273bf06c | ||
|
|
6b8c64ffa8 | ||
|
|
dab6ef6b38 | ||
|
|
092a34bf0c | ||
|
|
e0bc3f764d | ||
|
|
091fede288 | ||
|
|
e8ddb101de | ||
|
|
f9cf4f5cfe | ||
|
|
1cc02565b0 | ||
|
|
6410c756ea | ||
|
|
62297e6259 | ||
|
|
ade53094b9 | ||
|
|
164254655b | ||
|
|
e2344787c4 | ||
|
|
334abff10f | ||
|
|
19c1bca1e4 | ||
|
|
0799c8f674 | ||
|
|
924bdb6305 | ||
|
|
d4e5c39fe4 | ||
|
|
2fb4b46307 | ||
|
|
488c5c8f94 | ||
|
|
421da63750 | ||
|
|
62b1ea302c | ||
|
|
76ec60a137 | ||
|
|
1748a55ece | ||
|
|
a29a9c71ae | ||
|
|
6ef138b61f | ||
|
|
63e0a37a88 | ||
|
|
2927be34d8 | ||
|
|
9d4b4362e9 | ||
|
|
8efd7af37c | ||
|
|
66fa4350e1 | ||
|
|
f149d1f7ca | ||
|
|
0951ce2b4f | ||
|
|
18ec38a6b1 | ||
|
|
67b5ec1773 | ||
|
|
50580c37c2 | ||
|
|
ec4eeab478 | ||
|
|
4e353b207d | ||
|
|
608e0eefcd | ||
|
|
aa31cab9e3 | ||
|
|
28aee42e8e | ||
|
|
ebca26e1f9 | ||
|
|
d61b375bf8 | ||
|
|
dcc21516dd | ||
|
|
16f6633014 | ||
|
|
5d131cea20 | ||
|
|
52480157a1 | ||
|
|
5ee1f729bd | ||
|
|
0e21a2a791 | ||
|
|
767a67ee00 | ||
|
|
89ab00a4a1 | ||
|
|
993b8f302a | ||
|
|
d5896c968b | ||
|
|
bf285afcf2 | ||
|
|
9d491c6d2f | ||
|
|
a88f38dec0 | ||
|
|
20d9eaf496 | ||
|
|
339dc709da | ||
|
|
f33e9d7662 | ||
|
|
bbd0d3e4f7 | ||
|
|
3d7d3152a4 | ||
|
|
bddeb70f4e | ||
|
|
1e1e228680 | ||
|
|
11680561e9 | ||
|
|
9d1c7e21b6 | ||
|
|
010f06c339 | ||
|
|
eee0a4ff24 | ||
|
|
d14084d4a4 | ||
|
|
30eddd95ed | ||
|
|
b6a3ea82e1 | ||
|
|
b2d0a3f70c | ||
|
|
73d3f3432f | ||
|
|
09b22cee6c | ||
|
|
97d73bd3dc | ||
|
|
790fd8c29a | ||
|
|
2518301d3e | ||
|
|
89bf44ba92 | ||
|
|
adfa3462cc | ||
|
|
68efdf6b03 | ||
|
|
cc640a21d3 | ||
|
|
c594f9c6ec | ||
|
|
942be4ee42 | ||
|
|
c23964274c | ||
|
|
e46bad392a | ||
|
|
ff252c984f | ||
|
|
0072845828 | ||
|
|
5b537aa8f8 | ||
|
|
aa5c03c234 | ||
|
|
ff3244af7a | ||
|
|
49c0030392 | ||
|
|
51acc830f9 | ||
|
|
cc9a36dc25 | ||
|
|
a9031821ef | ||
|
|
c1d64ad8d0 | ||
|
|
57ce5a5e3d | ||
|
|
c4e322ce79 | ||
|
|
836967d8ab | ||
|
|
28ef437a89 | ||
|
|
c80b685a88 | ||
|
|
7108476911 | ||
|
|
b8b55b8d4c | ||
|
|
a7d0916f28 | ||
|
|
198cbc4ace | ||
|
|
d802789c4d | ||
|
|
c1b1745200 | ||
|
|
980b902a9d | ||
|
|
be5d811914 | ||
|
|
122642fdea | ||
|
|
09f36adc70 | ||
|
|
2c5a83c945 | ||
|
|
a6abd0423e | ||
|
|
234799114a | ||
|
|
f80ee3b917 | ||
|
|
1871824fae | ||
|
|
1f1ca3a887 | ||
|
|
d84aa3472e | ||
|
|
ab52d334df | ||
|
|
42a1844d27 | ||
|
|
899a45dff6 | ||
|
|
3db2340df3 | ||
|
|
88fbfc5751 | ||
|
|
c856fa9db1 | ||
|
|
4c9cc89566 | ||
|
|
97f2e184c1 | ||
|
|
e49e89a557 | ||
|
|
f0950ba9ae | ||
|
|
0861b07618 | ||
|
|
5de7da7692 | ||
|
|
db2523db27 | ||
|
|
eb01f8f3a5 | ||
|
|
cd948d4136 | ||
|
|
07a6cf1249 | ||
|
|
4da6f6b30f | ||
|
|
eaf5f61318 | ||
|
|
0f27ef40fb | ||
|
|
f26d31570e | ||
|
|
a4b7f9dff7 | ||
|
|
6aa1eae796 | ||
|
|
487cc860f8 | ||
|
|
c5307462b0 | ||
|
|
fc16cc8b11 | ||
|
|
03fe25c1f6 | ||
|
|
81ea116292 | ||
|
|
3a830dd98f | ||
|
|
777e2a2d05 | ||
|
|
680cf5edb8 | ||
|
|
edf6638065 | ||
|
|
a1d0cdffc4 | ||
|
|
064b3c3aa5 | ||
|
|
2ab0689aa3 | ||
|
|
75c0be853c | ||
|
|
ccbaffc975 | ||
|
|
bae6de87ec | ||
|
|
9babaa005f | ||
|
|
af1cd9d6a4 | ||
|
|
a3f71b4a9b | ||
|
|
58881061ab | ||
|
|
e1c180565e | ||
|
|
b8d97d2537 | ||
|
|
74a5dac34f | ||
|
|
f2b0316a91 | ||
|
|
92ee97fbfe | ||
|
|
da5682ce51 | ||
|
|
f4e1a8ef50 | ||
|
|
b66121e32b | ||
|
|
bddf79873b | ||
|
|
ae703c372c | ||
|
|
3d1eabba0f | ||
|
|
27ff199627 | ||
|
|
31174cbaba | ||
|
|
ba20abf0c3 | ||
|
|
2dd27b37c6 | ||
|
|
82d63e0296 | ||
|
|
c8a7f26229 | ||
|
|
12f5ba4c9d | ||
|
|
227f90fa00 | ||
|
|
0d699ec7f5 | ||
|
|
bf749ee1da | ||
|
|
0b44308754 | ||
|
|
0301ce58ab | ||
|
|
724c4fee27 | ||
|
|
006b348e6b | ||
|
|
0c9bdeab70 | ||
|
|
cd019514f3 | ||
|
|
1bfc699045 | ||
|
|
2cacfc1394 | ||
|
|
dcae8a4dc9 | ||
|
|
7de6ccb65b | ||
|
|
ea6b7197c7 | ||
|
|
ae652a8e4e | ||
|
|
b1a9842b2f | ||
|
|
32a16295c3 | ||
|
|
447fefd31c | ||
|
|
6510916b9f | ||
|
|
9c95411dfa | ||
|
|
e0ef8db54b | ||
|
|
4a1b91a9c8 | ||
|
|
3301d3036e | ||
|
|
fb1fecd754 | ||
|
|
60769db4ee | ||
|
|
efcc86273b | ||
|
|
b648a56009 | ||
|
|
282680e163 | ||
|
|
79e9fdf13f | ||
|
|
d146c1ddc1 | ||
|
|
a815c7d269 | ||
|
|
2eb6d1e71c | ||
|
|
6378df47c0 | ||
|
|
9f629a9d38 | ||
|
|
df355eca3a | ||
|
|
4fe3946cb4 | ||
|
|
7fbe03946f | ||
|
|
7a613a4507 | ||
|
|
9f1f7789bf | ||
|
|
8492b82d12 | ||
|
|
a092499981 | ||
|
|
b5fb6da46e |
8
.codespellrc
Normal file
@@ -0,0 +1,8 @@
|
||||
[codespell]
|
||||
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
|
||||
skip = .git*,node_modules,package-lock.json,*.css,.codespellrc
|
||||
check-hidden = true
|
||||
# Ignore super long lines -- must be minimized etc, acronyms
|
||||
# and some near hit variables
|
||||
ignore-regex = ^.{120,}|\b(currentY|FOM)\b
|
||||
# ignore-words-list =
|
||||
24
.github/workflows/js.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: tests
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 14.x, 16.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm install
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
env:
|
||||
CI: true
|
||||
23
.github/workflows/spellcheck.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Codespell configuration is within .codespellrc
|
||||
---
|
||||
name: Spellcheck
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
codespell:
|
||||
name: Check for spelling errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Codespell
|
||||
uses: codespell-project/actions-codespell@v2
|
||||
31
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
- push
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version:
|
||||
- 18
|
||||
- 20
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- run: npm install
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
env:
|
||||
CI: true
|
||||
@@ -1,7 +1,5 @@
|
||||
/test
|
||||
/examples
|
||||
.github
|
||||
.gulpfile
|
||||
.sass-cache
|
||||
gulpfile.js
|
||||
CONTRIBUTING.md
|
||||
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (C) 2011-2022 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
||||
Copyright (C) 2011-2024 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
24
README.md
@@ -4,7 +4,7 @@
|
||||
</a>
|
||||
<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://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://static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
|
||||
</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/).
|
||||
@@ -17,26 +17,6 @@ Want to create reveal.js presentation in a graphical editor? Try <https://slides
|
||||
|
||||
---
|
||||
|
||||
### Sponsors
|
||||
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>
|
||||
|
||||
---
|
||||
|
||||
### Getting started
|
||||
- 🚀 [Install reveal.js](https://revealjs.com/installation)
|
||||
- 👀 [View the demo presentation](https://revealjs.com/demo)
|
||||
@@ -46,5 +26,5 @@ Hakim's open source work is supported by <a href="https://github.com/sponsors/ha
|
||||
|
||||
---
|
||||
<div align="center">
|
||||
MIT licensed | Copyright © 2011-2022 Hakim El Hattab, https://hakim.se
|
||||
MIT licensed | Copyright © 2011-2024 Hakim El Hattab, https://hakim.se
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
// Stack multiple elements on top of each other
|
||||
.reveal .r-stack {
|
||||
display: grid;
|
||||
grid-template-rows: 100%;
|
||||
}
|
||||
|
||||
.reveal .r-stack > * {
|
||||
|
||||
@@ -1,42 +1,30 @@
|
||||
/* Default Print Stylesheet Template
|
||||
by Rob Glazebrook of CSSnewbie.com
|
||||
Last Updated: June 4, 2008
|
||||
|
||||
Feel free (nay, compelled) to edit, append, and
|
||||
manipulate this file as you see fit. */
|
||||
|
||||
@media print {
|
||||
html:not(.print-pdf) {
|
||||
|
||||
background: #fff;
|
||||
overflow: visible;
|
||||
width: auto;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font-size: 20pt;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: 0;
|
||||
margin: 0 5%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
float: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
html:not(.print-pdf) .reveal {
|
||||
background: #fff;
|
||||
font-size: 20pt;
|
||||
|
||||
.nestedarrow,
|
||||
.controls,
|
||||
.fork-reveal,
|
||||
.share-reveal,
|
||||
.state-background,
|
||||
.reveal .progress,
|
||||
.reveal .backgrounds,
|
||||
.reveal .slide-number {
|
||||
.progress,
|
||||
.backgrounds,
|
||||
.slide-number {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body, p, td, li {
|
||||
p, td, li {
|
||||
font-size: 20pt!important;
|
||||
color: #000;
|
||||
}
|
||||
@@ -49,7 +37,6 @@
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
/* Need to reduce the size of the fonts for printing */
|
||||
h1 { font-size: 28pt !important; }
|
||||
h2 { font-size: 24pt !important; }
|
||||
h3 { font-size: 22pt !important; }
|
||||
@@ -74,18 +61,19 @@
|
||||
margin: 0;
|
||||
text-align: left !important;
|
||||
}
|
||||
.reveal pre,
|
||||
.reveal table {
|
||||
pre,
|
||||
table {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.reveal pre code {
|
||||
pre code {
|
||||
padding: 20px;
|
||||
}
|
||||
.reveal blockquote {
|
||||
blockquote {
|
||||
margin: 20px 0;
|
||||
}
|
||||
.reveal .slides {
|
||||
|
||||
.slides {
|
||||
position: static !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
@@ -106,7 +94,7 @@
|
||||
|
||||
perspective-origin: 50% 50%;
|
||||
}
|
||||
.reveal .slides section {
|
||||
.slides section {
|
||||
visibility: visible !important;
|
||||
position: static !important;
|
||||
width: auto !important;
|
||||
@@ -129,24 +117,24 @@
|
||||
transform: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
.reveal .slides section.stack {
|
||||
.slides section.stack {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.reveal section:last-of-type {
|
||||
.slides section:last-of-type {
|
||||
page-break-after: avoid !important;
|
||||
}
|
||||
.reveal section .fragment {
|
||||
.slides section .fragment {
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.reveal .r-fit-text {
|
||||
.r-fit-text {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
.reveal section img {
|
||||
section img {
|
||||
display: block;
|
||||
margin: 15px 0px;
|
||||
background: rgba(255,255,255,1);
|
||||
@@ -154,11 +142,11 @@
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.reveal section small {
|
||||
section small {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.reveal .hljs {
|
||||
.hljs {
|
||||
max-height: 100%;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
@@ -166,11 +154,11 @@
|
||||
font-size: 15pt;
|
||||
}
|
||||
|
||||
.reveal .hljs .hljs-ln-numbers {
|
||||
.hljs .hljs-ln-numbers {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.reveal .hljs td {
|
||||
.hljs td {
|
||||
font-size: inherit !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* https://revealjs.com/pdf-export/
|
||||
*/
|
||||
|
||||
html.print-pdf {
|
||||
html.reveal-print {
|
||||
* {
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
@@ -36,7 +36,6 @@ html.print-pdf {
|
||||
|
||||
.reveal pre code {
|
||||
overflow: hidden !important;
|
||||
font-family: Courier, 'Courier New', monospace !important;
|
||||
}
|
||||
|
||||
.reveal {
|
||||
@@ -71,6 +70,10 @@ html.print-pdf {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.reveal .slides .pdf-page:last-of-type {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
.reveal .slides section {
|
||||
visibility: visible !important;
|
||||
display: block !important;
|
||||
@@ -146,6 +149,7 @@ html.print-pdf {
|
||||
display: block;
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* This accessibility tool is not useful in PDF and breaks it visually */
|
||||
|
||||
733
css/reveal.scss
@@ -1,5 +1,3 @@
|
||||
@use "sass:math";
|
||||
|
||||
/**
|
||||
* reveal.js
|
||||
* http://revealjs.com
|
||||
@@ -8,6 +6,7 @@
|
||||
* Copyright (C) Hakim El Hattab, https://hakim.se
|
||||
*/
|
||||
|
||||
@use "sass:math";
|
||||
@import 'layout';
|
||||
|
||||
/*********************************************
|
||||
@@ -19,6 +18,7 @@ html.reveal-full-page {
|
||||
height: 100%;
|
||||
height: 100vh;
|
||||
height: calc( var(--vh, 1vh) * 100 );
|
||||
height: 100dvh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,18 @@ html.reveal-full-page {
|
||||
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
|
||||
--r-controls-spacing: 12px;
|
||||
--r-overlay-header-height: 40px;
|
||||
--r-overlay-margin: 0px;
|
||||
--r-overlay-padding: 6px;
|
||||
--r-overlay-gap: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px), (max-height: 768px) {
|
||||
.reveal-viewport {
|
||||
--r-overlay-header-height: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
// Force the presentation to cover the full viewport when we
|
||||
@@ -48,11 +60,14 @@ html.reveal-full-page {
|
||||
* VIEW FRAGMENTS
|
||||
*********************************************/
|
||||
|
||||
.reveal .slides section .fragment {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
.reveal .fragment {
|
||||
transition: all .2s ease;
|
||||
will-change: opacity;
|
||||
|
||||
&:not(.custom) {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
@@ -64,7 +79,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.grow {
|
||||
.reveal .fragment.grow {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
|
||||
@@ -73,7 +88,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.shrink {
|
||||
.reveal .fragment.shrink {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
|
||||
@@ -82,7 +97,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.zoom-in {
|
||||
.reveal .fragment.zoom-in {
|
||||
transform: scale( 0.1 );
|
||||
|
||||
&.visible {
|
||||
@@ -90,7 +105,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-out {
|
||||
.reveal .fragment.fade-out {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
|
||||
@@ -100,7 +115,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.semi-fade-out {
|
||||
.reveal .fragment.semi-fade-out {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
|
||||
@@ -110,7 +125,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.strike {
|
||||
.reveal .fragment.strike {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
|
||||
@@ -119,7 +134,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-up {
|
||||
.reveal .fragment.fade-up {
|
||||
transform: translate(0, 40px);
|
||||
|
||||
&.visible {
|
||||
@@ -127,7 +142,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-down {
|
||||
.reveal .fragment.fade-down {
|
||||
transform: translate(0, -40px);
|
||||
|
||||
&.visible {
|
||||
@@ -135,7 +150,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-right {
|
||||
.reveal .fragment.fade-right {
|
||||
transform: translate(-40px, 0);
|
||||
|
||||
&.visible {
|
||||
@@ -143,7 +158,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-left {
|
||||
.reveal .fragment.fade-left {
|
||||
transform: translate(40px, 0);
|
||||
|
||||
&.visible {
|
||||
@@ -151,8 +166,8 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-in-then-out,
|
||||
.reveal .slides section .fragment.current-visible {
|
||||
.reveal .fragment.fade-in-then-out,
|
||||
.reveal .fragment.current-visible {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
|
||||
@@ -162,7 +177,7 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.fade-in-then-semi-out {
|
||||
.reveal .fragment.fade-in-then-semi-out {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
|
||||
@@ -177,32 +192,32 @@ html.reveal-full-page {
|
||||
}
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.highlight-red,
|
||||
.reveal .slides section .fragment.highlight-current-red,
|
||||
.reveal .slides section .fragment.highlight-green,
|
||||
.reveal .slides section .fragment.highlight-current-green,
|
||||
.reveal .slides section .fragment.highlight-blue,
|
||||
.reveal .slides section .fragment.highlight-current-blue {
|
||||
.reveal .fragment.highlight-red,
|
||||
.reveal .fragment.highlight-current-red,
|
||||
.reveal .fragment.highlight-green,
|
||||
.reveal .fragment.highlight-current-green,
|
||||
.reveal .fragment.highlight-blue,
|
||||
.reveal .fragment.highlight-current-blue {
|
||||
opacity: 1;
|
||||
visibility: inherit;
|
||||
}
|
||||
.reveal .slides section .fragment.highlight-red.visible {
|
||||
.reveal .fragment.highlight-red.visible {
|
||||
color: #ff2c2d
|
||||
}
|
||||
.reveal .slides section .fragment.highlight-green.visible {
|
||||
.reveal .fragment.highlight-green.visible {
|
||||
color: #17ff2e;
|
||||
}
|
||||
.reveal .slides section .fragment.highlight-blue.visible {
|
||||
.reveal .fragment.highlight-blue.visible {
|
||||
color: #1b91ff;
|
||||
}
|
||||
|
||||
.reveal .slides section .fragment.highlight-current-red.current-fragment {
|
||||
.reveal .fragment.highlight-current-red.current-fragment {
|
||||
color: #ff2c2d
|
||||
}
|
||||
.reveal .slides section .fragment.highlight-current-green.current-fragment {
|
||||
.reveal .fragment.highlight-current-green.current-fragment {
|
||||
color: #17ff2e;
|
||||
}
|
||||
.reveal .slides section .fragment.highlight-current-blue.current-fragment {
|
||||
.reveal .fragment.highlight-current-blue.current-fragment {
|
||||
color: #1b91ff;
|
||||
}
|
||||
|
||||
@@ -268,13 +283,11 @@ $controlsArrowAngleActive: 36deg;
|
||||
}
|
||||
|
||||
.reveal .controls {
|
||||
$spacing: 12px;
|
||||
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: auto;
|
||||
bottom: $spacing;
|
||||
right: $spacing;
|
||||
bottom: var(--r-controls-spacing);
|
||||
right: var(--r-controls-spacing);
|
||||
left: auto;
|
||||
z-index: 11;
|
||||
color: #000;
|
||||
@@ -506,7 +519,9 @@ $controlsArrowAngleActive: 36deg;
|
||||
// Edge aligned controls layout
|
||||
@media screen and (min-width: 500px) {
|
||||
|
||||
$spacing: 0.8em;
|
||||
.reveal-viewport {
|
||||
--r-controls-spacing: 0.8em;
|
||||
}
|
||||
|
||||
.reveal .controls[data-controls-layout="edges"] {
|
||||
& {
|
||||
@@ -526,24 +541,24 @@ $controlsArrowAngleActive: 36deg;
|
||||
|
||||
.navigate-left {
|
||||
top: 50%;
|
||||
left: $spacing;
|
||||
left: var(--r-controls-spacing);
|
||||
margin-top: -$controlArrowSize*0.5;
|
||||
}
|
||||
|
||||
.navigate-right {
|
||||
top: 50%;
|
||||
right: $spacing;
|
||||
right: var(--r-controls-spacing);
|
||||
margin-top: -$controlArrowSize*0.5;
|
||||
}
|
||||
|
||||
.navigate-up {
|
||||
top: $spacing;
|
||||
top: var(--r-controls-spacing);
|
||||
left: 50%;
|
||||
margin-left: -$controlArrowSize*0.5;
|
||||
}
|
||||
|
||||
.navigate-down {
|
||||
bottom: $spacing - $controlArrowSpacing + 0.3em;
|
||||
bottom: calc(var(--r-controls-spacing) - #{$controlArrowSpacing} + 0.3em);
|
||||
left: 50%;
|
||||
margin-left: -$controlArrowSize*0.5;
|
||||
}
|
||||
@@ -625,11 +640,16 @@ $controlsArrowAngleActive: 36deg;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
|
||||
// Swiping on an embedded deck should not block page scrolling
|
||||
// Swiping on an embedded deck should not block page scrolling...
|
||||
.reveal.embedded {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
// ... unless we're on a vertical slide
|
||||
.reveal.embedded.is-vertical-slide {
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.reveal .slides {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@@ -989,7 +1009,7 @@ $controlsArrowAngleActive: 36deg;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 95px 25px rgba(0,0,0,0.2);
|
||||
|
||||
-webkit-transform: translateZ(-90px) rotateX( 65deg );
|
||||
transform: translateZ(-90px) rotateX( 65deg );
|
||||
}
|
||||
|
||||
.reveal.page .slides>section.stack {
|
||||
@@ -1308,12 +1328,6 @@ $controlsArrowAngleActive: 36deg;
|
||||
perspective-origin: 50% 50%;
|
||||
perspective: 700px;
|
||||
|
||||
.slides {
|
||||
// Fixes overview rendering errors in FF48+, not applied to
|
||||
// other browsers since it degrades performance
|
||||
-moz-transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.slides section {
|
||||
height: 100%;
|
||||
top: 0 !important;
|
||||
@@ -1325,9 +1339,12 @@ $controlsArrowAngleActive: 36deg;
|
||||
}
|
||||
.slides section:hover,
|
||||
.slides section.present {
|
||||
outline: 10px solid rgba(150,150,150,0.4);
|
||||
outline: 10px solid rgba(150,150,150,0.6);
|
||||
outline-offset: 10px;
|
||||
}
|
||||
.slides section.present {
|
||||
outline: 10px solid var(--r-link-color);
|
||||
}
|
||||
.slides section .fragment {
|
||||
opacity: 1;
|
||||
transition: none;
|
||||
@@ -1346,10 +1363,6 @@ $controlsArrowAngleActive: 36deg;
|
||||
|
||||
.backgrounds {
|
||||
perspective: inherit;
|
||||
|
||||
// Fixes overview rendering errors in FF48+, not applied to
|
||||
// other browsers since it degrades performance
|
||||
-moz-transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.backgrounds .slide-background {
|
||||
@@ -1429,160 +1442,234 @@ $controlsArrowAngleActive: 36deg;
|
||||
* OVERLAY FOR LINK PREVIEWS AND HELP
|
||||
*********************************************/
|
||||
|
||||
$overlayHeaderHeight: 40px;
|
||||
$overlayHeaderPadding: 5px;
|
||||
@keyframes fade-in {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.reveal > .overlay {
|
||||
@keyframes scale-up {
|
||||
from { transform: scale( 0.95 ); }
|
||||
to { transform: scale( 1 ); }
|
||||
}
|
||||
|
||||
.reveal [data-preview-image],
|
||||
.reveal [data-preview-video],
|
||||
.reveal [data-preview-link]:not(a):not([data-preview-link=false]) {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.r-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
top: var(--r-overlay-margin);
|
||||
right: var(--r-overlay-margin);
|
||||
bottom: var(--r-overlay-margin);
|
||||
left: var(--r-overlay-margin);
|
||||
border-radius: min( var(--r-overlay-margin), 6px );
|
||||
z-index: 99;
|
||||
background: rgba( 0, 0, 0, 0.95 );
|
||||
backdrop-filter: blur( 10px );
|
||||
transition: all 0.3s ease;
|
||||
color: #fff;
|
||||
animation: fade-in 0.3s ease;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.r-overlay-viewport {
|
||||
position: absolute;
|
||||
top: var(--r-overlay-padding);
|
||||
right: var(--r-overlay-padding);
|
||||
bottom: var(--r-overlay-padding);
|
||||
left: var(--r-overlay-padding);
|
||||
gap: var(--r-overlay-gap);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.r-overlay-header {
|
||||
display: flex;
|
||||
z-index: 2;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
height: var(--r-overlay-header-height);
|
||||
gap: 6px;
|
||||
}
|
||||
.r-overlay-header .r-overlay-button {
|
||||
all: unset;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: var(--r-overlay-header-height);
|
||||
min-height: var(--r-overlay-header-height);
|
||||
padding: 0 calc(var(--r-overlay-header-height) / 4);
|
||||
opacity: 1;
|
||||
border-radius: 6px;
|
||||
font-size: 18px;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.r-overlay-header .r-overlay-button:hover {
|
||||
opacity: 1;
|
||||
background-color: rgba( 255, 255, 255, 0.15 );
|
||||
}
|
||||
.r-overlay-header .icon {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
background-position: 50% 50%;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.r-overlay-close .icon {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTIuODU0IDIuODU0YS41LjUgMCAwIDAtLjcwOC0uNzA4TDcuNSA2Ljc5MyAyLjg1NCAyLjE0NmEuNS41IDAgMSAwLS43MDguNzA4TDYuNzkzIDcuNWwtNC42NDcgNC42NDZhLjUuNSAwIDAgMCAuNzA4LjcwOEw3LjUgOC4yMDdsNC42NDYgNC42NDdhLjUuNSAwIDAgMCAuNzA4LS43MDhMOC4yMDcgNy41bDQuNjQ3LTQuNjQ2WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+);
|
||||
}
|
||||
.r-overlay-external .icon {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMyAyYTEgMSAwIDAgMC0xIDF2OWExIDEgMCAwIDAgMSAxaDlhMSAxIDAgMCAwIDEtMVY4LjVhLjUuNSAwIDAgMC0xIDBWMTJIM1YzaDMuNWEuNS41IDAgMCAwIDAtMUgzWm05Ljg1NC4xNDZhLjUuNSAwIDAgMSAuMTQ2LjM1MVY1LjVhLjUuNSAwIDAgMS0xIDBWMy43MDdMNi44NTQgOC44NTRhLjUuNSAwIDEgMS0uNzA4LS43MDhMMTEuMjkzIDNIOS41YS41LjUgMCAwIDEgMC0xaDNhLjQ5OS40OTkgMCAwIDEgLjM1NC4xNDZaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=);
|
||||
}
|
||||
|
||||
.r-overlay-content {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
background-color: rgba(20, 20, 20, 0.8);
|
||||
animation: scale-up 0.5s cubic-bezier(0.260, 0.860, 0.440, 0.985);
|
||||
}
|
||||
|
||||
.r-overlay-spinner {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: -16px 0 0 -16px;
|
||||
z-index: 10;
|
||||
background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);
|
||||
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
// Preview overlay
|
||||
.r-overlay-preview .r-overlay-content iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1000;
|
||||
background: rgba( 0, 0, 0, 0.9 );
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
border: 0;
|
||||
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.reveal > .overlay .spinner {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: -16px 0 0 -16px;
|
||||
z-index: 10;
|
||||
background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);
|
||||
.r-overlay-preview[data-state="loaded"] iframe {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
visibility: visible;
|
||||
opacity: 0.6;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.r-overlay-preview .r-overlay-content img,
|
||||
.r-overlay-preview .r-overlay-content video {
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
object-fit: scale-down;
|
||||
}
|
||||
|
||||
.reveal > .overlay header {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
padding: $overlayHeaderPadding;
|
||||
z-index: 2;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.reveal > .overlay header a {
|
||||
display: inline-block;
|
||||
width: $overlayHeaderHeight;
|
||||
height: $overlayHeaderHeight;
|
||||
line-height: 36px;
|
||||
padding: 0 10px;
|
||||
float: right;
|
||||
opacity: 0.6;
|
||||
.r-overlay-preview[data-preview-fit="none"] img,
|
||||
.r-overlay-preview[data-preview-fit="none"] video {
|
||||
object-fit: none;
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.reveal > .overlay header a:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.reveal > .overlay header a .icon {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
.r-overlay-preview[data-preview-fit="scale-down"] img,
|
||||
.r-overlay-preview[data-preview-fit="scale-down"] video {
|
||||
object-fit: scale-down;
|
||||
}
|
||||
|
||||
background-position: 50% 50%;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.reveal > .overlay header a.close .icon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC);
|
||||
}
|
||||
.reveal > .overlay header a.external .icon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==);
|
||||
}
|
||||
.r-overlay-preview[data-preview-fit="contain"] img,
|
||||
.r-overlay-preview[data-preview-fit="contain"] video {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.reveal > .overlay .viewport {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
top: $overlayHeaderHeight + $overlayHeaderPadding*2;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.r-overlay-preview[data-preview-fit="cover"] img,
|
||||
.r-overlay-preview[data-preview-fit="cover"] video {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-preview .viewport iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
border: 0;
|
||||
.r-overlay-preview[data-state="loaded"] .r-overlay-content-inner {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 0;
|
||||
top: 45%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
.r-overlay-preview .r-overlay-error {
|
||||
font-size: 18px;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.r-overlay-preview .x-frame-error {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease 0.3s;
|
||||
}
|
||||
.r-overlay-preview[data-state="loaded"] .x-frame-error {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-preview.loaded .viewport iframe {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
.r-overlay-preview[data-state="loading"] .r-overlay-spinner {
|
||||
opacity: 0.6;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-preview.loaded .viewport-inner {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 0;
|
||||
top: 45%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
.reveal > .overlay.overlay-preview .x-frame-error {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease 0.3s;
|
||||
}
|
||||
.reveal > .overlay.overlay-preview.loaded .x-frame-error {
|
||||
opacity: 1;
|
||||
}
|
||||
// Help overlay
|
||||
.r-overlay-help .r-overlay-content {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-preview.loaded .spinner {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: scale(0.2);
|
||||
}
|
||||
.r-overlay-help-content {
|
||||
max-width: 560px;
|
||||
padding: 20px 0;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport {
|
||||
overflow: auto;
|
||||
color: #fff;
|
||||
}
|
||||
.r-overlay-help-content .title {
|
||||
font-size: 20px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner {
|
||||
width: 600px;
|
||||
margin: auto;
|
||||
padding: 20px 20px 80px 20px;
|
||||
text-align: center;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
/* Specificity battle with reveal.js theme table styles */
|
||||
.r-overlay-help .r-overlay-help-content table {
|
||||
border: 1px solid #fff;
|
||||
border-collapse: collapse;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner .title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner table {
|
||||
border: 1px solid #fff;
|
||||
border-collapse: collapse;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner table th,
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner table td {
|
||||
width: 200px;
|
||||
padding: 14px;
|
||||
border: 1px solid #fff;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.reveal > .overlay.overlay-help .viewport .viewport-inner table th {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.r-overlay-help .r-overlay-help-content table th,
|
||||
.r-overlay-help .r-overlay-help-content table td {
|
||||
width: 240px;
|
||||
padding: 14px;
|
||||
border: 1px solid #fff;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.r-overlay-help .r-overlay-help-content table th {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PLAYBACK COMPONENT
|
||||
@@ -1633,6 +1720,10 @@ $overlayHeaderPadding: 5px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.reveal .hljs.has-highlights.fragment {
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.reveal .hljs:not(:first-child).fragment {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -1796,6 +1887,43 @@ $notesWidthPercent: 25%;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
* JUMP-TO-SLIDE COMPONENT
|
||||
*********************************************/
|
||||
|
||||
.reveal .jump-to-slide {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
z-index: 30;
|
||||
font-size: 32px;
|
||||
-webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
.reveal .jump-to-slide-input {
|
||||
background: transparent;
|
||||
padding: 8px;
|
||||
font-size: inherit;
|
||||
color: currentColor;
|
||||
border: 0;
|
||||
}
|
||||
.reveal .jump-to-slide-input::placeholder {
|
||||
color: currentColor;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.reveal.has-dark-background .jump-to-slide-input {
|
||||
color: #fff;
|
||||
}
|
||||
.reveal.has-light-background .jump-to-slide-input {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.reveal .jump-to-slide-input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
* ZOOM PLUGIN
|
||||
*********************************************/
|
||||
@@ -1820,6 +1948,239 @@ $notesWidthPercent: 25%;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
* SCROLL VIEW
|
||||
*********************************************/
|
||||
.reveal-viewport.loading-scroll-mode {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.reveal-viewport.reveal-scroll {
|
||||
& {
|
||||
margin: 0 auto;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
z-index: 1;
|
||||
|
||||
--r-scrollbar-width: 7px;
|
||||
--r-scrollbar-trigger-size: 5px;
|
||||
--r-controls-spacing: 8px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
--r-scrollbar-width: 3px;
|
||||
--r-scrollbar-trigger-size: 3px;
|
||||
}
|
||||
|
||||
.controls,
|
||||
.progress,
|
||||
.playback,
|
||||
.backgrounds,
|
||||
.slide-number,
|
||||
.speaker-notes {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.r-overlay,
|
||||
.pause-overlay {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.reveal {
|
||||
overflow: visible;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
.slides {
|
||||
position: static;
|
||||
pointer-events: initial;
|
||||
|
||||
left: auto;
|
||||
top: auto;
|
||||
width: 100% !important;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
overflow: visible;
|
||||
display: block;
|
||||
|
||||
perspective: none;
|
||||
perspective-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.scroll-page {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(var(--page-height) + var(--page-scroll-padding));
|
||||
z-index: 1;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.scroll-page-sticky {
|
||||
position: sticky;
|
||||
height: var(--page-height);
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.scroll-page-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scroll-page section {
|
||||
visibility: visible !important;
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
width: var(--slide-width) !important;
|
||||
height: var(--slide-height) !important;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
opacity: 1 !important;
|
||||
transform: scale(var(--slide-scale)) translate(-50%, -50%) !important;
|
||||
transform-style: flat !important;
|
||||
transform-origin: 0 0 !important;
|
||||
}
|
||||
|
||||
.slide-background {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: auto !important;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
}
|
||||
|
||||
// Chromium
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="true"]::-webkit-scrollbar,
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="auto"]::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Firefox
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="true"],
|
||||
.reveal-viewport.reveal-scroll[data-scrollbar="auto"] {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.reveal.has-dark-background,
|
||||
.reveal-viewport.has-dark-background {
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
.reveal.has-light-background,
|
||||
.reveal-viewport.has-light-background {
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport.reveal-scroll .scrollbar {
|
||||
position: sticky;
|
||||
top: 50%;
|
||||
z-index: 20;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.visible,
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.scrollbar-inner {
|
||||
position: absolute;
|
||||
width: var(--r-scrollbar-width);
|
||||
height: calc(var(--viewport-height) - var(--r-controls-spacing) * 2);
|
||||
right: var(--r-controls-spacing);
|
||||
top: 0;
|
||||
transform: translateY(-50%);
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-playhead {
|
||||
position: absolute;
|
||||
width: var(--r-scrollbar-width);
|
||||
height: var(--r-scrollbar-width);
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||
z-index: 11;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.scrollbar-slide {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.2);
|
||||
box-shadow: 0 0 0px 1px rgba(var(--r-overlay-element-fg-color), 0.1);
|
||||
border-radius: var(--r-scrollbar-width);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
// Hit area
|
||||
.scrollbar-slide:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: -50%;
|
||||
background: rgba( 0, 0, 0, 0 );
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.scrollbar-slide:hover,
|
||||
.scrollbar-slide.active {
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||
}
|
||||
|
||||
.scrollbar-trigger {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.scrollbar-slide.active.has-triggers {
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-slide.active .scrollbar-trigger:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: var(--r-scrollbar-trigger-size);
|
||||
height: var(--r-scrollbar-trigger-size);
|
||||
border-radius: 20px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.scrollbar-slide.active .scrollbar-trigger.active:after,
|
||||
.scrollbar-slide.active .scrollbar-trigger.active ~ .scrollbar-trigger:after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.scrollbar-slide.active .scrollbar-trigger ~ .scrollbar-trigger.active:after {
|
||||
transform: translate(calc( var(--r-scrollbar-width) * -2), 0);
|
||||
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
* PRINT STYLES
|
||||
*********************************************/
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -23,10 +24,13 @@ $headingColor: #333;
|
||||
$headingTextShadow: none;
|
||||
$backgroundColor: #f7f3de;
|
||||
$linkColor: #8b743d;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
|
||||
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Background generator
|
||||
@mixin bodyBackground() {
|
||||
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
|
||||
|
||||
50
css/theme/source/black-contrast.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Black compact & high contrast reveal.js theme, with headers not in capitals.
|
||||
*
|
||||
* By Peter Kehl. Based on black.(s)css by Hakim El Hattab, http://hakim.se
|
||||
*
|
||||
* - Keep the source similar to black.css - for easy comparison.
|
||||
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||
*/
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
|
||||
|
||||
// Include theme-specific fonts
|
||||
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||
|
||||
|
||||
// Override theme settings (see ../template/settings.scss)
|
||||
$backgroundColor: #000000;
|
||||
|
||||
$mainColor: #fff;
|
||||
$headingColor: #fff;
|
||||
|
||||
$mainFontSize: 42px;
|
||||
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||
$headingTextShadow: none;
|
||||
$headingLetterSpacing: normal;
|
||||
$headingTextTransform: uppercase;
|
||||
$headingFontWeight: 600;
|
||||
$linkColor: #42affa;
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
||||
$selectionBackgroundColor: color.scale( $linkColor, $lightness: 25% );
|
||||
|
||||
$heading1Size: 2.5em;
|
||||
$heading2Size: 1.6em;
|
||||
$heading3Size: 1.3em;
|
||||
$heading4Size: 1.0em;
|
||||
|
||||
// Change text colors against light slide backgrounds
|
||||
@include light-bg-text-color(#000);
|
||||
|
||||
|
||||
// Theme template ------------------------------
|
||||
@import "../template/theme";
|
||||
// ---------------------------------------------
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -29,8 +30,8 @@ $headingLetterSpacing: normal;
|
||||
$headingTextTransform: uppercase;
|
||||
$headingFontWeight: 600;
|
||||
$linkColor: #42affa;
|
||||
$linkColorHover: lighten( $linkColor, 15% );
|
||||
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
||||
$selectionBackgroundColor: rgba( $linkColor, 0.75 );
|
||||
|
||||
$heading1Size: 2.5em;
|
||||
$heading2Size: 1.6em;
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -40,7 +41,7 @@ $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b
|
||||
|
||||
// Links
|
||||
$linkColor: $blood;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
|
||||
// Text selection
|
||||
$selectionBackgroundColor: $blood;
|
||||
|
||||
107
css/theme/source/dracula.scss
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Dracula Dark theme for reveal.js.
|
||||
* Based on https://draculatheme.com
|
||||
*/
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
|
||||
// Include theme-specific fonts
|
||||
@import url(./fonts/league-gothic/league-gothic.css);
|
||||
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||
|
||||
$systemFontsSansSerif: -apple-system,
|
||||
BlinkMacSystemFont,
|
||||
avenir next,
|
||||
avenir,
|
||||
segoe ui,
|
||||
helvetica neue,
|
||||
helvetica,
|
||||
Cantarell,
|
||||
Ubuntu,
|
||||
roboto,
|
||||
noto,
|
||||
arial,
|
||||
sans-serif;
|
||||
$systemFontsMono: Menlo,
|
||||
Consolas,
|
||||
Monaco,
|
||||
Liberation Mono,
|
||||
Lucida Console,
|
||||
monospace;
|
||||
|
||||
/**
|
||||
* Dracula colors by Zeno Rocha
|
||||
* https://draculatheme.com/contribute
|
||||
*/
|
||||
html * {
|
||||
color-profile: sRGB;
|
||||
rendering-intent: auto;
|
||||
}
|
||||
|
||||
$background: #282A36;
|
||||
$foreground: #F8F8F2;
|
||||
$selection: #44475A;
|
||||
$comment: #6272A4;
|
||||
$red: #FF5555;
|
||||
$orange: #FFB86C;
|
||||
$yellow: #F1FA8C;
|
||||
$green: #50FA7B;
|
||||
$purple: #BD93F9;
|
||||
$cyan: #8BE9FD;
|
||||
$pink: #FF79C6;
|
||||
|
||||
|
||||
|
||||
// Override theme settings (see ../template/settings.scss)
|
||||
$mainColor: $foreground;
|
||||
$headingColor: $purple;
|
||||
$headingTextShadow: none;
|
||||
$headingTextTransform: none;
|
||||
$backgroundColor: $background;
|
||||
$linkColor: $pink;
|
||||
$linkColorHover: $cyan;
|
||||
$selectionBackgroundColor: $selection;
|
||||
$inlineCodeColor: $green;
|
||||
$listBulletColor: $cyan;
|
||||
|
||||
$mainFont: $systemFontsSansSerif;
|
||||
$codeFont: "Fira Code", $systemFontsMono;
|
||||
|
||||
// Change text colors against light slide backgrounds
|
||||
@include light-bg-text-color($background);
|
||||
|
||||
// Theme template ------------------------------
|
||||
@import "../template/theme";
|
||||
// ---------------------------------------------
|
||||
|
||||
// Define additional color effects based on Dracula spec
|
||||
// https://spec.draculatheme.com/
|
||||
:root {
|
||||
--r-bold-color: #{$orange};
|
||||
--r-italic-color: #{$yellow};
|
||||
--r-inline-code-color: #{$inlineCodeColor};
|
||||
--r-list-bullet-color: #{$listBulletColor};
|
||||
}
|
||||
|
||||
.reveal {
|
||||
strong, b {
|
||||
color: var(--r-bold-color);
|
||||
}
|
||||
em, i, blockquote {
|
||||
color: var(--r-italic-color);
|
||||
}
|
||||
code {
|
||||
color: var(--r-inline-code-color);
|
||||
}
|
||||
// Dracula colored list bullets and numbers
|
||||
ul, ol {
|
||||
li::marker {
|
||||
color: var(--r-list-bullet-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -18,10 +19,6 @@
|
||||
/**
|
||||
* Solarized colors by Ethan Schoonover
|
||||
*/
|
||||
html * {
|
||||
color-profile: sRGB;
|
||||
rendering-intent: auto;
|
||||
}
|
||||
|
||||
// Solarized colors
|
||||
$base03: #002b36;
|
||||
@@ -47,7 +44,7 @@ $headingColor: $base2;
|
||||
$headingTextShadow: none;
|
||||
$backgroundColor: $base03;
|
||||
$linkColor: $blue;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: $magenta;
|
||||
|
||||
// Change text colors against light slide backgrounds
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -21,7 +22,7 @@ $backgroundColor: #111;
|
||||
|
||||
$mainFont: 'Open Sans', sans-serif;
|
||||
$linkColor: #e7ad52;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$headingFont: 'Montserrat', Impact, sans-serif;
|
||||
$headingTextShadow: none;
|
||||
$headingLetterSpacing: -0.03em;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -22,9 +23,12 @@ $headingTextShadow: none;
|
||||
$headingTextTransform: none;
|
||||
$backgroundColor: #F0F1EB;
|
||||
$linkColor: #51483D;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: #26351C;
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
.reveal a {
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -28,9 +29,12 @@ $headingTextShadow: none;
|
||||
$headingTextTransform: none;
|
||||
$backgroundColor: #fff;
|
||||
$linkColor: #00008B;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Change text colors against dark slide backgrounds
|
||||
@include dark-bg-text-color(#fff);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -26,9 +27,12 @@ $headingLetterSpacing: -0.08em;
|
||||
$headingTextShadow: none;
|
||||
$backgroundColor: #f7fbfc;
|
||||
$linkColor: #3b759e;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: #134674;
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Fix links so they are not cut off
|
||||
.reveal a {
|
||||
line-height: 1.3em;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -48,9 +49,12 @@ $headingColor: $base01;
|
||||
$headingTextShadow: none;
|
||||
$backgroundColor: $base3;
|
||||
$linkColor: $blue;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
$selectionBackgroundColor: $magenta;
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Background generator
|
||||
// @mixin bodyBackground() {
|
||||
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
||||
|
||||
53
css/theme/source/white-contrast.scss
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||
*
|
||||
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||
*
|
||||
* - Keep the source similar to black.css - for easy comparison.
|
||||
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||
*/
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
|
||||
|
||||
// Include theme-specific fonts
|
||||
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||
|
||||
|
||||
// Override theme settings (see ../template/settings.scss)
|
||||
$backgroundColor: #fff;
|
||||
|
||||
$mainColor: #000;
|
||||
$headingColor: #000;
|
||||
|
||||
$mainFontSize: 42px;
|
||||
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||
$headingTextShadow: none;
|
||||
$headingLetterSpacing: normal;
|
||||
$headingTextTransform: uppercase;
|
||||
$headingFontWeight: 600;
|
||||
$linkColor: #2a76dd;
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
||||
$selectionBackgroundColor: color.scale( $linkColor, $lightness: 25% );
|
||||
|
||||
$heading1Size: 2.5em;
|
||||
$heading2Size: 1.6em;
|
||||
$heading3Size: 1.3em;
|
||||
$heading4Size: 1.0em;
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Change text colors against dark slide backgrounds
|
||||
@include dark-bg-text-color(#fff);
|
||||
|
||||
|
||||
// Theme template ------------------------------
|
||||
@import "../template/theme";
|
||||
// ---------------------------------------------
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
// Default mixins and settings -----------------
|
||||
@use "sass:color";
|
||||
@import "../template/mixins";
|
||||
@import "../template/settings";
|
||||
// ---------------------------------------------
|
||||
@@ -29,14 +30,17 @@ $headingLetterSpacing: normal;
|
||||
$headingTextTransform: uppercase;
|
||||
$headingFontWeight: 600;
|
||||
$linkColor: #2a76dd;
|
||||
$linkColorHover: lighten( $linkColor, 15% );
|
||||
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
||||
$selectionBackgroundColor: color.scale( $linkColor, $lightness: 25% );
|
||||
|
||||
$heading1Size: 2.5em;
|
||||
$heading2Size: 1.6em;
|
||||
$heading3Size: 1.3em;
|
||||
$heading4Size: 1.0em;
|
||||
|
||||
$overlayElementBgColor: 0, 0, 0;
|
||||
$overlayElementFgColor: 240, 240, 240;
|
||||
|
||||
// Change text colors against dark slide backgrounds
|
||||
@include dark-bg-text-color(#fff);
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Exposes theme's variables for easy re-use in CSS for plugin authors
|
||||
// Exposes theme's variables for easy reuse in CSS for plugin authors
|
||||
|
||||
@use "sass:color";
|
||||
|
||||
:root {
|
||||
--r-background-color: #{$backgroundColor};
|
||||
@@ -21,8 +23,10 @@
|
||||
--r-heading4-size: #{$heading4Size};
|
||||
--r-code-font: #{$codeFont};
|
||||
--r-link-color: #{$linkColor};
|
||||
--r-link-color-dark: #{darken($linkColor , 15% )};
|
||||
--r-link-color-dark: #{color.scale( $linkColor, $lightness: -15% )};
|
||||
--r-link-color-hover: #{$linkColorHover};
|
||||
--r-selection-background-color: #{$selectionBackgroundColor};
|
||||
--r-selection-color: #{$selectionColor};
|
||||
--r-overlay-element-bg-color: #{$overlayElementBgColor};
|
||||
--r-overlay-element-fg-color: #{$overlayElementFgColor};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use "sass:color";
|
||||
|
||||
// Base settings for all themes that can optionally be
|
||||
// overridden by the super-theme
|
||||
|
||||
@@ -32,12 +34,17 @@ $codeFont: monospace;
|
||||
|
||||
// Links and actions
|
||||
$linkColor: #13DAEC;
|
||||
$linkColorHover: lighten( $linkColor, 20% );
|
||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
||||
|
||||
// Text selection
|
||||
$selectionBackgroundColor: #FF5E99;
|
||||
$selectionColor: #fff;
|
||||
|
||||
// Colors used for UI elements that are overlaid on top of
|
||||
// the presentation
|
||||
$overlayElementBgColor: 240, 240, 240;
|
||||
$overlayElementFgColor: 0, 0, 0;
|
||||
|
||||
// Generates the presentation background, can be overridden
|
||||
// to return a background image or gradient
|
||||
@mixin bodyBackground() {
|
||||
|
||||
@@ -278,8 +278,7 @@
|
||||
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
// background: darken( var(--r-link-color), 15% );
|
||||
background: var(--r-link-color-dark);
|
||||
background: var(--r-link-color-dark);
|
||||
|
||||
}
|
||||
|
||||
|
||||
57
demo.html
@@ -86,7 +86,7 @@
|
||||
|
||||
<section data-auto-animate>
|
||||
<h2 data-id="code-title">Pretty Code</h2>
|
||||
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
|
||||
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers>
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function Example() {
|
||||
@@ -101,8 +101,8 @@
|
||||
</section>
|
||||
|
||||
<section data-auto-animate>
|
||||
<h2 data-id="code-title">With animations</h2>
|
||||
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||
<h2 data-id="code-title">With Animations</h2>
|
||||
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function Example() {
|
||||
@@ -165,9 +165,9 @@
|
||||
</section>
|
||||
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||
<div class="r-stack">
|
||||
<div data-id="box1" style="background: cyan; width: 300px; height: 300px; border-radius: 200px;"></div>
|
||||
<div data-id="box2" style="background: magenta; width: 200px; height: 200px; border-radius: 200px;"></div>
|
||||
<div data-id="box3" style="background: yellow; width: 100px; height: 100px; border-radius: 200px;"></div>
|
||||
<div data-id="box1" style="background: cyan; width: 300px; height: 300px;"></div>
|
||||
<div data-id="box2" style="background: magenta; width: 200px; height: 200px;"></div>
|
||||
<div data-id="box3" style="background: yellow; width: 100px; height: 100px;"></div>
|
||||
</div>
|
||||
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||
</section>
|
||||
@@ -181,14 +181,14 @@
|
||||
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||
## Markdown support
|
||||
## Markdown Support
|
||||
|
||||
Write content using inline or external Markdown.
|
||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||
|
||||
```html []
|
||||
<section data-markdown>
|
||||
## Markdown support
|
||||
## Markdown Support
|
||||
|
||||
Write content using inline or external Markdown.
|
||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||
@@ -197,6 +197,25 @@
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Lightbox</h2>
|
||||
Turn any element into a <a href="https://revealjs.com/lightbox/">lightbox</a> using <strong>data‑preview‑image</strong> & <strong>data‑preview‑video</strong>.
|
||||
<div class="r-hstack" style="gap: 2rem;">
|
||||
<div>
|
||||
<pre style="font-size: 12px; width: 100%"><code class="html" data-trim>
|
||||
<img src="image.png" data-preview-image="image.png">
|
||||
</code></pre>
|
||||
<img src="https://static.slid.es/logo/v2/slides-symbol-1024x1024.png" height="100" data-preview-image>
|
||||
</div>
|
||||
<div>
|
||||
<pre style="font-size: 12px; width: 100%"><code class="html" data-trim>
|
||||
<img src="video.png" data-preview-video="video.mp4">
|
||||
</code></pre>
|
||||
<img src="https://static.slid.es/site/homepage/v1/homepage-video-editor.png" height="100" data-preview-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Add the <code>r-fit-text</code> class to auto-size text</p>
|
||||
<h2 class="r-fit-text">FIT TEXT</h2>
|
||||
@@ -249,17 +268,17 @@
|
||||
<p>
|
||||
reveal.js comes with a few themes built in: <br>
|
||||
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/black.css'); return false;">Black (default)</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/white.css'); return false;">White</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/league.css'); return false;">League</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/sky.css'); return false;">Sky</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/beige.css'); return false;">Beige</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/simple.css'); return false;">Simple</a> <br>
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/serif.css'); return false;">Serif</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/blood.css'); return false;">Blood</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/night.css'); return false;">Night</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/moon.css'); return false;">Moon</a> -
|
||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/black.css'); return false;">Black (default)</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/white.css'); return false;">White</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/league.css'); return false;">League</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/sky.css'); return false;">Sky</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/beige.css'); return false;">Beige</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/simple.css'); return false;">Simple</a> <br>
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/serif.css'); return false;">Serif</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/blood.css'); return false;">Blood</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/night.css'); return false;">Night</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/moon.css'); return false;">Moon</a> -
|
||||
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
||||
17
dist/reveal.css
vendored
14
dist/reveal.esm.js
vendored
2
dist/reveal.esm.js.map
vendored
14
dist/reveal.js
vendored
2
dist/reveal.js.map
vendored
20
dist/theme/beige.css
vendored
@@ -33,20 +33,22 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #8b743d;
|
||||
--r-link-color-dark: #564826;
|
||||
--r-link-color-hover: #c0a86e;
|
||||
--r-link-color-dark: rgb(118.15, 98.6, 51.85);
|
||||
--r-link-color-hover: rgb(179.36, 150.84, 82.64);
|
||||
--r-selection-background-color: rgba(79, 64, 28, 0.99);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #f7f2d3;
|
||||
background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
|
||||
background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||
background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||
background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||
background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||
background: rgb(247, 242, 211);
|
||||
background: -moz-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgb(255, 255, 255)), color-stop(100%, rgb(247, 242, 211)));
|
||||
background: -webkit-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||
background: -o-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||
background: -ms-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||
background: radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
|
||||
362
dist/theme/black-contrast.css
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* Black compact & high contrast reveal.js theme, with headers not in capitals.
|
||||
*
|
||||
* By Peter Kehl. Based on black.(s)css by Hakim El Hattab, http://hakim.se
|
||||
*
|
||||
* - Keep the source similar to black.css - for easy comparison.
|
||||
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||
*/
|
||||
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* GLOBAL STYLES
|
||||
*********************************************/
|
||||
:root {
|
||||
--r-background-color: #000000;
|
||||
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-main-font-size: 42px;
|
||||
--r-main-color: #fff;
|
||||
--r-block-margin: 20px;
|
||||
--r-heading-margin: 0 0 20px 0;
|
||||
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-heading-color: #fff;
|
||||
--r-heading-line-height: 1.2;
|
||||
--r-heading-letter-spacing: normal;
|
||||
--r-heading-text-transform: uppercase;
|
||||
--r-heading-text-shadow: none;
|
||||
--r-heading-font-weight: 600;
|
||||
--r-heading1-text-shadow: none;
|
||||
--r-heading1-size: 2.5em;
|
||||
--r-heading2-size: 1.6em;
|
||||
--r-heading3-size: 1.3em;
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #42affa;
|
||||
--r-link-color-dark: rgb(19.8216494845, 155.4536082474, 248.7783505155);
|
||||
--r-link-color-hover: rgb(94.35, 187, 250.75);
|
||||
--r-selection-background-color: rgb(113.25, 195, 251.25);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #000000;
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
.reveal {
|
||||
font-family: var(--r-main-font);
|
||||
font-size: var(--r-main-font-size);
|
||||
font-weight: normal;
|
||||
color: var(--r-main-color);
|
||||
}
|
||||
|
||||
.reveal ::selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal ::-moz-selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal .slides section,
|
||||
.reveal .slides section > section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
.reveal h1,
|
||||
.reveal h2,
|
||||
.reveal h3,
|
||||
.reveal h4,
|
||||
.reveal h5,
|
||||
.reveal h6 {
|
||||
margin: var(--r-heading-margin);
|
||||
color: var(--r-heading-color);
|
||||
font-family: var(--r-heading-font);
|
||||
font-weight: var(--r-heading-font-weight);
|
||||
line-height: var(--r-heading-line-height);
|
||||
letter-spacing: var(--r-heading-letter-spacing);
|
||||
text-transform: var(--r-heading-text-transform);
|
||||
text-shadow: var(--r-heading-text-shadow);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
font-size: var(--r-heading1-size);
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
font-size: var(--r-heading2-size);
|
||||
}
|
||||
|
||||
.reveal h3 {
|
||||
font-size: var(--r-heading3-size);
|
||||
}
|
||||
|
||||
.reveal h4 {
|
||||
font-size: var(--r-heading4-size);
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
text-shadow: var(--r-heading1-text-shadow);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
.reveal p {
|
||||
margin: var(--r-block-margin) 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Remove trailing margins after titles */
|
||||
.reveal h1:last-child,
|
||||
.reveal h2:last-child,
|
||||
.reveal h3:last-child,
|
||||
.reveal h4:last-child,
|
||||
.reveal h5:last-child,
|
||||
.reveal h6:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
.reveal img,
|
||||
.reveal video,
|
||||
.reveal iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.reveal strong,
|
||||
.reveal b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal ol,
|
||||
.reveal dl,
|
||||
.reveal ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.reveal ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.reveal ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.reveal ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.reveal ul ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.reveal ul ul,
|
||||
.reveal ul ol,
|
||||
.reveal ol ol,
|
||||
.reveal ol ul {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.reveal blockquote p:first-child,
|
||||
.reveal blockquote p:last-child {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.reveal q {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
text-align: left;
|
||||
font-size: 0.55em;
|
||||
font-family: var(--r-code-font);
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal code {
|
||||
font-family: var(--r-code-font);
|
||||
text-transform: none;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.reveal pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper code {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.reveal table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.reveal table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal table th,
|
||||
.reveal table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.reveal table th[align=center],
|
||||
.reveal table td[align=center] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reveal table th[align=right],
|
||||
.reveal table td[align=right] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reveal table tbody tr:last-child th,
|
||||
.reveal table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reveal sup {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal sub {
|
||||
vertical-align: sub;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal small * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal img {
|
||||
margin: var(--r-block-margin) 0;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
.reveal a {
|
||||
color: var(--r-link-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.reveal a:hover {
|
||||
color: var(--r-link-color-hover);
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
background: var(--r-link-color-dark);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Frame helper
|
||||
*********************************************/
|
||||
.reveal .r-frame {
|
||||
border: 4px solid var(--r-main-color);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal a .r-frame {
|
||||
transition: all 0.15s linear;
|
||||
}
|
||||
|
||||
.reveal a:hover .r-frame {
|
||||
border-color: var(--r-link-color);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* NAVIGATION CONTROLS
|
||||
*********************************************/
|
||||
.reveal .controls {
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
.reveal .progress {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PRINT BACKGROUND
|
||||
*********************************************/
|
||||
@media print {
|
||||
.backgrounds {
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
}
|
||||
8
dist/theme/black.css
vendored
@@ -32,10 +32,12 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #42affa;
|
||||
--r-link-color-dark: #068de9;
|
||||
--r-link-color-hover: #8dcffc;
|
||||
--r-selection-background-color: #bee4fd;
|
||||
--r-link-color-dark: rgb(19.8216494845, 155.4536082474, 248.7783505155);
|
||||
--r-link-color-hover: rgb(94.35, 187, 250.75);
|
||||
--r-selection-background-color: rgba(66, 175, 250, 0.75);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/blood.css
vendored
@@ -38,10 +38,12 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #a23;
|
||||
--r-link-color-dark: #6a1520;
|
||||
--r-link-color-hover: #dd5566;
|
||||
--r-link-color-dark: rgb(144.5, 28.9, 43.35);
|
||||
--r-link-color-hover: rgb(214.2, 51, 71.4);
|
||||
--r-selection-background-color: #a23;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
387
dist/theme/dracula.css
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
/**
|
||||
* Dracula Dark theme for reveal.js.
|
||||
* Based on https://draculatheme.com
|
||||
*/
|
||||
@import url(./fonts/league-gothic/league-gothic.css);
|
||||
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||
/**
|
||||
* Dracula colors by Zeno Rocha
|
||||
* https://draculatheme.com/contribute
|
||||
*/
|
||||
html * {
|
||||
color-profile: sRGB;
|
||||
rendering-intent: auto;
|
||||
}
|
||||
|
||||
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||
color: #282A36;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* GLOBAL STYLES
|
||||
*********************************************/
|
||||
:root {
|
||||
--r-background-color: #282A36;
|
||||
--r-main-font: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
|
||||
--r-main-font-size: 40px;
|
||||
--r-main-color: #F8F8F2;
|
||||
--r-block-margin: 20px;
|
||||
--r-heading-margin: 0 0 20px 0;
|
||||
--r-heading-font: League Gothic, Impact, sans-serif;
|
||||
--r-heading-color: #BD93F9;
|
||||
--r-heading-line-height: 1.2;
|
||||
--r-heading-letter-spacing: normal;
|
||||
--r-heading-text-transform: none;
|
||||
--r-heading-text-shadow: none;
|
||||
--r-heading-font-weight: normal;
|
||||
--r-heading1-text-shadow: none;
|
||||
--r-heading1-size: 3.77em;
|
||||
--r-heading2-size: 2.11em;
|
||||
--r-heading3-size: 1.55em;
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: Fira Code, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
|
||||
--r-link-color: #FF79C6;
|
||||
--r-link-color-dark: rgb(255, 64.6, 174.0089552239);
|
||||
--r-link-color-hover: #8BE9FD;
|
||||
--r-selection-background-color: #44475A;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #282A36;
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
.reveal {
|
||||
font-family: var(--r-main-font);
|
||||
font-size: var(--r-main-font-size);
|
||||
font-weight: normal;
|
||||
color: var(--r-main-color);
|
||||
}
|
||||
|
||||
.reveal ::selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal ::-moz-selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal .slides section,
|
||||
.reveal .slides section > section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
.reveal h1,
|
||||
.reveal h2,
|
||||
.reveal h3,
|
||||
.reveal h4,
|
||||
.reveal h5,
|
||||
.reveal h6 {
|
||||
margin: var(--r-heading-margin);
|
||||
color: var(--r-heading-color);
|
||||
font-family: var(--r-heading-font);
|
||||
font-weight: var(--r-heading-font-weight);
|
||||
line-height: var(--r-heading-line-height);
|
||||
letter-spacing: var(--r-heading-letter-spacing);
|
||||
text-transform: var(--r-heading-text-transform);
|
||||
text-shadow: var(--r-heading-text-shadow);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
font-size: var(--r-heading1-size);
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
font-size: var(--r-heading2-size);
|
||||
}
|
||||
|
||||
.reveal h3 {
|
||||
font-size: var(--r-heading3-size);
|
||||
}
|
||||
|
||||
.reveal h4 {
|
||||
font-size: var(--r-heading4-size);
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
text-shadow: var(--r-heading1-text-shadow);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
.reveal p {
|
||||
margin: var(--r-block-margin) 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Remove trailing margins after titles */
|
||||
.reveal h1:last-child,
|
||||
.reveal h2:last-child,
|
||||
.reveal h3:last-child,
|
||||
.reveal h4:last-child,
|
||||
.reveal h5:last-child,
|
||||
.reveal h6:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
.reveal img,
|
||||
.reveal video,
|
||||
.reveal iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.reveal strong,
|
||||
.reveal b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal ol,
|
||||
.reveal dl,
|
||||
.reveal ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.reveal ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.reveal ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.reveal ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.reveal ul ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.reveal ul ul,
|
||||
.reveal ul ol,
|
||||
.reveal ol ol,
|
||||
.reveal ol ul {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.reveal blockquote p:first-child,
|
||||
.reveal blockquote p:last-child {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.reveal q {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
text-align: left;
|
||||
font-size: 0.55em;
|
||||
font-family: var(--r-code-font);
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal code {
|
||||
font-family: var(--r-code-font);
|
||||
text-transform: none;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.reveal pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper code {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.reveal table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.reveal table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal table th,
|
||||
.reveal table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.reveal table th[align=center],
|
||||
.reveal table td[align=center] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reveal table th[align=right],
|
||||
.reveal table td[align=right] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reveal table tbody tr:last-child th,
|
||||
.reveal table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reveal sup {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal sub {
|
||||
vertical-align: sub;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal small * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal img {
|
||||
margin: var(--r-block-margin) 0;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
.reveal a {
|
||||
color: var(--r-link-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.reveal a:hover {
|
||||
color: var(--r-link-color-hover);
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
background: var(--r-link-color-dark);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Frame helper
|
||||
*********************************************/
|
||||
.reveal .r-frame {
|
||||
border: 4px solid var(--r-main-color);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal a .r-frame {
|
||||
transition: all 0.15s linear;
|
||||
}
|
||||
|
||||
.reveal a:hover .r-frame {
|
||||
border-color: var(--r-link-color);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* NAVIGATION CONTROLS
|
||||
*********************************************/
|
||||
.reveal .controls {
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
.reveal .progress {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PRINT BACKGROUND
|
||||
*********************************************/
|
||||
@media print {
|
||||
.backgrounds {
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
}
|
||||
:root {
|
||||
--r-bold-color: #FFB86C;
|
||||
--r-italic-color: #F1FA8C;
|
||||
--r-inline-code-color: #50FA7B;
|
||||
--r-list-bullet-color: #8BE9FD;
|
||||
}
|
||||
|
||||
.reveal strong, .reveal b {
|
||||
color: var(--r-bold-color);
|
||||
}
|
||||
.reveal em, .reveal i, .reveal blockquote {
|
||||
color: var(--r-italic-color);
|
||||
}
|
||||
.reveal code {
|
||||
color: var(--r-inline-code-color);
|
||||
}
|
||||
.reveal ul li::marker, .reveal ol li::marker {
|
||||
color: var(--r-list-bullet-color);
|
||||
}
|
||||
20
dist/theme/league.css
vendored
@@ -35,20 +35,22 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #13DAEC;
|
||||
--r-link-color-dark: #0d99a5;
|
||||
--r-link-color-hover: #71e9f4;
|
||||
--r-link-color-dark: rgb(16.15, 185.3, 200.6);
|
||||
--r-link-color-hover: rgb(66.2, 225.4, 239.8);
|
||||
--r-selection-background-color: #FF5E99;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #1c1e20;
|
||||
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
|
||||
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||
background: rgb(28, 30, 32);
|
||||
background: -moz-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgb(85, 90, 95)), color-stop(100%, rgb(28, 30, 32)));
|
||||
background: -webkit-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||
background: -o-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||
background: -ms-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||
background: radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
|
||||
11
dist/theme/moon.css
vendored
@@ -7,11 +7,6 @@
|
||||
/**
|
||||
* Solarized colors by Ethan Schoonover
|
||||
*/
|
||||
html * {
|
||||
color-profile: sRGB;
|
||||
rendering-intent: auto;
|
||||
}
|
||||
|
||||
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||
color: #222;
|
||||
}
|
||||
@@ -40,10 +35,12 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #268bd2;
|
||||
--r-link-color-dark: #1a6091;
|
||||
--r-link-color-hover: #78b9e6;
|
||||
--r-link-color-dark: rgb(32.3, 118.15, 178.5);
|
||||
--r-link-color-hover: rgb(77.5161290323, 162.8774193548, 222.8838709677);
|
||||
--r-selection-background-color: #d33682;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/night.css
vendored
@@ -33,10 +33,12 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #e7ad52;
|
||||
--r-link-color-dark: #d08a1d;
|
||||
--r-link-color-hover: #f3d7ac;
|
||||
--r-link-color-dark: rgb(225.2802030457, 153.4573604061, 40.7697969543);
|
||||
--r-link-color-hover: rgb(235.8, 189.4, 116.6);
|
||||
--r-selection-background-color: #e7ad52;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 240, 240, 240;
|
||||
--r-overlay-element-fg-color: 0, 0, 0;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/serif.css
vendored
@@ -36,10 +36,12 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #51483D;
|
||||
--r-link-color-dark: #25211c;
|
||||
--r-link-color-hover: #8b7c69;
|
||||
--r-link-color-dark: rgb(68.85, 61.2, 51.85);
|
||||
--r-link-color-hover: rgb(122.9830985915, 109.3183098592, 92.6169014085);
|
||||
--r-selection-background-color: #26351C;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/simple.css
vendored
@@ -35,10 +35,12 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #00008B;
|
||||
--r-link-color-dark: #00003f;
|
||||
--r-link-color-hover: #0000f1;
|
||||
--r-link-color-dark: rgb(0, 0, 118.15);
|
||||
--r-link-color-hover: rgb(0, 0, 213.2);
|
||||
--r-selection-background-color: rgba(0, 0, 0, 0.99);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/sky.css
vendored
@@ -37,10 +37,12 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #3b759e;
|
||||
--r-link-color-dark: #264c66;
|
||||
--r-link-color-hover: #74a7cb;
|
||||
--r-link-color-dark: rgb(50.15, 99.45, 134.3);
|
||||
--r-link-color-hover: rgb(84.330875576, 146.9815668203, 191.269124424);
|
||||
--r-selection-background-color: #134674;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
6
dist/theme/solarized.css
vendored
@@ -36,10 +36,12 @@ html * {
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #268bd2;
|
||||
--r-link-color-dark: #1a6091;
|
||||
--r-link-color-hover: #78b9e6;
|
||||
--r-link-color-dark: rgb(32.3, 118.15, 178.5);
|
||||
--r-link-color-hover: rgb(77.5161290323, 162.8774193548, 222.8838709677);
|
||||
--r-selection-background-color: #d33682;
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
362
dist/theme/white-contrast.css
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||
*
|
||||
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||
*
|
||||
* - Keep the source similar to black.css - for easy comparison.
|
||||
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||
*/
|
||||
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* GLOBAL STYLES
|
||||
*********************************************/
|
||||
:root {
|
||||
--r-background-color: #fff;
|
||||
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-main-font-size: 42px;
|
||||
--r-main-color: #000;
|
||||
--r-block-margin: 20px;
|
||||
--r-heading-margin: 0 0 20px 0;
|
||||
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-heading-color: #000;
|
||||
--r-heading-line-height: 1.2;
|
||||
--r-heading-letter-spacing: normal;
|
||||
--r-heading-text-transform: uppercase;
|
||||
--r-heading-text-shadow: none;
|
||||
--r-heading-font-weight: 600;
|
||||
--r-heading1-text-shadow: none;
|
||||
--r-heading1-size: 2.5em;
|
||||
--r-heading2-size: 1.6em;
|
||||
--r-heading3-size: 1.3em;
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #2a76dd;
|
||||
--r-link-color-dark: rgb(30.7720647773, 99.5566801619, 192.7779352227);
|
||||
--r-link-color-hover: rgb(73.95, 138.55, 226.1);
|
||||
--r-selection-background-color: rgb(95.25, 152.25, 229.5);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #fff;
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
.reveal {
|
||||
font-family: var(--r-main-font);
|
||||
font-size: var(--r-main-font-size);
|
||||
font-weight: normal;
|
||||
color: var(--r-main-color);
|
||||
}
|
||||
|
||||
.reveal ::selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal ::-moz-selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal .slides section,
|
||||
.reveal .slides section > section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
.reveal h1,
|
||||
.reveal h2,
|
||||
.reveal h3,
|
||||
.reveal h4,
|
||||
.reveal h5,
|
||||
.reveal h6 {
|
||||
margin: var(--r-heading-margin);
|
||||
color: var(--r-heading-color);
|
||||
font-family: var(--r-heading-font);
|
||||
font-weight: var(--r-heading-font-weight);
|
||||
line-height: var(--r-heading-line-height);
|
||||
letter-spacing: var(--r-heading-letter-spacing);
|
||||
text-transform: var(--r-heading-text-transform);
|
||||
text-shadow: var(--r-heading-text-shadow);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
font-size: var(--r-heading1-size);
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
font-size: var(--r-heading2-size);
|
||||
}
|
||||
|
||||
.reveal h3 {
|
||||
font-size: var(--r-heading3-size);
|
||||
}
|
||||
|
||||
.reveal h4 {
|
||||
font-size: var(--r-heading4-size);
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
text-shadow: var(--r-heading1-text-shadow);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
.reveal p {
|
||||
margin: var(--r-block-margin) 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Remove trailing margins after titles */
|
||||
.reveal h1:last-child,
|
||||
.reveal h2:last-child,
|
||||
.reveal h3:last-child,
|
||||
.reveal h4:last-child,
|
||||
.reveal h5:last-child,
|
||||
.reveal h6:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
.reveal img,
|
||||
.reveal video,
|
||||
.reveal iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.reveal strong,
|
||||
.reveal b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal ol,
|
||||
.reveal dl,
|
||||
.reveal ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.reveal ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.reveal ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.reveal ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.reveal ul ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.reveal ul ul,
|
||||
.reveal ul ol,
|
||||
.reveal ol ol,
|
||||
.reveal ol ul {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.reveal blockquote p:first-child,
|
||||
.reveal blockquote p:last-child {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.reveal q {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
text-align: left;
|
||||
font-size: 0.55em;
|
||||
font-family: var(--r-code-font);
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal code {
|
||||
font-family: var(--r-code-font);
|
||||
text-transform: none;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.reveal pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper code {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.reveal table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.reveal table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal table th,
|
||||
.reveal table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.reveal table th[align=center],
|
||||
.reveal table td[align=center] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reveal table th[align=right],
|
||||
.reveal table td[align=right] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reveal table tbody tr:last-child th,
|
||||
.reveal table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reveal sup {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal sub {
|
||||
vertical-align: sub;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal small * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal img {
|
||||
margin: var(--r-block-margin) 0;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
.reveal a {
|
||||
color: var(--r-link-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.reveal a:hover {
|
||||
color: var(--r-link-color-hover);
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
background: var(--r-link-color-dark);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Frame helper
|
||||
*********************************************/
|
||||
.reveal .r-frame {
|
||||
border: 4px solid var(--r-main-color);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal a .r-frame {
|
||||
transition: all 0.15s linear;
|
||||
}
|
||||
|
||||
.reveal a:hover .r-frame {
|
||||
border-color: var(--r-link-color);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* NAVIGATION CONTROLS
|
||||
*********************************************/
|
||||
.reveal .controls {
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
.reveal .progress {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PRINT BACKGROUND
|
||||
*********************************************/
|
||||
@media print {
|
||||
.backgrounds {
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
}
|
||||
8
dist/theme/white.css
vendored
@@ -32,10 +32,12 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #2a76dd;
|
||||
--r-link-color-dark: #1a53a1;
|
||||
--r-link-color-hover: #6ca0e8;
|
||||
--r-selection-background-color: #98bdef;
|
||||
--r-link-color-dark: rgb(30.7720647773, 99.5566801619, 192.7779352227);
|
||||
--r-link-color-hover: rgb(73.95, 138.55, 226.1);
|
||||
--r-selection-background-color: rgb(95.25, 152.25, 229.5);
|
||||
--r-selection-color: #fff;
|
||||
--r-overlay-element-bg-color: 0, 0, 0;
|
||||
--r-overlay-element-fg-color: 240, 240, 240;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
|
||||
360
dist/theme/white_contrast_compact_verbatim_headers.css
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||
*
|
||||
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||
*
|
||||
* - Keep the source similar to black.css - for easy comparison.
|
||||
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||
*/
|
||||
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* GLOBAL STYLES
|
||||
*********************************************/
|
||||
:root {
|
||||
--r-background-color: #fff;
|
||||
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-main-font-size: 25px;
|
||||
--r-main-color: #000;
|
||||
--r-block-margin: 20px;
|
||||
--r-heading-margin: 0 0 20px 0;
|
||||
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||
--r-heading-color: #000;
|
||||
--r-heading-line-height: 1.2;
|
||||
--r-heading-letter-spacing: normal;
|
||||
--r-heading-text-transform: none;
|
||||
--r-heading-text-shadow: none;
|
||||
--r-heading-font-weight: 450;
|
||||
--r-heading1-text-shadow: none;
|
||||
--r-heading1-size: 2.5em;
|
||||
--r-heading2-size: 1.6em;
|
||||
--r-heading3-size: 1.3em;
|
||||
--r-heading4-size: 1em;
|
||||
--r-code-font: monospace;
|
||||
--r-link-color: #2a76dd;
|
||||
--r-link-color-dark: #1a53a1;
|
||||
--r-link-color-hover: #6ca0e8;
|
||||
--r-selection-background-color: #98bdef;
|
||||
--r-selection-color: #fff;
|
||||
}
|
||||
|
||||
.reveal-viewport {
|
||||
background: #fff;
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
|
||||
.reveal {
|
||||
font-family: var(--r-main-font);
|
||||
font-size: var(--r-main-font-size);
|
||||
font-weight: normal;
|
||||
color: var(--r-main-color);
|
||||
}
|
||||
|
||||
.reveal ::selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal ::-moz-selection {
|
||||
color: var(--r-selection-color);
|
||||
background: var(--r-selection-background-color);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.reveal .slides section,
|
||||
.reveal .slides section > section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
.reveal h1,
|
||||
.reveal h2,
|
||||
.reveal h3,
|
||||
.reveal h4,
|
||||
.reveal h5,
|
||||
.reveal h6 {
|
||||
margin: var(--r-heading-margin);
|
||||
color: var(--r-heading-color);
|
||||
font-family: var(--r-heading-font);
|
||||
font-weight: var(--r-heading-font-weight);
|
||||
line-height: var(--r-heading-line-height);
|
||||
letter-spacing: var(--r-heading-letter-spacing);
|
||||
text-transform: var(--r-heading-text-transform);
|
||||
text-shadow: var(--r-heading-text-shadow);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
font-size: var(--r-heading1-size);
|
||||
}
|
||||
|
||||
.reveal h2 {
|
||||
font-size: var(--r-heading2-size);
|
||||
}
|
||||
|
||||
.reveal h3 {
|
||||
font-size: var(--r-heading3-size);
|
||||
}
|
||||
|
||||
.reveal h4 {
|
||||
font-size: var(--r-heading4-size);
|
||||
}
|
||||
|
||||
.reveal h1 {
|
||||
text-shadow: var(--r-heading1-text-shadow);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
.reveal p {
|
||||
margin: var(--r-block-margin) 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Remove trailing margins after titles */
|
||||
.reveal h1:last-child,
|
||||
.reveal h2:last-child,
|
||||
.reveal h3:last-child,
|
||||
.reveal h4:last-child,
|
||||
.reveal h5:last-child,
|
||||
.reveal h6:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
.reveal img,
|
||||
.reveal video,
|
||||
.reveal iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.reveal strong,
|
||||
.reveal b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal ol,
|
||||
.reveal dl,
|
||||
.reveal ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.reveal ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.reveal ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.reveal ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.reveal ul ul ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.reveal ul ul,
|
||||
.reveal ul ol,
|
||||
.reveal ol ol,
|
||||
.reveal ol ul {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal dd {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.reveal blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.reveal blockquote p:first-child,
|
||||
.reveal blockquote p:last-child {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.reveal q {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reveal pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: var(--r-block-margin) auto;
|
||||
text-align: left;
|
||||
font-size: 0.55em;
|
||||
font-family: var(--r-code-font);
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal code {
|
||||
font-family: var(--r-code-font);
|
||||
text-transform: none;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.reveal pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.reveal .code-wrapper code {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.reveal table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.reveal table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.reveal table th,
|
||||
.reveal table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.reveal table th[align=center],
|
||||
.reveal table td[align=center] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reveal table th[align=right],
|
||||
.reveal table td[align=right] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.reveal table tbody tr:last-child th,
|
||||
.reveal table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reveal sup {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal sub {
|
||||
vertical-align: sub;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.reveal small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal small * {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reveal img {
|
||||
margin: var(--r-block-margin) 0;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
.reveal a {
|
||||
color: var(--r-link-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.reveal a:hover {
|
||||
color: var(--r-link-color-hover);
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reveal .roll span:after {
|
||||
color: #fff;
|
||||
background: var(--r-link-color-dark);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Frame helper
|
||||
*********************************************/
|
||||
.reveal .r-frame {
|
||||
border: 4px solid var(--r-main-color);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.reveal a .r-frame {
|
||||
transition: all 0.15s linear;
|
||||
}
|
||||
|
||||
.reveal a:hover .r-frame {
|
||||
border-color: var(--r-link-color);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* NAVIGATION CONTROLS
|
||||
*********************************************/
|
||||
.reveal .controls {
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
.reveal .progress {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: var(--r-link-color);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* PRINT BACKGROUND
|
||||
*********************************************/
|
||||
@media print {
|
||||
.backgrounds {
|
||||
background-color: var(--r-background-color);
|
||||
}
|
||||
}
|
||||
526
examples/500-slides.html
Normal file
@@ -0,0 +1,526 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - 500 slides</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<link rel="stylesheet" href="../dist/reveal.css">
|
||||
<link rel="stylesheet" href="../dist/theme/black.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="reveal">
|
||||
<div class="slides">
|
||||
<section><h1>1</h1></section>
|
||||
<section><h1>2</h1></section>
|
||||
<section><h1>3</h1></section>
|
||||
<section><h1>4</h1></section>
|
||||
<section><h1>5</h1></section>
|
||||
<section><h1>6</h1></section>
|
||||
<section><h1>7</h1></section>
|
||||
<section><h1>8</h1></section>
|
||||
<section><h1>9</h1></section>
|
||||
<section><h1>10</h1></section>
|
||||
<section><h1>11</h1></section>
|
||||
<section><h1>12</h1></section>
|
||||
<section><h1>13</h1></section>
|
||||
<section><h1>14</h1></section>
|
||||
<section><h1>15</h1></section>
|
||||
<section><h1>16</h1></section>
|
||||
<section><h1>17</h1></section>
|
||||
<section><h1>18</h1></section>
|
||||
<section><h1>19</h1></section>
|
||||
<section><h1>20</h1></section>
|
||||
<section><h1>21</h1></section>
|
||||
<section><h1>22</h1></section>
|
||||
<section><h1>23</h1></section>
|
||||
<section><h1>24</h1></section>
|
||||
<section><h1>25</h1></section>
|
||||
<section><h1>26</h1></section>
|
||||
<section><h1>27</h1></section>
|
||||
<section><h1>28</h1></section>
|
||||
<section><h1>29</h1></section>
|
||||
<section><h1>30</h1></section>
|
||||
<section><h1>31</h1></section>
|
||||
<section><h1>32</h1></section>
|
||||
<section><h1>33</h1></section>
|
||||
<section><h1>34</h1></section>
|
||||
<section><h1>35</h1></section>
|
||||
<section><h1>36</h1></section>
|
||||
<section><h1>37</h1></section>
|
||||
<section><h1>38</h1></section>
|
||||
<section><h1>39</h1></section>
|
||||
<section><h1>40</h1></section>
|
||||
<section><h1>41</h1></section>
|
||||
<section><h1>42</h1></section>
|
||||
<section><h1>43</h1></section>
|
||||
<section><h1>44</h1></section>
|
||||
<section><h1>45</h1></section>
|
||||
<section><h1>46</h1></section>
|
||||
<section><h1>47</h1></section>
|
||||
<section><h1>48</h1></section>
|
||||
<section><h1>49</h1></section>
|
||||
<section><h1>50</h1></section>
|
||||
<section><h1>51</h1></section>
|
||||
<section><h1>52</h1></section>
|
||||
<section><h1>53</h1></section>
|
||||
<section><h1>54</h1></section>
|
||||
<section><h1>55</h1></section>
|
||||
<section><h1>56</h1></section>
|
||||
<section><h1>57</h1></section>
|
||||
<section><h1>58</h1></section>
|
||||
<section><h1>59</h1></section>
|
||||
<section><h1>60</h1></section>
|
||||
<section><h1>61</h1></section>
|
||||
<section><h1>62</h1></section>
|
||||
<section><h1>63</h1></section>
|
||||
<section><h1>64</h1></section>
|
||||
<section><h1>65</h1></section>
|
||||
<section><h1>66</h1></section>
|
||||
<section><h1>67</h1></section>
|
||||
<section><h1>68</h1></section>
|
||||
<section><h1>69</h1></section>
|
||||
<section><h1>70</h1></section>
|
||||
<section><h1>71</h1></section>
|
||||
<section><h1>72</h1></section>
|
||||
<section><h1>73</h1></section>
|
||||
<section><h1>74</h1></section>
|
||||
<section><h1>75</h1></section>
|
||||
<section><h1>76</h1></section>
|
||||
<section><h1>77</h1></section>
|
||||
<section><h1>78</h1></section>
|
||||
<section><h1>79</h1></section>
|
||||
<section><h1>80</h1></section>
|
||||
<section><h1>81</h1></section>
|
||||
<section><h1>82</h1></section>
|
||||
<section><h1>83</h1></section>
|
||||
<section><h1>84</h1></section>
|
||||
<section><h1>85</h1></section>
|
||||
<section><h1>86</h1></section>
|
||||
<section><h1>87</h1></section>
|
||||
<section><h1>88</h1></section>
|
||||
<section><h1>89</h1></section>
|
||||
<section><h1>90</h1></section>
|
||||
<section><h1>91</h1></section>
|
||||
<section><h1>92</h1></section>
|
||||
<section><h1>93</h1></section>
|
||||
<section><h1>94</h1></section>
|
||||
<section><h1>95</h1></section>
|
||||
<section><h1>96</h1></section>
|
||||
<section><h1>97</h1></section>
|
||||
<section><h1>98</h1></section>
|
||||
<section><h1>99</h1></section>
|
||||
<section><h1>100</h1></section>
|
||||
<section><h1>101</h1></section>
|
||||
<section><h1>102</h1></section>
|
||||
<section><h1>103</h1></section>
|
||||
<section><h1>104</h1></section>
|
||||
<section><h1>105</h1></section>
|
||||
<section><h1>106</h1></section>
|
||||
<section><h1>107</h1></section>
|
||||
<section><h1>108</h1></section>
|
||||
<section><h1>109</h1></section>
|
||||
<section><h1>110</h1></section>
|
||||
<section><h1>111</h1></section>
|
||||
<section><h1>112</h1></section>
|
||||
<section><h1>113</h1></section>
|
||||
<section><h1>114</h1></section>
|
||||
<section><h1>115</h1></section>
|
||||
<section><h1>116</h1></section>
|
||||
<section><h1>117</h1></section>
|
||||
<section><h1>118</h1></section>
|
||||
<section><h1>119</h1></section>
|
||||
<section><h1>120</h1></section>
|
||||
<section><h1>121</h1></section>
|
||||
<section><h1>122</h1></section>
|
||||
<section><h1>123</h1></section>
|
||||
<section><h1>124</h1></section>
|
||||
<section><h1>125</h1></section>
|
||||
<section><h1>126</h1></section>
|
||||
<section><h1>127</h1></section>
|
||||
<section><h1>128</h1></section>
|
||||
<section><h1>129</h1></section>
|
||||
<section><h1>130</h1></section>
|
||||
<section><h1>131</h1></section>
|
||||
<section><h1>132</h1></section>
|
||||
<section><h1>133</h1></section>
|
||||
<section><h1>134</h1></section>
|
||||
<section><h1>135</h1></section>
|
||||
<section><h1>136</h1></section>
|
||||
<section><h1>137</h1></section>
|
||||
<section><h1>138</h1></section>
|
||||
<section><h1>139</h1></section>
|
||||
<section><h1>140</h1></section>
|
||||
<section><h1>141</h1></section>
|
||||
<section><h1>142</h1></section>
|
||||
<section><h1>143</h1></section>
|
||||
<section><h1>144</h1></section>
|
||||
<section><h1>145</h1></section>
|
||||
<section><h1>146</h1></section>
|
||||
<section><h1>147</h1></section>
|
||||
<section><h1>148</h1></section>
|
||||
<section><h1>149</h1></section>
|
||||
<section><h1>150</h1></section>
|
||||
<section><h1>151</h1></section>
|
||||
<section><h1>152</h1></section>
|
||||
<section><h1>153</h1></section>
|
||||
<section><h1>154</h1></section>
|
||||
<section><h1>155</h1></section>
|
||||
<section><h1>156</h1></section>
|
||||
<section><h1>157</h1></section>
|
||||
<section><h1>158</h1></section>
|
||||
<section><h1>159</h1></section>
|
||||
<section><h1>160</h1></section>
|
||||
<section><h1>161</h1></section>
|
||||
<section><h1>162</h1></section>
|
||||
<section><h1>163</h1></section>
|
||||
<section><h1>164</h1></section>
|
||||
<section><h1>165</h1></section>
|
||||
<section><h1>166</h1></section>
|
||||
<section><h1>167</h1></section>
|
||||
<section><h1>168</h1></section>
|
||||
<section><h1>169</h1></section>
|
||||
<section><h1>170</h1></section>
|
||||
<section><h1>171</h1></section>
|
||||
<section><h1>172</h1></section>
|
||||
<section><h1>173</h1></section>
|
||||
<section><h1>174</h1></section>
|
||||
<section><h1>175</h1></section>
|
||||
<section><h1>176</h1></section>
|
||||
<section><h1>177</h1></section>
|
||||
<section><h1>178</h1></section>
|
||||
<section><h1>179</h1></section>
|
||||
<section><h1>180</h1></section>
|
||||
<section><h1>181</h1></section>
|
||||
<section><h1>182</h1></section>
|
||||
<section><h1>183</h1></section>
|
||||
<section><h1>184</h1></section>
|
||||
<section><h1>185</h1></section>
|
||||
<section><h1>186</h1></section>
|
||||
<section><h1>187</h1></section>
|
||||
<section><h1>188</h1></section>
|
||||
<section><h1>189</h1></section>
|
||||
<section><h1>190</h1></section>
|
||||
<section><h1>191</h1></section>
|
||||
<section><h1>192</h1></section>
|
||||
<section><h1>193</h1></section>
|
||||
<section><h1>194</h1></section>
|
||||
<section><h1>195</h1></section>
|
||||
<section><h1>196</h1></section>
|
||||
<section><h1>197</h1></section>
|
||||
<section><h1>198</h1></section>
|
||||
<section><h1>199</h1></section>
|
||||
<section><h1>200</h1></section>
|
||||
<section><h1>201</h1></section>
|
||||
<section><h1>202</h1></section>
|
||||
<section><h1>203</h1></section>
|
||||
<section><h1>204</h1></section>
|
||||
<section><h1>205</h1></section>
|
||||
<section><h1>206</h1></section>
|
||||
<section><h1>207</h1></section>
|
||||
<section><h1>208</h1></section>
|
||||
<section><h1>209</h1></section>
|
||||
<section><h1>210</h1></section>
|
||||
<section><h1>211</h1></section>
|
||||
<section><h1>212</h1></section>
|
||||
<section><h1>213</h1></section>
|
||||
<section><h1>214</h1></section>
|
||||
<section><h1>215</h1></section>
|
||||
<section><h1>216</h1></section>
|
||||
<section><h1>217</h1></section>
|
||||
<section><h1>218</h1></section>
|
||||
<section><h1>219</h1></section>
|
||||
<section><h1>220</h1></section>
|
||||
<section><h1>221</h1></section>
|
||||
<section><h1>222</h1></section>
|
||||
<section><h1>223</h1></section>
|
||||
<section><h1>224</h1></section>
|
||||
<section><h1>225</h1></section>
|
||||
<section><h1>226</h1></section>
|
||||
<section><h1>227</h1></section>
|
||||
<section><h1>228</h1></section>
|
||||
<section><h1>229</h1></section>
|
||||
<section><h1>230</h1></section>
|
||||
<section><h1>231</h1></section>
|
||||
<section><h1>232</h1></section>
|
||||
<section><h1>233</h1></section>
|
||||
<section><h1>234</h1></section>
|
||||
<section><h1>235</h1></section>
|
||||
<section><h1>236</h1></section>
|
||||
<section><h1>237</h1></section>
|
||||
<section><h1>238</h1></section>
|
||||
<section><h1>239</h1></section>
|
||||
<section><h1>240</h1></section>
|
||||
<section><h1>241</h1></section>
|
||||
<section><h1>242</h1></section>
|
||||
<section><h1>243</h1></section>
|
||||
<section><h1>244</h1></section>
|
||||
<section><h1>245</h1></section>
|
||||
<section><h1>246</h1></section>
|
||||
<section><h1>247</h1></section>
|
||||
<section><h1>248</h1></section>
|
||||
<section><h1>249</h1></section>
|
||||
<section><h1>250</h1></section>
|
||||
<section><h1>251</h1></section>
|
||||
<section><h1>252</h1></section>
|
||||
<section><h1>253</h1></section>
|
||||
<section><h1>254</h1></section>
|
||||
<section><h1>255</h1></section>
|
||||
<section><h1>256</h1></section>
|
||||
<section><h1>257</h1></section>
|
||||
<section><h1>258</h1></section>
|
||||
<section><h1>259</h1></section>
|
||||
<section><h1>260</h1></section>
|
||||
<section><h1>261</h1></section>
|
||||
<section><h1>262</h1></section>
|
||||
<section><h1>263</h1></section>
|
||||
<section><h1>264</h1></section>
|
||||
<section><h1>265</h1></section>
|
||||
<section><h1>266</h1></section>
|
||||
<section><h1>267</h1></section>
|
||||
<section><h1>268</h1></section>
|
||||
<section><h1>269</h1></section>
|
||||
<section><h1>270</h1></section>
|
||||
<section><h1>271</h1></section>
|
||||
<section><h1>272</h1></section>
|
||||
<section><h1>273</h1></section>
|
||||
<section><h1>274</h1></section>
|
||||
<section><h1>275</h1></section>
|
||||
<section><h1>276</h1></section>
|
||||
<section><h1>277</h1></section>
|
||||
<section><h1>278</h1></section>
|
||||
<section><h1>279</h1></section>
|
||||
<section><h1>280</h1></section>
|
||||
<section><h1>281</h1></section>
|
||||
<section><h1>282</h1></section>
|
||||
<section><h1>283</h1></section>
|
||||
<section><h1>284</h1></section>
|
||||
<section><h1>285</h1></section>
|
||||
<section><h1>286</h1></section>
|
||||
<section><h1>287</h1></section>
|
||||
<section><h1>288</h1></section>
|
||||
<section><h1>289</h1></section>
|
||||
<section><h1>290</h1></section>
|
||||
<section><h1>291</h1></section>
|
||||
<section><h1>292</h1></section>
|
||||
<section><h1>293</h1></section>
|
||||
<section><h1>294</h1></section>
|
||||
<section><h1>295</h1></section>
|
||||
<section><h1>296</h1></section>
|
||||
<section><h1>297</h1></section>
|
||||
<section><h1>298</h1></section>
|
||||
<section><h1>299</h1></section>
|
||||
<section><h1>300</h1></section>
|
||||
<section><h1>301</h1></section>
|
||||
<section><h1>302</h1></section>
|
||||
<section><h1>303</h1></section>
|
||||
<section><h1>304</h1></section>
|
||||
<section><h1>305</h1></section>
|
||||
<section><h1>306</h1></section>
|
||||
<section><h1>307</h1></section>
|
||||
<section><h1>308</h1></section>
|
||||
<section><h1>309</h1></section>
|
||||
<section><h1>310</h1></section>
|
||||
<section><h1>311</h1></section>
|
||||
<section><h1>312</h1></section>
|
||||
<section><h1>313</h1></section>
|
||||
<section><h1>314</h1></section>
|
||||
<section><h1>315</h1></section>
|
||||
<section><h1>316</h1></section>
|
||||
<section><h1>317</h1></section>
|
||||
<section><h1>318</h1></section>
|
||||
<section><h1>319</h1></section>
|
||||
<section><h1>320</h1></section>
|
||||
<section><h1>321</h1></section>
|
||||
<section><h1>322</h1></section>
|
||||
<section><h1>323</h1></section>
|
||||
<section><h1>324</h1></section>
|
||||
<section><h1>325</h1></section>
|
||||
<section><h1>326</h1></section>
|
||||
<section><h1>327</h1></section>
|
||||
<section><h1>328</h1></section>
|
||||
<section><h1>329</h1></section>
|
||||
<section><h1>330</h1></section>
|
||||
<section><h1>331</h1></section>
|
||||
<section><h1>332</h1></section>
|
||||
<section><h1>333</h1></section>
|
||||
<section><h1>334</h1></section>
|
||||
<section><h1>335</h1></section>
|
||||
<section><h1>336</h1></section>
|
||||
<section><h1>337</h1></section>
|
||||
<section><h1>338</h1></section>
|
||||
<section><h1>339</h1></section>
|
||||
<section><h1>340</h1></section>
|
||||
<section><h1>341</h1></section>
|
||||
<section><h1>342</h1></section>
|
||||
<section><h1>343</h1></section>
|
||||
<section><h1>344</h1></section>
|
||||
<section><h1>345</h1></section>
|
||||
<section><h1>346</h1></section>
|
||||
<section><h1>347</h1></section>
|
||||
<section><h1>348</h1></section>
|
||||
<section><h1>349</h1></section>
|
||||
<section><h1>350</h1></section>
|
||||
<section><h1>351</h1></section>
|
||||
<section><h1>352</h1></section>
|
||||
<section><h1>353</h1></section>
|
||||
<section><h1>354</h1></section>
|
||||
<section><h1>355</h1></section>
|
||||
<section><h1>356</h1></section>
|
||||
<section><h1>357</h1></section>
|
||||
<section><h1>358</h1></section>
|
||||
<section><h1>359</h1></section>
|
||||
<section><h1>360</h1></section>
|
||||
<section><h1>361</h1></section>
|
||||
<section><h1>362</h1></section>
|
||||
<section><h1>363</h1></section>
|
||||
<section><h1>364</h1></section>
|
||||
<section><h1>365</h1></section>
|
||||
<section><h1>366</h1></section>
|
||||
<section><h1>367</h1></section>
|
||||
<section><h1>368</h1></section>
|
||||
<section><h1>369</h1></section>
|
||||
<section><h1>370</h1></section>
|
||||
<section><h1>371</h1></section>
|
||||
<section><h1>372</h1></section>
|
||||
<section><h1>373</h1></section>
|
||||
<section><h1>374</h1></section>
|
||||
<section><h1>375</h1></section>
|
||||
<section><h1>376</h1></section>
|
||||
<section><h1>377</h1></section>
|
||||
<section><h1>378</h1></section>
|
||||
<section><h1>379</h1></section>
|
||||
<section><h1>380</h1></section>
|
||||
<section><h1>381</h1></section>
|
||||
<section><h1>382</h1></section>
|
||||
<section><h1>383</h1></section>
|
||||
<section><h1>384</h1></section>
|
||||
<section><h1>385</h1></section>
|
||||
<section><h1>386</h1></section>
|
||||
<section><h1>387</h1></section>
|
||||
<section><h1>388</h1></section>
|
||||
<section><h1>389</h1></section>
|
||||
<section><h1>390</h1></section>
|
||||
<section><h1>391</h1></section>
|
||||
<section><h1>392</h1></section>
|
||||
<section><h1>393</h1></section>
|
||||
<section><h1>394</h1></section>
|
||||
<section><h1>395</h1></section>
|
||||
<section><h1>396</h1></section>
|
||||
<section><h1>397</h1></section>
|
||||
<section><h1>398</h1></section>
|
||||
<section><h1>399</h1></section>
|
||||
<section><h1>400</h1></section>
|
||||
<section><h1>401</h1></section>
|
||||
<section><h1>402</h1></section>
|
||||
<section><h1>403</h1></section>
|
||||
<section><h1>404</h1></section>
|
||||
<section><h1>405</h1></section>
|
||||
<section><h1>406</h1></section>
|
||||
<section><h1>407</h1></section>
|
||||
<section><h1>408</h1></section>
|
||||
<section><h1>409</h1></section>
|
||||
<section><h1>410</h1></section>
|
||||
<section><h1>411</h1></section>
|
||||
<section><h1>412</h1></section>
|
||||
<section><h1>413</h1></section>
|
||||
<section><h1>414</h1></section>
|
||||
<section><h1>415</h1></section>
|
||||
<section><h1>416</h1></section>
|
||||
<section><h1>417</h1></section>
|
||||
<section><h1>418</h1></section>
|
||||
<section><h1>419</h1></section>
|
||||
<section><h1>420</h1></section>
|
||||
<section><h1>421</h1></section>
|
||||
<section><h1>422</h1></section>
|
||||
<section><h1>423</h1></section>
|
||||
<section><h1>424</h1></section>
|
||||
<section><h1>425</h1></section>
|
||||
<section><h1>426</h1></section>
|
||||
<section><h1>427</h1></section>
|
||||
<section><h1>428</h1></section>
|
||||
<section><h1>429</h1></section>
|
||||
<section><h1>430</h1></section>
|
||||
<section><h1>431</h1></section>
|
||||
<section><h1>432</h1></section>
|
||||
<section><h1>433</h1></section>
|
||||
<section><h1>434</h1></section>
|
||||
<section><h1>435</h1></section>
|
||||
<section><h1>436</h1></section>
|
||||
<section><h1>437</h1></section>
|
||||
<section><h1>438</h1></section>
|
||||
<section><h1>439</h1></section>
|
||||
<section><h1>440</h1></section>
|
||||
<section><h1>441</h1></section>
|
||||
<section><h1>442</h1></section>
|
||||
<section><h1>443</h1></section>
|
||||
<section><h1>444</h1></section>
|
||||
<section><h1>445</h1></section>
|
||||
<section><h1>446</h1></section>
|
||||
<section><h1>447</h1></section>
|
||||
<section><h1>448</h1></section>
|
||||
<section><h1>449</h1></section>
|
||||
<section><h1>450</h1></section>
|
||||
<section><h1>451</h1></section>
|
||||
<section><h1>452</h1></section>
|
||||
<section><h1>453</h1></section>
|
||||
<section><h1>454</h1></section>
|
||||
<section><h1>455</h1></section>
|
||||
<section><h1>456</h1></section>
|
||||
<section><h1>457</h1></section>
|
||||
<section><h1>458</h1></section>
|
||||
<section><h1>459</h1></section>
|
||||
<section><h1>460</h1></section>
|
||||
<section><h1>461</h1></section>
|
||||
<section><h1>462</h1></section>
|
||||
<section><h1>463</h1></section>
|
||||
<section><h1>464</h1></section>
|
||||
<section><h1>465</h1></section>
|
||||
<section><h1>466</h1></section>
|
||||
<section><h1>467</h1></section>
|
||||
<section><h1>468</h1></section>
|
||||
<section><h1>469</h1></section>
|
||||
<section><h1>470</h1></section>
|
||||
<section><h1>471</h1></section>
|
||||
<section><h1>472</h1></section>
|
||||
<section><h1>473</h1></section>
|
||||
<section><h1>474</h1></section>
|
||||
<section><h1>475</h1></section>
|
||||
<section><h1>476</h1></section>
|
||||
<section><h1>477</h1></section>
|
||||
<section><h1>478</h1></section>
|
||||
<section><h1>479</h1></section>
|
||||
<section><h1>480</h1></section>
|
||||
<section><h1>481</h1></section>
|
||||
<section><h1>482</h1></section>
|
||||
<section><h1>483</h1></section>
|
||||
<section><h1>484</h1></section>
|
||||
<section><h1>485</h1></section>
|
||||
<section><h1>486</h1></section>
|
||||
<section><h1>487</h1></section>
|
||||
<section><h1>488</h1></section>
|
||||
<section><h1>489</h1></section>
|
||||
<section><h1>490</h1></section>
|
||||
<section><h1>491</h1></section>
|
||||
<section><h1>492</h1></section>
|
||||
<section><h1>493</h1></section>
|
||||
<section><h1>494</h1></section>
|
||||
<section><h1>495</h1></section>
|
||||
<section><h1>496</h1></section>
|
||||
<section><h1>497</h1></section>
|
||||
<section><h1>498</h1></section>
|
||||
<section><h1>499</h1></section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../dist/reveal.js"></script>
|
||||
<script>
|
||||
Reveal.initialize({
|
||||
transition: 'linear'
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -89,7 +89,7 @@
|
||||
<h2>Same background twice (2/2)</h2>
|
||||
</section>
|
||||
|
||||
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm">
|
||||
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://static.slid.es/site/homepage/v1/homepage-video-editor.webm">
|
||||
<h2>Video background</h2>
|
||||
</section>
|
||||
|
||||
|
||||
144
examples/lightbox.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Ligthbox</title>
|
||||
|
||||
<link rel="stylesheet" href="../dist/reveal.css">
|
||||
<link rel="stylesheet" href="../dist/theme/black.css" id="theme">
|
||||
|
||||
<style>
|
||||
.reveal {
|
||||
font-size: 24px;
|
||||
}
|
||||
.reveal figure {
|
||||
margin: 0 0 1rem 0;
|
||||
text-align: left;
|
||||
}
|
||||
.reveal figure img,
|
||||
.reveal figure video {
|
||||
margin: 0.25rem 0 0 0;
|
||||
}
|
||||
figcaption, a {
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="reveal">
|
||||
|
||||
<div class="slides">
|
||||
|
||||
<section>
|
||||
|
||||
<h2>Preview Overlays</h2>
|
||||
|
||||
<div class="r-hstack items-start">
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Images</h5>
|
||||
<figure>
|
||||
<figcaption>Preview with default settings:</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/a.png" data-preview-image>
|
||||
</figure>
|
||||
<figure>
|
||||
<figcaption>Preview with data-preview-fit="contain"</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/a.png" data-preview-image data-preview-fit="contain">
|
||||
</figure>
|
||||
<figure>
|
||||
<figcaption>Preview with data-preview-fit="cover"</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/a.png" data-preview-image data-preview-fit="cover">
|
||||
</figure>
|
||||
<figure>
|
||||
<figcaption>Preview another image (c)</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/b.png" data-preview-image="https://static.slid.es/images/alphabet/v1/c.png">
|
||||
</figure>
|
||||
<a href="#" data-preview-image="https://static.slid.es/images/alphabet/v1/x.png">
|
||||
Preview image from a link.
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="width: 1px; height: 30vh; margin: 0 3rem;background-color: #999;"></div>
|
||||
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Videos</h5>
|
||||
<figure>
|
||||
<figcaption>Preview video</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/x.png" data-preview-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4">
|
||||
</figure>
|
||||
<figure>
|
||||
<figcaption>Preview video</figcaption>
|
||||
<video height="50" src="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-preview-video></video>
|
||||
</figure>
|
||||
<a href="#" data-preview-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4">
|
||||
Preview video from a link.
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="width: 1px; height: 30vh; margin: 0 3rem;background-color: #999;"></div>
|
||||
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Iframes</h5>
|
||||
<a href="https://hakim.se">https://hakim.se | data-preview-link</a>
|
||||
<a data-preview-link href="https://hakim.se">https://hakim.se | data-preview-link</a>
|
||||
<br />
|
||||
<a data-preview-link="false" href="https://hakim.se">https://hakim.se | data-preview-link=false</a>
|
||||
<br />
|
||||
<figure>
|
||||
<figcaption>Preview link from an image</figcaption>
|
||||
<img height="50" src="https://static.slid.es/images/alphabet/v1/a.png" data-preview-link="https://hakim.se">
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<section style="text-align: left;">
|
||||
|
||||
<h2>Lightbox</h2>
|
||||
|
||||
<div class="r-hstack items-start justify-start">
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Images</h5>
|
||||
<figure>
|
||||
<img height="100" src="https://static.slid.es/images/alphabet/v1/a.png" data-preview-image data-preview-fit="contain">
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div style="width: 1px; height: 20vh; margin: 0 3rem;background-color: #222;"></div>
|
||||
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Videos</h5>
|
||||
<figure>
|
||||
<video height="100" src="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-preview-video></video>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div style="width: 1px; height: 20vh; margin: 0 3rem;background-color: #222;"></div>
|
||||
|
||||
<div class="r-vstack items-start">
|
||||
<h5>Iframes</h5>
|
||||
<a style="font-size: 28px;" data-preview-link href="https://hakim.se">https://hakim.se</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="../dist/reveal.js"></script>
|
||||
<script>
|
||||
Reveal.initialize({
|
||||
previewLinks: false,
|
||||
width: 1280,
|
||||
height: 720
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -19,102 +19,7 @@
|
||||
<div class="slides">
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- Slides are separated by three dashes (the default) -->
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||
## Demo 1
|
||||
Slide 1
|
||||
---
|
||||
## Demo 1
|
||||
Slide 2
|
||||
---
|
||||
## Demo 1
|
||||
Slide 3
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Slides are separated by regexp matching newline + three dashes + newline, vertical slides identical but two dashes -->
|
||||
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
|
||||
<script type="text/template">
|
||||
## Demo 2
|
||||
Slide 1.1
|
||||
|
||||
--
|
||||
|
||||
## Demo 2
|
||||
Slide 1.2
|
||||
|
||||
---
|
||||
|
||||
## Demo 2
|
||||
Slide 2
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- No "extra" slides, since the separator can't be matched ("---" will become horizontal rulers) -->
|
||||
<section data-markdown data-separator="$x">
|
||||
<script type="text/template">
|
||||
A
|
||||
|
||||
---
|
||||
|
||||
B
|
||||
|
||||
---
|
||||
|
||||
C
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Slide attributes -->
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||
<!-- .slide: data-background="#000000" -->
|
||||
## Slide attributes
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Element attributes -->
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||
## Element attributes
|
||||
- Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
|
||||
- Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Code -->
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||
```php [1|3-5]
|
||||
public function foo()
|
||||
{
|
||||
$foo = array(
|
||||
'bar' => 'bar'
|
||||
)
|
||||
}
|
||||
```
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Images -->
|
||||
<section data-markdown>
|
||||
<script type="text/template">
|
||||

|
||||
</script>
|
||||
</section>
|
||||
|
||||
<!-- Math -->
|
||||
<section data-markdown>
|
||||
## The Lorenz Equations
|
||||
`\[\begin{aligned}
|
||||
\dot{x} & = \sigma(y-x) \\
|
||||
\dot{y} & = \rho x - y - xz \\
|
||||
\dot{z} & = -\beta z + xy
|
||||
\end{aligned} \]`
|
||||
</section>
|
||||
<section style="text-align: left;" data-markdown="markdown.md" data-separator="---" data-separator-vertical="^\n\n"></section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -128,6 +33,8 @@
|
||||
<script>
|
||||
|
||||
Reveal.initialize({
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
controls: true,
|
||||
progress: true,
|
||||
history: true,
|
||||
|
||||
@@ -1,41 +1,153 @@
|
||||
# Markdown Demo
|
||||
# JSONite: High-Performance Embedded Database for Semi-Structured Data
|
||||
|
||||
---
|
||||
|
||||
## The JSON Performance Crisis
|
||||
|
||||
**JSON is Everywhere:**
|
||||
- Web APIS, IoT, logs, configurations
|
||||
- Semi-structured, flexible, human-readable
|
||||
|
||||
**But Current Solutions Fail:**
|
||||
- **Large Databases**: People use MongoDB or PostgreSQL's JSONB to store data
|
||||
- **Embeded Databases**: RocksDB and PoloDB lack of ACID and SQL support
|
||||
- **Serialization to String**: Or serialize JSON into strings and store in SQLite
|
||||
|
||||
|
||||
Serialized JSON with SQL example
|
||||
|
||||
## External 1.1
|
||||
```sql
|
||||
insert into http_request_log (ip, headers)
|
||||
values ('127.0.0.1', '{
|
||||
"Content-Type": "application/oct-stream",
|
||||
"X-Forwarded-For": "100.64.0.1",
|
||||
}');
|
||||
```
|
||||
|
||||
Content 1.1
|
||||
---
|
||||
|
||||
Note: This will only appear in the speaker notes window.
|
||||
## Introducing JSONite
|
||||
|
||||
**Best of Both Worlds:**
|
||||
- SQLite's based
|
||||
- Native JSON optimization
|
||||
|
||||
**Key Advantages:**
|
||||
- ✅ ACID compliance
|
||||
- ✅ SQL simplicity
|
||||
- ✅ Serverless C library
|
||||
- ✅ Lightning-fast JSON access
|
||||
|
||||
---
|
||||
|
||||
## Smart Key Optimization
|
||||
|
||||
**Key Sorting by Length:**
|
||||
```
|
||||
{
|
||||
"id": 1,
|
||||
"address": {...}
|
||||
"name": "John",
|
||||
"email": "john@example.com",
|
||||
}
|
||||
```
|
||||
|
||||
**Sorted as:**
|
||||
```
|
||||
{
|
||||
"id", (2 chars)
|
||||
"name", (4 chars)
|
||||
"email", (5 chars)
|
||||
"address", (7 chars)
|
||||
}
|
||||
```
|
||||
|
||||
**Binary search on length → Fast lookups**
|
||||
|
||||
---
|
||||
|
||||
## Handling Massive Data: Smart TOAST
|
||||
|
||||
**The Oversized-Attribute Storage Technique**
|
||||
- Standard approach: arbitrary chunking
|
||||
- JSONite's innovation: **Data-Type Aware TOAST**
|
||||
|
||||
**Intelligent Chunking:**
|
||||
- Arrays split between elements
|
||||
- Objects split between key-value pairs
|
||||
- Text falls back to fixed chunks
|
||||
|
||||
**Enables "Slice Detoasting":**
|
||||
- `$.logs[1000000:1000010]` fetches only 10 elements
|
||||
- Not the entire multi-gigabyte array
|
||||
|
||||
|
||||
## External 1.2
|
||||
Smart Chunking Example
|
||||
|
||||
Content 1.2
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"title": "some text",
|
||||
"html": <pointer to TOAST of 200k text>,
|
||||
"photos": [<pointer to TOAST of binary data>],
|
||||
"crawl_logs": [<pointer to TOAST of array of texts>]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Query Power
|
||||
|
||||
## External 2
|
||||
**Full SQL + JSON Support:**
|
||||
- PostgreSQL-compatible JSONB path operators
|
||||
- GIN indexes for instant search
|
||||
|
||||
Content 2.1
|
||||
```sql
|
||||
SELECT *
|
||||
FROM accounts
|
||||
WHERE data @> '{"status": "active"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Validation: Benchmark Datasets
|
||||
|
||||
## External 3.1
|
||||
**Three Specialized Workloads:**
|
||||
|
||||
Content 3.1
|
||||
1. **YCSB-Style Read Benchmark**
|
||||
- Yahoo! Cloud Serving Benchmark
|
||||
- 1M JSON documents (1KB-100KB each)
|
||||
|
||||
2. **TPC-C Inspired Update Benchmark**
|
||||
- Transaction Processing Performance Council
|
||||
- 100K transactional JSON records
|
||||
- Frequent small field updates
|
||||
|
||||
## External 3.2
|
||||
3. **Large-Array Slice Benchmark**
|
||||
- Multi-gigabyte JSON documents
|
||||
- Massive arrays (10M+ elements)
|
||||
|
||||
Content 3.2
|
||||
**Comparison Targets:** SQLite JSONB vs MongoDB vs PostgreSQL vs JSONite
|
||||
|
||||
---
|
||||
|
||||
## External 3.3 (Image)
|
||||
## JSONite: The Future of Embedded Data Storage
|
||||
|
||||

|
||||
**Why It Matters Today:**
|
||||
- **Edge Computing**: Lightweight, handles sensor data efficiently
|
||||
- **Modern Apps**: SQL power + JSON flexibility, no schema migrations
|
||||
|
||||
**The Vision:**
|
||||
- Open source implementation
|
||||
- Community-driven development
|
||||
- Becoming the default choice for embedded JSON storage
|
||||
- Bridging SQL reliability with NoSQL flexibility
|
||||
|
||||
## External 3.4 (Math)
|
||||
---
|
||||
|
||||
`\[ J(\theta_0,\theta_1) = \sum_{i=0} \]`
|
||||
## Thank You
|
||||
|
||||
**Questions?**
|
||||
|
||||
*CHEN Yongyuan*
|
||||
*2025-11-01*
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
|
||||
<section>
|
||||
<h2>Video</h2>
|
||||
<video src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" data-autoplay></video>
|
||||
<video src="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-autoplay></video>
|
||||
</section>
|
||||
|
||||
<section data-background-video="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">
|
||||
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4">
|
||||
<h2>Background Video</h2>
|
||||
</section>
|
||||
|
||||
|
||||
120
examples/scroll.html
Normal file
@@ -0,0 +1,120 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Scroll View</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<link rel="stylesheet" href="../dist/reset.css">
|
||||
<link rel="stylesheet" href="../dist/reveal.css">
|
||||
<link rel="stylesheet" href="../dist/theme/black.css" id="theme">
|
||||
<link rel="stylesheet" href="../plugin/highlight/monokai.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="reveal">
|
||||
|
||||
<div class="slides">
|
||||
|
||||
<section><h1>Scroll View</h1></section>
|
||||
<section data-background="indigo">
|
||||
<h2>Scroll triggered fragments</h2>
|
||||
<ul>
|
||||
<li class="fragment fade-left">Step one</li>
|
||||
<li class="fragment fade-left">Step two</li>
|
||||
<li class="fragment fade-left">Step three</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section data-background-color="#fff"><h2>Scrollbar inverts<br>based on slide bg</h2></section>
|
||||
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||
<h2>Auto-Animate</h2>
|
||||
<p>Scroll triggered auto-animations 😍</p>
|
||||
<div class="r-hstack justify-center">
|
||||
<div data-id="box1" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||
<div data-id="box2" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||
<div data-id="box3" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||
</div>
|
||||
</section>
|
||||
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||
<div class="r-hstack justify-center">
|
||||
<div data-id="box1" data-auto-animate-delay="0" style="background: cyan; width: 150px; height: 100px; margin: 10px;"></div>
|
||||
<div data-id="box2" data-auto-animate-delay="0.1" style="background: magenta; width: 150px; height: 100px; margin: 10px;"></div>
|
||||
<div data-id="box3" data-auto-animate-delay="0.2" style="background: yellow; width: 150px; height: 100px; margin: 10px;"></div>
|
||||
</div>
|
||||
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||
</section>
|
||||
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||
<div class="r-stack">
|
||||
<div data-id="box1" style="background: cyan; width: 300px; height: 300px; border-radius: 200px;"></div>
|
||||
<div data-id="box2" style="background: magenta; width: 200px; height: 200px; border-radius: 200px;"></div>
|
||||
<div data-id="box3" style="background: yellow; width: 100px; height: 100px; border-radius: 200px;"></div>
|
||||
</div>
|
||||
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||
</section>
|
||||
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)" id="gradient-bg">
|
||||
<h2 data-id="code-title">Code highlights,<br />meet scroll triggers</h2>
|
||||
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function Example() {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>You clicked {count} times</p>
|
||||
<button onClick={() => setCount(count + 1)}>
|
||||
Click me
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SecondExample() {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>You clicked {count} times</p>
|
||||
<button onClick={() => setCount(count + 1)}>
|
||||
Click me
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</script></code></pre>
|
||||
</section>
|
||||
<section class="stack">
|
||||
<section data-background="https://static.slid.es/reveal/image-placeholder.png" id="image-bg">
|
||||
<h2>Image Backgrounds</h2>
|
||||
</section>
|
||||
<section data-background-video-muted data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://static.slid.es/site/homepage/v1/homepage-video-editor.webm">
|
||||
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
|
||||
<h2>Video background</h2>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section><h2>The end</h2></section>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="../dist/reveal.js"></script>
|
||||
<script src="../plugin/notes/notes.js"></script>
|
||||
<script src="../plugin/markdown/markdown.js"></script>
|
||||
<script src="../plugin/highlight/highlight.js"></script>
|
||||
<script>
|
||||
Reveal.initialize({
|
||||
view: 'scroll',
|
||||
hash: true,
|
||||
|
||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
84
gulpfile.js
@@ -1,22 +1,20 @@
|
||||
const fs = require('fs');
|
||||
const pkg = require('./package.json')
|
||||
const path = require('path')
|
||||
const glob = require('glob')
|
||||
const yargs = require('yargs')
|
||||
const colors = require('colors')
|
||||
const through = require('through2');
|
||||
const qunit = require('node-qunit-puppeteer')
|
||||
|
||||
const {rollup} = require('rollup')
|
||||
const {terser} = require('rollup-plugin-terser')
|
||||
const terser = require('@rollup/plugin-terser')
|
||||
const babel = require('@rollup/plugin-babel').default
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
const resolve = require('@rollup/plugin-node-resolve').default
|
||||
const sass = require('sass')
|
||||
|
||||
const gulp = require('gulp')
|
||||
const tap = require('gulp-tap')
|
||||
const zip = require('gulp-zip')
|
||||
const header = require('gulp-header')
|
||||
const header = require('gulp-header-comment')
|
||||
const eslint = require('gulp-eslint')
|
||||
const minify = require('gulp-clean-css')
|
||||
const connect = require('gulp-connect')
|
||||
@@ -26,13 +24,21 @@ const root = yargs.argv.root || '.'
|
||||
const port = yargs.argv.port || 8000
|
||||
const host = yargs.argv.host || 'localhost'
|
||||
|
||||
const banner = `/*!
|
||||
* reveal.js ${pkg.version}
|
||||
* ${pkg.homepage}
|
||||
* MIT licensed
|
||||
*
|
||||
* Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se
|
||||
*/\n`
|
||||
const cssLicense = `
|
||||
reveal.js ${pkg.version}
|
||||
${pkg.homepage}
|
||||
MIT licensed
|
||||
|
||||
Copyright (C) 2011-2024 Hakim El Hattab, https://hakim.se
|
||||
`;
|
||||
|
||||
const jsLicense = `/*!
|
||||
* reveal.js ${pkg.version}
|
||||
* ${pkg.homepage}
|
||||
* MIT licensed
|
||||
*
|
||||
* Copyright (C) 2011-2024 Hakim El Hattab, https://hakim.se
|
||||
*/\n`;
|
||||
|
||||
// Prevents warnings from opening too many test pages
|
||||
process.setMaxListeners(20);
|
||||
@@ -88,7 +94,7 @@ gulp.task('js-es5', () => {
|
||||
name: 'Reveal',
|
||||
file: './dist/reveal.js',
|
||||
format: 'umd',
|
||||
banner: banner,
|
||||
banner: jsLicense,
|
||||
sourcemap: true
|
||||
});
|
||||
});
|
||||
@@ -110,7 +116,7 @@ gulp.task('js-es6', () => {
|
||||
return bundle.write({
|
||||
file: './dist/reveal.esm.js',
|
||||
format: 'es',
|
||||
banner: banner,
|
||||
banner: jsLicense,
|
||||
sourcemap: true
|
||||
});
|
||||
});
|
||||
@@ -163,12 +169,12 @@ function compileSass() {
|
||||
const transformedFile = vinylFile.clone();
|
||||
|
||||
sass.render({
|
||||
silenceDeprecations: ['legacy-js-api'],
|
||||
data: transformedFile.contents.toString(),
|
||||
includePaths: ['css/', 'css/theme/template']
|
||||
file: transformedFile.path,
|
||||
}, ( err, result ) => {
|
||||
if( err ) {
|
||||
console.log( vinylFile.path );
|
||||
console.log( err.formatted );
|
||||
callback(err);
|
||||
}
|
||||
else {
|
||||
transformedFile.extname = '.css';
|
||||
@@ -187,7 +193,7 @@ gulp.task('css-core', () => gulp.src(['css/reveal.scss'])
|
||||
.pipe(compileSass())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(minify({compatibility: 'ie9'}))
|
||||
.pipe(header(banner))
|
||||
.pipe(header(cssLicense))
|
||||
.pipe(gulp.dest('./dist')))
|
||||
|
||||
gulp.task('css', gulp.parallel('css-themes', 'css-core'))
|
||||
@@ -214,7 +220,7 @@ gulp.task('qunit', () => {
|
||||
targetUrl: `http://${serverConfig.host}:${serverConfig.port}/${filename}`,
|
||||
timeout: 20000,
|
||||
redirectConsole: false,
|
||||
puppeteerArgs: ['--allow-file-access-from-files']
|
||||
puppeteerArgs: ['--allow-file-access-from-files', '--no-sandbox']
|
||||
})
|
||||
.then(result => {
|
||||
if( result.stats.failed > 0 ) {
|
||||
@@ -269,24 +275,25 @@ gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test'))
|
||||
|
||||
gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
|
||||
|
||||
gulp.task('package', gulp.series(() =>
|
||||
gulp.task('package', gulp.series(async () => {
|
||||
|
||||
gulp.src(
|
||||
[
|
||||
'./index.html',
|
||||
'./dist/**',
|
||||
'./lib/**',
|
||||
'./images/**',
|
||||
'./plugin/**',
|
||||
'./**.md'
|
||||
],
|
||||
{ base: './' }
|
||||
)
|
||||
let dirs = [
|
||||
'./index.html',
|
||||
'./dist/**',
|
||||
'./plugin/**',
|
||||
'./*/*.md'
|
||||
];
|
||||
|
||||
if (fs.existsSync('./lib')) dirs.push('./lib/**');
|
||||
if (fs.existsSync('./images')) dirs.push('./images/**');
|
||||
if (fs.existsSync('./slides')) dirs.push('./slides/**');
|
||||
|
||||
return gulp.src( dirs, { base: './', encoding: false } )
|
||||
.pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
|
||||
|
||||
))
|
||||
}))
|
||||
|
||||
gulp.task('reload', () => gulp.src(['*.html', '*.md'])
|
||||
gulp.task('reload', () => gulp.src(['index.html'])
|
||||
.pipe(connect.reload()));
|
||||
|
||||
gulp.task('serve', () => {
|
||||
@@ -298,14 +305,19 @@ gulp.task('serve', () => {
|
||||
livereload: true
|
||||
})
|
||||
|
||||
gulp.watch(['*.html', '*.md'], gulp.series('reload'))
|
||||
const slidesRoot = root.endsWith('/') ? root : root + '/'
|
||||
gulp.watch([
|
||||
slidesRoot + '**/*.html',
|
||||
slidesRoot + '**/*.md',
|
||||
`!${slidesRoot}**/node_modules/**`, // ignore node_modules
|
||||
], gulp.series('reload'))
|
||||
|
||||
gulp.watch(['js/**'], gulp.series('js', 'reload', 'eslint'))
|
||||
|
||||
gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload'))
|
||||
|
||||
gulp.watch([
|
||||
'css/theme/source/*.{sass,scss}',
|
||||
'css/theme/source/**/*.{sass,scss}',
|
||||
'css/theme/template/*.{sass,scss}',
|
||||
], gulp.series('css-themes', 'reload'))
|
||||
|
||||
@@ -316,4 +328,4 @@ gulp.task('serve', () => {
|
||||
|
||||
gulp.watch(['test/*.html'], gulp.series('test'))
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
BIN
images/excel.png
|
Before Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 102 KiB |
BIN
images/logo.png
|
Before Width: | Height: | Size: 6.5 KiB |
BIN
images/oil.jpg
|
Before Width: | Height: | Size: 224 KiB |
BIN
images/paper.jpg
|
Before Width: | Height: | Size: 454 KiB |
|
Before Width: | Height: | Size: 118 KiB |
247
index.html
@@ -1,217 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta 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/reveal.css" />
|
||||
<link rel="stylesheet" href="dist/theme/serif.css" />
|
||||
<link rel="stylesheet" href="dist/reset.css">
|
||||
<link rel="stylesheet" href="dist/reveal.css">
|
||||
<link rel="stylesheet" href="dist/theme/black.css">
|
||||
|
||||
<!-- Theme used for syntax highlighted code -->
|
||||
<link rel="stylesheet" href="plugin/highlight/monokai.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="reveal">
|
||||
<div class="slides">
|
||||
<section data-markdown>
|
||||

|
||||
<!-- Theme used for syntax highlighted code -->
|
||||
<link rel="stylesheet" href="plugin/highlight/monokai.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="reveal">
|
||||
<div class="slides">
|
||||
<section>Slide 1</section>
|
||||
<section>Slide 2</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
### Accounting Internship Report
|
||||
<script src="dist/reveal.js"></script>
|
||||
<script src="plugin/notes/notes.js"></script>
|
||||
<script src="plugin/markdown/markdown.js"></script>
|
||||
<script src="plugin/highlight/highlight.js"></script>
|
||||
<script>
|
||||
// More info about initialization & config:
|
||||
// - https://revealjs.com/initialization/
|
||||
// - https://revealjs.com/config/
|
||||
Reveal.initialize({
|
||||
hash: true,
|
||||
|
||||
- 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
|
||||
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 data-markdown>
|
||||
### Key Lessons Learned
|
||||
|
||||
> 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 data-markdown>
|
||||
## Suggestion
|
||||
</section>
|
||||
<section data-markdown>
|
||||
## For the Company
|
||||
|
||||
> Information Island: Data in system that has no external connectivity.
|
||||
|
||||
- Can't sync/compare data between systems
|
||||
- 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 data-markdown>
|
||||
## For the Accounting Program
|
||||
|
||||
- Set a file naming standard
|
||||
- Instead of something like `Water final ver.2 (1).docx`
|
||||
- Set a version control system for the files
|
||||
- Automate repetitive tasks
|
||||
</section>
|
||||
<section>
|
||||
<h2>For Future Accounting Interns</h2>
|
||||
<ul>
|
||||
<li class="fragment">Get an accounting certification</li>
|
||||
<li class="fragment">Be familiar with Chinese tax & laws</li>
|
||||
<li class="fragment">Learn a programming language (Recommend: <code>Python</code>)</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Thank you</h1>
|
||||
<p>for listining</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="dist/reveal.js"></script>
|
||||
<script src="plugin/notes/notes.js"></script>
|
||||
<script src="plugin/markdown/markdown.js"></script>
|
||||
<script src="plugin/highlight/highlight.js"></script>
|
||||
<script src="plugin/zoom/zoom.js"></script>
|
||||
<script>
|
||||
// More info about initialization & config:
|
||||
// - https://revealjs.com/initialization/
|
||||
// - https://revealjs.com/config/
|
||||
Reveal.initialize({
|
||||
hash: true,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
|
||||
// Learn about plugins: https://revealjs.com/plugins/
|
||||
plugins: [RevealMarkdown, RevealHighlight, RevealNotes, RevealZoom],
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
// Learn about plugins: https://revealjs.com/plugins/
|
||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
47
js/config.js
@@ -15,7 +15,10 @@ export default {
|
||||
minScale: 0.2,
|
||||
maxScale: 2.0,
|
||||
|
||||
// Display presentation control arrows
|
||||
// Display presentation control arrows.
|
||||
// - true: Display controls on all screens
|
||||
// - false: Hide controls on all screens
|
||||
// - "speaker-only": Only display controls in the speaker view
|
||||
controls: true,
|
||||
|
||||
// Help the user learn the controls by providing hints, for example by
|
||||
@@ -65,13 +68,16 @@ export default {
|
||||
// Flags if we should monitor the hash and change slides accordingly
|
||||
respondToHashChanges: true,
|
||||
|
||||
// Enable support for jump-to-slide navigation shortcuts
|
||||
jumpToSlide: true,
|
||||
|
||||
// Push each slide change to the browser history. Implies `hash: true`
|
||||
history: false,
|
||||
|
||||
// Enable keyboard shortcuts for navigation
|
||||
keyboard: true,
|
||||
|
||||
// Optional function that blocks keyboard events when retuning false
|
||||
// Optional function that blocks keyboard events when returning false
|
||||
//
|
||||
// If you set this to 'focused', we will only capture keyboard events
|
||||
// for embedded decks when they are in focus
|
||||
@@ -162,6 +168,9 @@ export default {
|
||||
// - false: All iframes with data-src will be loaded only when visible
|
||||
preloadIframes: null,
|
||||
|
||||
// Prevent embedded iframes from automatically focusing on themselves
|
||||
preventIframeAutoFocus: true,
|
||||
|
||||
// Can be used to globally disable auto-animation
|
||||
autoAnimate: true,
|
||||
|
||||
@@ -253,6 +262,36 @@ export default {
|
||||
parallaxBackgroundHorizontal: null,
|
||||
parallaxBackgroundVertical: null,
|
||||
|
||||
// Can be used to initialize reveal.js in one of the following views:
|
||||
// - print: Render the presentation so that it can be printed to PDF
|
||||
// - scroll: Show the presentation as a tall scrollable page with scroll
|
||||
// triggered animations
|
||||
view: null,
|
||||
|
||||
// Adjusts the height of each slide in the scroll view.
|
||||
// - full: Each slide is as tall as the viewport
|
||||
// - compact: Slides are as small as possible, allowing multiple slides
|
||||
// to be visible in parallel on tall devices
|
||||
scrollLayout: 'full',
|
||||
|
||||
// Control how scroll snapping works in the scroll view.
|
||||
// - false: No snapping, scrolling is continuous
|
||||
// - proximity: Snap when close to a slide
|
||||
// - mandatory: Always snap to the closest slide
|
||||
//
|
||||
// Only applies to presentations in scroll view.
|
||||
scrollSnap: 'mandatory',
|
||||
|
||||
// Enables and configure the scroll view progress bar.
|
||||
// - 'auto': Show the scrollbar while scrolling, hide while idle
|
||||
// - true: Always show the scrollbar
|
||||
// - false: Never show the scrollbar
|
||||
scrollProgress: 'auto',
|
||||
|
||||
// Automatically activate the scroll view when we the viewport falls
|
||||
// below the given width.
|
||||
scrollActivationWidth: 435,
|
||||
|
||||
// The maximum number of pages a single slide can expand onto when printing
|
||||
// to PDF, unlimited by default
|
||||
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
|
||||
@@ -284,6 +323,10 @@ export default {
|
||||
// Time before the cursor is hidden (in ms)
|
||||
hideCursorTime: 5000,
|
||||
|
||||
// Should we automatically sort and set indices for fragments
|
||||
// at each sync? (See Reveal.sync)
|
||||
sortFragmentsOnSync: true,
|
||||
|
||||
// Script dependencies to load
|
||||
dependencies: [],
|
||||
|
||||
|
||||
@@ -31,10 +31,13 @@ export default class AutoAnimate {
|
||||
let toSlideIndex = allSlides.indexOf( toSlide );
|
||||
let fromSlideIndex = allSlides.indexOf( fromSlide );
|
||||
|
||||
// Ensure that both slides are auto-animate targets with the same data-auto-animate-id value
|
||||
// (including null if absent on both) and that data-auto-animate-restart isn't set on the
|
||||
// physically latter slide (independent of slide direction)
|
||||
if( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )
|
||||
// Ensure that;
|
||||
// 1. Both slides exist.
|
||||
// 2. Both slides are auto-animate targets with the same
|
||||
// data-auto-animate-id value (including null if absent on both).
|
||||
// 3. data-auto-animate-restart isn't set on the physically latter
|
||||
// slide (independent of slide direction).
|
||||
if( fromSlide && toSlide && fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )
|
||||
&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' )
|
||||
&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
|
||||
|
||||
@@ -175,28 +178,12 @@ export default class AutoAnimate {
|
||||
let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
|
||||
toProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );
|
||||
|
||||
// Maintain fragment visibility for matching elements when
|
||||
// we're navigating forwards, this way the viewer won't need
|
||||
// to step through the same fragments twice
|
||||
if( to.classList.contains( 'fragment' ) ) {
|
||||
|
||||
// Don't auto-animate the opacity of fragments to avoid
|
||||
// conflicts with fragment animations
|
||||
delete toProps.styles['opacity'];
|
||||
|
||||
if( from.classList.contains( 'fragment' ) ) {
|
||||
|
||||
let fromFragmentStyle = ( from.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];
|
||||
let toFragmentStyle = ( to.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];
|
||||
|
||||
// Only skip the fragment if the fragment animation style
|
||||
// remains unchanged
|
||||
if( fromFragmentStyle === toFragmentStyle && animationOptions.slideDirection === 'forward' ) {
|
||||
to.classList.add( 'visible', 'disabled' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If translation and/or scaling are enabled, css transform
|
||||
@@ -461,14 +448,14 @@ export default class AutoAnimate {
|
||||
const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
|
||||
const mediaNodes = 'img, video, iframe';
|
||||
|
||||
// Eplicit matches via data-id
|
||||
// Explicit matches via data-id
|
||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
|
||||
return node.nodeName + ':::' + node.getAttribute( 'data-id' );
|
||||
} );
|
||||
|
||||
// Text
|
||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {
|
||||
return node.nodeName + ':::' + node.innerText;
|
||||
return node.nodeName + ':::' + node.textContent.trim();
|
||||
} );
|
||||
|
||||
// Media
|
||||
@@ -478,7 +465,7 @@ export default class AutoAnimate {
|
||||
|
||||
// Code
|
||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {
|
||||
return node.nodeName + ':::' + node.innerText;
|
||||
return node.nodeName + ':::' + node.textContent.trim();
|
||||
} );
|
||||
|
||||
pairs.forEach( pair => {
|
||||
@@ -504,7 +491,7 @@ export default class AutoAnimate {
|
||||
} );
|
||||
|
||||
// Line numbers
|
||||
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {
|
||||
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-numbers[data-line-number]', node => {
|
||||
return node.getAttribute( 'data-line-number' );
|
||||
}, {
|
||||
scale: false,
|
||||
@@ -573,14 +560,14 @@ export default class AutoAnimate {
|
||||
|
||||
// Retrieve the 'from' element
|
||||
if( fromMatches[key] ) {
|
||||
const pimaryIndex = toMatches[key].length - 1;
|
||||
const primaryIndex = toMatches[key].length - 1;
|
||||
const secondaryIndex = fromMatches[key].length - 1;
|
||||
|
||||
// If there are multiple identical from elements, retrieve
|
||||
// the one at the same index as our to-element.
|
||||
if( fromMatches[key][ pimaryIndex ] ) {
|
||||
fromElement = fromMatches[key][ pimaryIndex ];
|
||||
fromMatches[key][ pimaryIndex ] = null;
|
||||
if( fromMatches[key][ primaryIndex ] ) {
|
||||
fromElement = fromMatches[key][ primaryIndex ];
|
||||
fromMatches[key][ primaryIndex ] = null;
|
||||
}
|
||||
// If there are no matching from-elements at the same index,
|
||||
// use the last one.
|
||||
@@ -608,7 +595,7 @@ export default class AutoAnimate {
|
||||
* fading of unmatched elements is turned on, these elements
|
||||
* will fade when going between auto-animate slides.
|
||||
*
|
||||
* Note that parents of auto-animate targets are NOT considerd
|
||||
* Note that parents of auto-animate targets are NOT considered
|
||||
* unmatched since fading them would break the auto-animation.
|
||||
*
|
||||
* @param {HTMLElement} rootElement
|
||||
|
||||
@@ -190,10 +190,30 @@ export default class Backgrounds {
|
||||
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
|
||||
if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
|
||||
|
||||
const contrastClass = this.getContrastClass( slide );
|
||||
|
||||
if( typeof contrastClass === 'string' ) {
|
||||
slide.classList.add( contrastClass );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a class name that can be applied to a slide to indicate
|
||||
* if it has a light or dark background.
|
||||
*
|
||||
* @param {*} slide
|
||||
*
|
||||
* @returns {string|null}
|
||||
*/
|
||||
getContrastClass( slide ) {
|
||||
|
||||
const element = slide.slideBackgroundElement;
|
||||
|
||||
// If this slide has a background color, we add a class that
|
||||
// signals if it is light or dark. If the slide has no background
|
||||
// color, no class will be added
|
||||
let contrastColor = data.backgroundColor;
|
||||
let contrastColor = slide.getAttribute( 'data-background-color' );
|
||||
|
||||
// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
|
||||
if( !contrastColor || !colorToRgb( contrastColor ) ) {
|
||||
@@ -211,14 +231,32 @@ export default class Backgrounds {
|
||||
// an element with no background
|
||||
if( rgb && rgb.a !== 0 ) {
|
||||
if( colorBrightness( contrastColor ) < 128 ) {
|
||||
slide.classList.add( 'has-dark-background' );
|
||||
return 'has-dark-background';
|
||||
}
|
||||
else {
|
||||
slide.classList.add( 'has-light-background' );
|
||||
return 'has-light-background';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Bubble the 'has-light-background'/'has-dark-background' classes.
|
||||
*/
|
||||
bubbleSlideContrastClassToElement( slide, target ) {
|
||||
|
||||
[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {
|
||||
if( slide.classList.contains( classToBubble ) ) {
|
||||
target.classList.add( classToBubble );
|
||||
}
|
||||
else {
|
||||
target.classList.remove( classToBubble );
|
||||
}
|
||||
}, this );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,14 +268,15 @@ export default class Backgrounds {
|
||||
*/
|
||||
update( includeAll = false ) {
|
||||
|
||||
let config = this.Reveal.getConfig();
|
||||
let currentSlide = this.Reveal.getCurrentSlide();
|
||||
let indices = this.Reveal.getIndices();
|
||||
|
||||
let currentBackground = null;
|
||||
|
||||
// Reverse past/future classes when in RTL mode
|
||||
let horizontalPast = this.Reveal.getConfig().rtl ? 'future' : 'past',
|
||||
horizontalFuture = this.Reveal.getConfig().rtl ? 'past' : 'future';
|
||||
let horizontalPast = config.rtl ? 'future' : 'past',
|
||||
horizontalFuture = config.rtl ? 'past' : 'future';
|
||||
|
||||
// Update the classes of all backgrounds to match the
|
||||
// states of their slides (past/present/future)
|
||||
@@ -263,10 +302,12 @@ export default class Backgrounds {
|
||||
|
||||
backgroundv.classList.remove( 'past', 'present', 'future' );
|
||||
|
||||
if( v < indices.v ) {
|
||||
const indexv = typeof indices.v === 'number' ? indices.v : 0;
|
||||
|
||||
if( v < indexv ) {
|
||||
backgroundv.classList.add( 'past' );
|
||||
}
|
||||
else if ( v > indices.v ) {
|
||||
else if ( v > indexv ) {
|
||||
backgroundv.classList.add( 'future' );
|
||||
}
|
||||
else {
|
||||
@@ -281,15 +322,53 @@ export default class Backgrounds {
|
||||
|
||||
} );
|
||||
|
||||
// The previous background may refer to a DOM element that has
|
||||
// been removed after a presentation is synced & bgs are recreated
|
||||
if( this.previousBackground && !this.previousBackground.closest( 'body' ) ) {
|
||||
this.previousBackground = null;
|
||||
}
|
||||
|
||||
if( currentBackground && this.previousBackground ) {
|
||||
|
||||
// Don't transition between identical backgrounds. This
|
||||
// prevents unwanted flicker.
|
||||
let previousBackgroundHash = this.previousBackground.getAttribute( 'data-background-hash' );
|
||||
let currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
|
||||
|
||||
if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {
|
||||
this.element.classList.add( 'no-transition' );
|
||||
|
||||
// If multiple slides have the same background video, carry
|
||||
// the <video> element forward so that it plays continuously
|
||||
// across multiple slides
|
||||
const currentVideo = currentBackground.querySelector( 'video' );
|
||||
const previousVideo = this.previousBackground.querySelector( 'video' );
|
||||
|
||||
if( currentVideo && previousVideo ) {
|
||||
|
||||
const currentVideoParent = currentVideo.parentNode;
|
||||
const previousVideoParent = previousVideo.parentNode;
|
||||
|
||||
// Swap the two videos
|
||||
previousVideoParent.appendChild( currentVideo );
|
||||
currentVideoParent.appendChild( previousVideo );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const backgroundChanged = currentBackground !== this.previousBackground;
|
||||
|
||||
// Stop content inside of previous backgrounds
|
||||
if( this.previousBackground ) {
|
||||
if( backgroundChanged && this.previousBackground ) {
|
||||
|
||||
this.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );
|
||||
|
||||
}
|
||||
|
||||
// Start content in the current background
|
||||
if( currentBackground ) {
|
||||
if( backgroundChanged && currentBackground ) {
|
||||
|
||||
this.Reveal.slideContent.startEmbeddedContent( currentBackground );
|
||||
|
||||
@@ -307,14 +386,6 @@ export default class Backgrounds {
|
||||
|
||||
}
|
||||
|
||||
// Don't transition between identical backgrounds. This
|
||||
// prevents unwanted flicker.
|
||||
let previousBackgroundHash = this.previousBackground ? this.previousBackground.getAttribute( 'data-background-hash' ) : null;
|
||||
let currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
|
||||
if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {
|
||||
this.element.classList.add( 'no-transition' );
|
||||
}
|
||||
|
||||
this.previousBackground = currentBackground;
|
||||
|
||||
}
|
||||
@@ -322,20 +393,13 @@ export default class Backgrounds {
|
||||
// If there's a background brightness flag for this slide,
|
||||
// bubble it to the .reveal container
|
||||
if( currentSlide ) {
|
||||
[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {
|
||||
if( currentSlide.classList.contains( classToBubble ) ) {
|
||||
this.Reveal.getRevealElement().classList.add( classToBubble );
|
||||
}
|
||||
else {
|
||||
this.Reveal.getRevealElement().classList.remove( classToBubble );
|
||||
}
|
||||
}, this );
|
||||
this.bubbleSlideContrastClassToElement( currentSlide, this.Reveal.getRevealElement() );
|
||||
}
|
||||
|
||||
// Allow the first background to apply without transition
|
||||
setTimeout( () => {
|
||||
this.element.classList.remove( 'no-transition' );
|
||||
}, 1 );
|
||||
}, 10 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
34
js/controllers/controls.js
vendored
@@ -1,4 +1,4 @@
|
||||
import { queryAll } from '../utils/util.js'
|
||||
import { queryAll, enterFullscreen } from '../utils/util.js'
|
||||
import { isAndroid } from '../utils/device.js'
|
||||
|
||||
/**
|
||||
@@ -12,6 +12,7 @@ import { isAndroid } from '../utils/device.js'
|
||||
* - .navigate-left
|
||||
* - .navigate-next
|
||||
* - .navigate-prev
|
||||
* - .enter-fullscreen
|
||||
*/
|
||||
export default class Controls {
|
||||
|
||||
@@ -25,6 +26,7 @@ export default class Controls {
|
||||
this.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );
|
||||
this.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );
|
||||
this.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );
|
||||
this.onEnterFullscreen = this.onEnterFullscreen.bind( this );
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +52,7 @@ export default class Controls {
|
||||
this.controlsDown = queryAll( revealElement, '.navigate-down' );
|
||||
this.controlsPrev = queryAll( revealElement, '.navigate-prev' );
|
||||
this.controlsNext = queryAll( revealElement, '.navigate-next' );
|
||||
this.controlsFullscreen = queryAll( revealElement, '.enter-fullscreen' );
|
||||
|
||||
// The left, right and down arrows in the standard reveal.js controls
|
||||
this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
|
||||
@@ -63,7 +66,10 @@ export default class Controls {
|
||||
*/
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
this.element.style.display = config.controls ? 'block' : 'none';
|
||||
this.element.style.display = (
|
||||
config.controls &&
|
||||
(config.controls !== 'speaker-only' || this.Reveal.isSpeakerNotes())
|
||||
) ? 'block' : 'none';
|
||||
|
||||
this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
|
||||
this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
|
||||
@@ -77,9 +83,10 @@ export default class Controls {
|
||||
let pointerEvents = [ 'touchstart', 'click' ];
|
||||
|
||||
// Only support touch for Android, fixes double navigations in
|
||||
// stock browser
|
||||
// stock browser. Use touchend for it to be considered a valid
|
||||
// user interaction (so we're allowed to autoplay media).
|
||||
if( isAndroid ) {
|
||||
pointerEvents = [ 'touchstart' ];
|
||||
pointerEvents = [ 'touchend' ];
|
||||
}
|
||||
|
||||
pointerEvents.forEach( eventName => {
|
||||
@@ -89,19 +96,21 @@ export default class Controls {
|
||||
this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||
this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||
this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||
this.controlsFullscreen.forEach( el => el.addEventListener( eventName, this.onEnterFullscreen, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
unbind() {
|
||||
|
||||
[ 'touchstart', 'click' ].forEach( eventName => {
|
||||
[ 'touchstart', 'touchend', 'click' ].forEach( eventName => {
|
||||
this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
|
||||
this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
|
||||
this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
|
||||
this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||
this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||
this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||
this.controlsFullscreen.forEach( el => el.removeEventListener( eventName, this.onEnterFullscreen, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
@@ -141,9 +150,14 @@ export default class Controls {
|
||||
if( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
const isVerticalStack = this.Reveal.isVerticalSlide( currentSlide );
|
||||
const hasVerticalSiblings = isVerticalStack &&
|
||||
currentSlide.parentElement &&
|
||||
currentSlide.parentElement.querySelectorAll( ':scope > section' ).length > 1;
|
||||
|
||||
// Apply fragment decorators to directional buttons based on
|
||||
// what slide axis they are in
|
||||
if( this.Reveal.isVerticalSlide( currentSlide ) ) {
|
||||
if( isVerticalStack && hasVerticalSiblings ) {
|
||||
if( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
}
|
||||
@@ -262,5 +276,13 @@ export default class Controls {
|
||||
|
||||
}
|
||||
|
||||
onEnterFullscreen( event ) {
|
||||
|
||||
const config = this.Reveal.getConfig();
|
||||
const viewport = this.Reveal.getViewportElement();
|
||||
|
||||
enterFullscreen( config.embedded ? viewport : viewport.parentElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -174,24 +174,23 @@ export default class Fragments {
|
||||
*
|
||||
* @return {{shown: array, hidden: array}}
|
||||
*/
|
||||
update( index, fragments ) {
|
||||
update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {
|
||||
|
||||
let changedFragments = {
|
||||
shown: [],
|
||||
hidden: []
|
||||
};
|
||||
|
||||
let currentSlide = this.Reveal.getCurrentSlide();
|
||||
if( currentSlide && this.Reveal.getConfig().fragments ) {
|
||||
if( slide && this.Reveal.getConfig().fragments ) {
|
||||
|
||||
fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );
|
||||
fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );
|
||||
|
||||
if( fragments.length ) {
|
||||
|
||||
let maxIndex = 0;
|
||||
|
||||
if( typeof index !== 'number' ) {
|
||||
let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
|
||||
let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
|
||||
if( currentFragment ) {
|
||||
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
||||
}
|
||||
@@ -252,12 +251,32 @@ export default class Fragments {
|
||||
// the current fragment index.
|
||||
index = typeof index === 'number' ? index : -1;
|
||||
index = Math.max( Math.min( index, maxIndex ), -1 );
|
||||
currentSlide.setAttribute( 'data-fragment', index );
|
||||
slide.setAttribute( 'data-fragment', index );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( changedFragments.hidden.length ) {
|
||||
this.Reveal.dispatchEvent({
|
||||
type: 'fragmenthidden',
|
||||
data: {
|
||||
fragment: changedFragments.hidden[0],
|
||||
fragments: changedFragments.hidden
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if( changedFragments.shown.length ) {
|
||||
this.Reveal.dispatchEvent({
|
||||
type: 'fragmentshown',
|
||||
data: {
|
||||
fragment: changedFragments.shown[0],
|
||||
fragments: changedFragments.shown
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return changedFragments;
|
||||
|
||||
}
|
||||
@@ -312,26 +331,6 @@ export default class Fragments {
|
||||
|
||||
let changedFragments = this.update( index, fragments );
|
||||
|
||||
if( changedFragments.hidden.length ) {
|
||||
this.Reveal.dispatchEvent({
|
||||
type: 'fragmenthidden',
|
||||
data: {
|
||||
fragment: changedFragments.hidden[0],
|
||||
fragments: changedFragments.hidden
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if( changedFragments.shown.length ) {
|
||||
this.Reveal.dispatchEvent({
|
||||
type: 'fragmentshown',
|
||||
data: {
|
||||
fragment: changedFragments.shown[0],
|
||||
fragments: changedFragments.shown
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.Reveal.controls.update();
|
||||
this.Reveal.progress.update();
|
||||
|
||||
|
||||
197
js/controllers/jumptoslide.js
Normal file
@@ -0,0 +1,197 @@
|
||||
import {
|
||||
SLIDE_NUMBER_FORMAT_CURRENT,
|
||||
SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL
|
||||
} from "../utils/constants";
|
||||
|
||||
/**
|
||||
* Makes it possible to jump to a slide by entering its
|
||||
* slide number or id.
|
||||
*/
|
||||
export default class JumpToSlide {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.onInput = this.onInput.bind( this );
|
||||
this.onBlur = this.onBlur.bind( this );
|
||||
this.onKeyDown = this.onKeyDown.bind( this );
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
this.element = document.createElement( 'div' );
|
||||
this.element.className = 'jump-to-slide';
|
||||
|
||||
this.jumpInput = document.createElement( 'input' );
|
||||
this.jumpInput.type = 'text';
|
||||
this.jumpInput.className = 'jump-to-slide-input';
|
||||
this.jumpInput.placeholder = 'Jump to slide';
|
||||
this.jumpInput.addEventListener( 'input', this.onInput );
|
||||
this.jumpInput.addEventListener( 'keydown', this.onKeyDown );
|
||||
this.jumpInput.addEventListener( 'blur', this.onBlur );
|
||||
|
||||
this.element.appendChild( this.jumpInput );
|
||||
|
||||
}
|
||||
|
||||
show() {
|
||||
|
||||
this.indicesOnShow = this.Reveal.getIndices();
|
||||
|
||||
this.Reveal.getRevealElement().appendChild( this.element );
|
||||
this.jumpInput.focus();
|
||||
|
||||
}
|
||||
|
||||
hide() {
|
||||
|
||||
if( this.isVisible() ) {
|
||||
this.element.remove();
|
||||
this.jumpInput.value = '';
|
||||
|
||||
clearTimeout( this.jumpTimeout );
|
||||
delete this.jumpTimeout;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isVisible() {
|
||||
|
||||
return !!this.element.parentNode;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current input and jumps to the given slide.
|
||||
*/
|
||||
jump() {
|
||||
|
||||
clearTimeout( this.jumpTimeout );
|
||||
delete this.jumpTimeout;
|
||||
|
||||
let query = this.jumpInput.value.trim( '' );
|
||||
let indices;
|
||||
|
||||
// When slide numbers are formatted to be a single linear number
|
||||
// (instead of showing a separate horizontal/vertical index) we
|
||||
// use the same format for slide jumps
|
||||
if( /^\d+$/.test( query ) ) {
|
||||
const slideNumberFormat = this.Reveal.getConfig().slideNumber;
|
||||
if( slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT || slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL ) {
|
||||
const slide = this.Reveal.getSlides()[ parseInt( query, 10 ) - 1 ];
|
||||
if( slide ) {
|
||||
indices = this.Reveal.getIndices( slide );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !indices ) {
|
||||
// If the query uses "horizontal.vertical" format, convert to
|
||||
// "horizontal/vertical" so that our URL parser can understand
|
||||
if( /^\d+\.\d+$/.test( query ) ) {
|
||||
query = query.replace( '.', '/' );
|
||||
}
|
||||
|
||||
indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );
|
||||
}
|
||||
|
||||
// Still no valid index? Fall back on a text search
|
||||
if( !indices && /\S+/i.test( query ) && query.length > 1 ) {
|
||||
indices = this.search( query );
|
||||
}
|
||||
|
||||
if( indices && query !== '' ) {
|
||||
this.Reveal.slide( indices.h, indices.v, indices.f );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
jumpAfter( delay ) {
|
||||
|
||||
clearTimeout( this.jumpTimeout );
|
||||
this.jumpTimeout = setTimeout( () => this.jump(), delay );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A lofi search that looks for the given query in all
|
||||
* of our slides and returns the first match.
|
||||
*/
|
||||
search( query ) {
|
||||
|
||||
const regex = new RegExp( '\\b' + query.trim() + '\\b', 'i' );
|
||||
|
||||
const slide = this.Reveal.getSlides().find( ( slide ) => {
|
||||
return regex.test( slide.innerText );
|
||||
} );
|
||||
|
||||
if( slide ) {
|
||||
return this.Reveal.getIndices( slide );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts back to the slide we were on when jump to slide was
|
||||
* invoked.
|
||||
*/
|
||||
cancel() {
|
||||
|
||||
this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
|
||||
this.hide();
|
||||
|
||||
}
|
||||
|
||||
confirm() {
|
||||
|
||||
this.jump();
|
||||
this.hide();
|
||||
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
||||
this.jumpInput.removeEventListener( 'input', this.onInput );
|
||||
this.jumpInput.removeEventListener( 'keydown', this.onKeyDown );
|
||||
this.jumpInput.removeEventListener( 'blur', this.onBlur );
|
||||
|
||||
this.element.remove();
|
||||
|
||||
}
|
||||
|
||||
onKeyDown( event ) {
|
||||
|
||||
if( event.keyCode === 13 ) {
|
||||
this.confirm();
|
||||
}
|
||||
else if( event.keyCode === 27 ) {
|
||||
this.cancel();
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onInput( event ) {
|
||||
|
||||
this.jumpAfter( 200 );
|
||||
|
||||
}
|
||||
|
||||
onBlur() {
|
||||
|
||||
setTimeout( () => this.hide(), 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,6 @@ export default class Keyboard {
|
||||
this.bindings = {};
|
||||
|
||||
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
||||
this.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +42,7 @@ export default class Keyboard {
|
||||
this.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';
|
||||
this.shortcuts['B , .'] = 'Pause';
|
||||
this.shortcuts['F'] = 'Fullscreen';
|
||||
this.shortcuts['G'] = 'Jump to slide';
|
||||
this.shortcuts['ESC, O'] = 'Slide overview';
|
||||
|
||||
}
|
||||
@@ -53,7 +53,6 @@ export default class Keyboard {
|
||||
bind() {
|
||||
|
||||
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||
document.addEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +62,6 @@ export default class Keyboard {
|
||||
unbind() {
|
||||
|
||||
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||
document.removeEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||
|
||||
}
|
||||
|
||||
@@ -134,20 +132,6 @@ export default class Keyboard {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'keypress' event.
|
||||
*
|
||||
* @param {object} event
|
||||
*/
|
||||
onDocumentKeyPress( event ) {
|
||||
|
||||
// Check if the pressed key is question mark
|
||||
if( event.shiftKey && event.charCode === 63 ) {
|
||||
this.Reveal.toggleHelp();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'keydown' event.
|
||||
*
|
||||
@@ -183,10 +167,10 @@ export default class Keyboard {
|
||||
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
||||
|
||||
// Whitelist certain modifiers for slide navigation shortcuts
|
||||
let isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1;
|
||||
let keyCodeUsesModifier = [32, 37, 38, 39, 40, 63, 78, 80, 191].indexOf( event.keyCode ) !== -1;
|
||||
|
||||
// Prevent all other events when a modifier is pressed
|
||||
let unusedModifier = !( isNavigationKey && event.shiftKey || event.altKey ) &&
|
||||
let unusedModifier = !( keyCodeUsesModifier && event.shiftKey || event.altKey ) &&
|
||||
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
||||
|
||||
// Disregard the event if there's a focused element or a
|
||||
@@ -194,7 +178,7 @@ export default class Keyboard {
|
||||
if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
|
||||
|
||||
// While paused only allow resume keyboard events; 'b', 'v', '.'
|
||||
let resumeKeyCodes = [66,86,190,191];
|
||||
let resumeKeyCodes = [66,86,190,191,112];
|
||||
let key;
|
||||
|
||||
// Custom key bindings for togglePause should be able to resume
|
||||
@@ -206,6 +190,10 @@ export default class Keyboard {
|
||||
}
|
||||
}
|
||||
|
||||
if( this.Reveal.isOverlayOpen() && !["Escape", "f", "c", "b", "."].includes(event.key) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
|
||||
return false;
|
||||
}
|
||||
@@ -287,7 +275,12 @@ export default class Keyboard {
|
||||
this.Reveal.slide( 0 );
|
||||
}
|
||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||
this.Reveal.prev({skipFragments: event.altKey});
|
||||
if( config.rtl ) {
|
||||
this.Reveal.next({skipFragments: event.altKey});
|
||||
}
|
||||
else {
|
||||
this.Reveal.prev({skipFragments: event.altKey});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.Reveal.left({skipFragments: event.altKey});
|
||||
@@ -299,7 +292,12 @@ export default class Keyboard {
|
||||
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
|
||||
}
|
||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||
this.Reveal.next({skipFragments: event.altKey});
|
||||
if( config.rtl ) {
|
||||
this.Reveal.prev({skipFragments: event.altKey});
|
||||
}
|
||||
else {
|
||||
this.Reveal.next({skipFragments: event.altKey});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.Reveal.right({skipFragments: event.altKey});
|
||||
@@ -350,7 +348,7 @@ export default class Keyboard {
|
||||
}
|
||||
}
|
||||
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
||||
else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
|
||||
else if( [58, 59, 66, 86, 190].includes( keyCode ) || ( keyCode === 191 && !event.shiftKey ) ) {
|
||||
this.Reveal.togglePause();
|
||||
}
|
||||
// F
|
||||
@@ -359,10 +357,28 @@ export default class Keyboard {
|
||||
}
|
||||
// A
|
||||
else if( keyCode === 65 ) {
|
||||
if ( config.autoSlideStoppable ) {
|
||||
if( config.autoSlideStoppable ) {
|
||||
this.Reveal.toggleAutoSlide( autoSlideWasPaused );
|
||||
}
|
||||
}
|
||||
// G
|
||||
else if( keyCode === 71 ) {
|
||||
if( config.jumpToSlide ) {
|
||||
this.Reveal.toggleJumpToSlide();
|
||||
}
|
||||
}
|
||||
// C
|
||||
else if( keyCode === 67 && this.Reveal.isOverlayOpen() ) {
|
||||
this.Reveal.closeOverlay();
|
||||
}
|
||||
// ?
|
||||
else if( ( keyCode === 63 || keyCode === 191 ) && event.shiftKey ) {
|
||||
this.Reveal.toggleHelp();
|
||||
}
|
||||
// F1
|
||||
else if( keyCode === 112 ) {
|
||||
this.Reveal.toggleHelp();
|
||||
}
|
||||
else {
|
||||
triggered = false;
|
||||
}
|
||||
@@ -382,6 +398,12 @@ export default class Keyboard {
|
||||
|
||||
event.preventDefault && event.preventDefault();
|
||||
}
|
||||
|
||||
// Enter to exit overview mode
|
||||
else if (keyCode === 13 && this.Reveal.overview.isActive()) {
|
||||
this.Reveal.overview.deactivate();
|
||||
event.preventDefault && event.preventDefault();
|
||||
}
|
||||
|
||||
// If auto-sliding is enabled we need to cue up
|
||||
// another timeout
|
||||
@@ -389,4 +411,4 @@ export default class Keyboard {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class Location {
|
||||
*
|
||||
* @returns slide indices or null
|
||||
*/
|
||||
getIndicesFromHash( hash=window.location.hash ) {
|
||||
getIndicesFromHash( hash=window.location.hash, options={} ) {
|
||||
|
||||
// Attempt to parse the hash as either an index or name
|
||||
let name = hash.replace( /^#\/?/, '' );
|
||||
@@ -49,7 +49,7 @@ export default class Location {
|
||||
// If the first bit is not fully numeric and there is a name we
|
||||
// can assume that this is a named link
|
||||
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
||||
let element;
|
||||
let slide;
|
||||
|
||||
let f;
|
||||
|
||||
@@ -60,19 +60,23 @@ export default class Location {
|
||||
name = name.split( '/' ).shift();
|
||||
}
|
||||
|
||||
// Ensure the named link is a valid HTML ID attribute
|
||||
// Ensure the named link is a valid HTML id or data-id attribute
|
||||
try {
|
||||
element = document.getElementById( decodeURIComponent( name ) );
|
||||
const decodedName = decodeURIComponent( name );
|
||||
slide = (
|
||||
document.getElementById( decodedName ) ||
|
||||
document.querySelector( `[data-id="${decodedName}"]` )
|
||||
).closest('.slides section');
|
||||
}
|
||||
catch ( error ) { }
|
||||
|
||||
if( element ) {
|
||||
return { ...this.Reveal.getIndices( element ), f };
|
||||
if( slide ) {
|
||||
return { ...this.Reveal.getIndices( slide ), f };
|
||||
}
|
||||
}
|
||||
else {
|
||||
const config = this.Reveal.getConfig();
|
||||
let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
|
||||
let hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0;
|
||||
|
||||
// Read the index components of the hash
|
||||
let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
|
||||
@@ -139,7 +143,7 @@ export default class Location {
|
||||
let hash = this.getHash();
|
||||
|
||||
// If we're configured to push to history OR the history
|
||||
// API is not avaialble.
|
||||
// API is not available.
|
||||
if( config.history ) {
|
||||
window.location.hash = hash;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,12 @@ export default class Notes {
|
||||
*/
|
||||
update() {
|
||||
|
||||
if( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {
|
||||
|
||||
if( this.Reveal.getConfig().showNotes &&
|
||||
this.element && this.Reveal.getCurrentSlide() &&
|
||||
!this.Reveal.isScrollView() &&
|
||||
!this.Reveal.isPrintView()
|
||||
) {
|
||||
this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,7 +56,11 @@ export default class Notes {
|
||||
*/
|
||||
updateVisibility() {
|
||||
|
||||
if( this.Reveal.getConfig().showNotes && this.hasNotes() && !this.Reveal.print.isPrintingPDF() ) {
|
||||
if( this.Reveal.getConfig().showNotes &&
|
||||
this.hasNotes() &&
|
||||
!this.Reveal.isScrollView() &&
|
||||
!this.Reveal.isPrintView()
|
||||
) {
|
||||
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
||||
}
|
||||
else {
|
||||
|
||||
389
js/controllers/overlay.js
Normal file
@@ -0,0 +1,389 @@
|
||||
/**
|
||||
* Handles the display of reveal.js' overlay elements used
|
||||
* to preview iframes, images & videos.
|
||||
*/
|
||||
export default class Overlay {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.onSlidesClicked = this.onSlidesClicked.bind( this );
|
||||
|
||||
this.iframeTriggerSelector = null;
|
||||
this.mediaTriggerSelector = '[data-preview-image], [data-preview-video]';
|
||||
|
||||
this.stateProps = ['previewIframe', 'previewImage', 'previewVideo', 'previewFit'];
|
||||
this.state = {};
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
// Enable link previews globally
|
||||
if( this.Reveal.getConfig().previewLinks ) {
|
||||
this.iframeTriggerSelector = 'a[href]:not([data-preview-link=false]), [data-preview-link]:not(a):not([data-preview-link=false])';
|
||||
}
|
||||
// Enable link previews for individual elements
|
||||
else {
|
||||
this.iframeTriggerSelector = '[data-preview-link]:not([data-preview-link=false])';
|
||||
}
|
||||
|
||||
const hasLinkPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.iframeTriggerSelector ).length > 0;
|
||||
const hasMediaPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.mediaTriggerSelector ).length > 0;
|
||||
|
||||
// Only add the listener when there are previewable elements in the slides
|
||||
if( hasLinkPreviews || hasMediaPreviews ) {
|
||||
this.Reveal.getSlidesElement().addEventListener( 'click', this.onSlidesClicked, false );
|
||||
}
|
||||
else {
|
||||
this.Reveal.getSlidesElement().removeEventListener( 'click', this.onSlidesClicked, false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createOverlay( className ) {
|
||||
|
||||
this.dom = document.createElement( 'div' );
|
||||
this.dom.classList.add( 'r-overlay' );
|
||||
this.dom.classList.add( className );
|
||||
|
||||
this.viewport = document.createElement( 'div' );
|
||||
this.viewport.classList.add( 'r-overlay-viewport' );
|
||||
|
||||
this.dom.appendChild( this.viewport );
|
||||
this.Reveal.getRevealElement().appendChild( this.dom );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a lightbox that previews the target URL.
|
||||
*
|
||||
* @param {string} url - url for lightbox iframe src
|
||||
*/
|
||||
previewIframe( url ) {
|
||||
|
||||
this.close();
|
||||
|
||||
this.state = { previewIframe: url };
|
||||
|
||||
this.createOverlay( 'r-overlay-preview' );
|
||||
this.dom.dataset.state = 'loading';
|
||||
|
||||
this.viewport.innerHTML =
|
||||
`<header class="r-overlay-header">
|
||||
<a class="r-overlay-button r-overlay-external" href="${url}" target="_blank"><span class="icon"></span></a>
|
||||
<button class="r-overlay-button r-overlay-close"><span class="icon"></span></button>
|
||||
</header>
|
||||
<div class="r-overlay-spinner"></div>
|
||||
<div class="r-overlay-content">
|
||||
<iframe src="${url}"></iframe>
|
||||
<small class="r-overlay-content-inner">
|
||||
<span class="r-overlay-error x-frame-error">Unable to load iframe. This is likely due to the site's policy (x-frame-options).</span>
|
||||
</small>
|
||||
</div>`;
|
||||
|
||||
this.dom.querySelector( 'iframe' ).addEventListener( 'load', event => {
|
||||
this.dom.dataset.state = 'loaded';
|
||||
}, false );
|
||||
|
||||
this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {
|
||||
this.close();
|
||||
event.preventDefault();
|
||||
}, false );
|
||||
|
||||
this.dom.querySelector( '.r-overlay-external' ).addEventListener( 'click', event => {
|
||||
this.close();
|
||||
}, false );
|
||||
|
||||
this.Reveal.dispatchEvent({ type: 'previewiframe', data: { url } });
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a lightbox window that provides a larger view of the
|
||||
* given image/video.
|
||||
*
|
||||
* @param {string} url - url to the image/video to preview
|
||||
* @param {image|video} mediaType
|
||||
* @param {string} [fitMode] - the fit mode to use for the preview
|
||||
*/
|
||||
previewMedia( url, mediaType, fitMode ) {
|
||||
|
||||
if( mediaType !== 'image' && mediaType !== 'video' ) {
|
||||
console.warn( 'Please specify a valid media type to preview (image|video)' );
|
||||
return;
|
||||
}
|
||||
|
||||
this.close();
|
||||
|
||||
fitMode = fitMode || 'scale-down';
|
||||
|
||||
this.createOverlay( 'r-overlay-preview' );
|
||||
this.dom.dataset.state = 'loading';
|
||||
this.dom.dataset.previewFit = fitMode;
|
||||
|
||||
this.viewport.innerHTML =
|
||||
`<header class="r-overlay-header">
|
||||
<button class="r-overlay-button r-overlay-close">Esc <span class="icon"></span></button>
|
||||
</header>
|
||||
<div class="r-overlay-spinner"></div>
|
||||
<div class="r-overlay-content"></div>`;
|
||||
|
||||
const contentElement = this.dom.querySelector( '.r-overlay-content' );
|
||||
|
||||
if( mediaType === 'image' ) {
|
||||
|
||||
this.state = { previewImage: url, previewFit: fitMode }
|
||||
|
||||
const img = document.createElement( 'img', {} );
|
||||
img.src = url;
|
||||
contentElement.appendChild( img );
|
||||
|
||||
img.addEventListener( 'load', () => {
|
||||
this.dom.dataset.state = 'loaded';
|
||||
}, false );
|
||||
|
||||
img.addEventListener( 'error', () => {
|
||||
this.dom.dataset.state = 'error';
|
||||
contentElement.innerHTML =
|
||||
`<span class="r-overlay-error">Unable to load image.</span>`
|
||||
}, false );
|
||||
|
||||
// Hide image overlays when clicking outside the overlay
|
||||
this.dom.style.cursor = 'zoom-out';
|
||||
this.dom.addEventListener( 'click', ( event ) => {
|
||||
this.close();
|
||||
}, false );
|
||||
|
||||
this.Reveal.dispatchEvent({ type: 'previewimage', data: { url } });
|
||||
|
||||
}
|
||||
else if( mediaType === 'video' ) {
|
||||
|
||||
this.state = { previewVideo: url, previewFit: fitMode }
|
||||
|
||||
const video = document.createElement( 'video' );
|
||||
video.autoplay = this.dom.dataset.previewAutoplay === 'false' ? false : true;
|
||||
video.controls = this.dom.dataset.previewControls === 'false' ? false : true;
|
||||
video.loop = this.dom.dataset.previewLoop === 'true' ? true : false;
|
||||
video.muted = this.dom.dataset.previewMuted === 'true' ? true : false;
|
||||
video.playsInline = true;
|
||||
video.src = url;
|
||||
contentElement.appendChild( video );
|
||||
|
||||
video.addEventListener( 'loadeddata', () => {
|
||||
this.dom.dataset.state = 'loaded';
|
||||
}, false );
|
||||
|
||||
video.addEventListener( 'error', () => {
|
||||
this.dom.dataset.state = 'error';
|
||||
contentElement.innerHTML =
|
||||
`<span class="r-overlay-error">Unable to load video.</span>`;
|
||||
}, false );
|
||||
|
||||
this.Reveal.dispatchEvent({ type: 'previewvideo', data: { url } });
|
||||
|
||||
}
|
||||
else {
|
||||
throw new Error( 'Please specify a valid media type to preview' );
|
||||
}
|
||||
|
||||
this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', ( event ) => {
|
||||
this.close();
|
||||
event.preventDefault();
|
||||
}, false );
|
||||
|
||||
}
|
||||
|
||||
previewImage( url, fitMode ) {
|
||||
|
||||
this.previewMedia( url, 'image', fitMode );
|
||||
|
||||
}
|
||||
|
||||
previewVideo( url, fitMode ) {
|
||||
|
||||
this.previewMedia( url, 'video', fitMode );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open or close help overlay window.
|
||||
*
|
||||
* @param {Boolean} [override] Flag which overrides the
|
||||
* toggle logic and forcibly sets the desired state. True means
|
||||
* help is open, false means it's closed.
|
||||
*/
|
||||
toggleHelp( override ) {
|
||||
|
||||
if( typeof override === 'boolean' ) {
|
||||
override ? this.showHelp() : this.close();
|
||||
}
|
||||
else {
|
||||
if( this.dom ) {
|
||||
this.close();
|
||||
}
|
||||
else {
|
||||
this.showHelp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an overlay window with help material.
|
||||
*/
|
||||
showHelp() {
|
||||
|
||||
if( this.Reveal.getConfig().help ) {
|
||||
|
||||
this.close();
|
||||
|
||||
this.createOverlay( 'r-overlay-help' );
|
||||
|
||||
let html = '<p class="title">Keyboard Shortcuts</p>';
|
||||
|
||||
let shortcuts = this.Reveal.keyboard.getShortcuts(),
|
||||
bindings = this.Reveal.keyboard.getBindings();
|
||||
|
||||
html += '<table><th>KEY</th><th>ACTION</th>';
|
||||
for( let key in shortcuts ) {
|
||||
html += `<tr><td>${key}</td><td>${shortcuts[ key ]}</td></tr>`;
|
||||
}
|
||||
|
||||
// Add custom key bindings that have associated descriptions
|
||||
for( let binding in bindings ) {
|
||||
if( bindings[binding].key && bindings[binding].description ) {
|
||||
html += `<tr><td>${bindings[binding].key}</td><td>${bindings[binding].description}</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
html += '</table>';
|
||||
|
||||
this.viewport.innerHTML = `
|
||||
<header class="r-overlay-header">
|
||||
<button class="r-overlay-button r-overlay-close">Esc <span class="icon"></span></button>
|
||||
</header>
|
||||
<div class="r-overlay-content">
|
||||
<div class="r-overlay-help-content">${html}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {
|
||||
this.close();
|
||||
event.preventDefault();
|
||||
}, false );
|
||||
|
||||
this.Reveal.dispatchEvent({ type: 'showhelp' });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isOpen() {
|
||||
|
||||
return !!this.dom;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes any currently open overlay.
|
||||
*/
|
||||
close() {
|
||||
|
||||
if( this.dom ) {
|
||||
this.dom.remove();
|
||||
this.dom = null;
|
||||
|
||||
this.state = {};
|
||||
|
||||
this.Reveal.dispatchEvent({ type: 'closeoverlay' });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
getState() {
|
||||
|
||||
return this.state;
|
||||
|
||||
}
|
||||
|
||||
setState( state ) {
|
||||
|
||||
// Ignore the incoming state if none of the preview related
|
||||
// props have changed
|
||||
if( this.stateProps.every( key => this.state[ key ] === state[ key ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( state.previewIframe ) {
|
||||
this.previewIframe( state.previewIframe );
|
||||
}
|
||||
else if( state.previewImage ) {
|
||||
this.previewImage( state.previewImage, state.previewFit );
|
||||
}
|
||||
else if( state.previewVideo ) {
|
||||
this.previewVideo( state.previewVideo, state.previewFit );
|
||||
}
|
||||
else {
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onSlidesClicked( event ) {
|
||||
|
||||
const target = event.target;
|
||||
|
||||
const linkTarget = target.closest( this.iframeTriggerSelector );
|
||||
const mediaTarget = target.closest( this.mediaTriggerSelector );
|
||||
|
||||
// Was an iframe lightbox trigger clicked?
|
||||
if( linkTarget ) {
|
||||
if( event.metaKey || event.shiftKey || event.altKey ) {
|
||||
// Let the browser handle meta keys naturally so users can cmd+click
|
||||
return;
|
||||
}
|
||||
let url = linkTarget.getAttribute( 'href' ) || linkTarget.getAttribute( 'data-preview-link' );
|
||||
if( url ) {
|
||||
this.previewIframe( url );
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
// Was a media lightbox trigger clicked?
|
||||
else if( mediaTarget ) {
|
||||
if( mediaTarget.hasAttribute( 'data-preview-image' ) ) {
|
||||
let url = mediaTarget.dataset.previewImage || mediaTarget.getAttribute( 'src' );
|
||||
if( url ) {
|
||||
this.previewImage( url, mediaTarget.dataset.previewFit );
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
else if( mediaTarget.hasAttribute( 'data-preview-video' ) ) {
|
||||
let url = mediaTarget.dataset.previewVideo || mediaTarget.getAttribute( 'src' );
|
||||
if( !url ) {
|
||||
let source = mediaTarget.querySelector( 'source' );
|
||||
if( source ) {
|
||||
url = source.getAttribute( 'src' );
|
||||
}
|
||||
}
|
||||
if( url ) {
|
||||
this.previewVideo( url, mediaTarget.dataset.previewFit );
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
||||
this.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export default class Overview {
|
||||
activate() {
|
||||
|
||||
// Only proceed if enabled in config
|
||||
if( this.Reveal.getConfig().overview && !this.isActive() ) {
|
||||
if( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {
|
||||
|
||||
this.active = true;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export default class Plugins {
|
||||
// Flags our current state (idle -> loading -> loaded)
|
||||
this.state = 'idle';
|
||||
|
||||
// An id:instance map of currently registed plugins
|
||||
// An id:instance map of currently registered plugins
|
||||
this.registeredPlugins = {};
|
||||
|
||||
this.asyncDependencies = [];
|
||||
@@ -171,7 +171,7 @@ export default class Plugins {
|
||||
/**
|
||||
* Registers a new plugin with this reveal.js instance.
|
||||
*
|
||||
* reveal.js waits for all regisered plugins to initialize
|
||||
* reveal.js waits for all registered plugins to initialize
|
||||
* before considering itself ready, as long as the plugin
|
||||
* is registered before calling `Reveal.initialize()`.
|
||||
*/
|
||||
|
||||
@@ -27,12 +27,10 @@ export default class Pointer {
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
if( config.mouseWheel ) {
|
||||
document.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
||||
document.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
||||
document.addEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||
}
|
||||
else {
|
||||
document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
||||
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
||||
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||
}
|
||||
|
||||
// Auto-hide the mouse pointer when its inactive
|
||||
@@ -79,8 +77,7 @@ export default class Pointer {
|
||||
|
||||
this.showCursor();
|
||||
|
||||
document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false );
|
||||
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
||||
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||
document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
|
||||
document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
|
||||
|
||||
@@ -126,4 +123,4 @@ export default class Pointer {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { queryAll, createStyleSheet } from '../utils/util.js'
|
||||
/**
|
||||
* Setups up our presentation for printing/exporting to PDF.
|
||||
*/
|
||||
export default class Print {
|
||||
export default class PrintView {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
@@ -16,7 +16,7 @@ export default class Print {
|
||||
* Configures the presentation for printing to a static
|
||||
* PDF.
|
||||
*/
|
||||
async setupPDF() {
|
||||
async activate() {
|
||||
|
||||
const config = this.Reveal.getConfig();
|
||||
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
|
||||
@@ -42,11 +42,11 @@ export default class Print {
|
||||
// Limit the size of certain elements to the dimensions of the slide
|
||||
createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
|
||||
|
||||
document.documentElement.classList.add( 'print-pdf' );
|
||||
document.documentElement.classList.add( 'reveal-print', 'print-pdf' );
|
||||
document.body.style.width = pageWidth + 'px';
|
||||
document.body.style.height = pageHeight + 'px';
|
||||
|
||||
const viewportElement = document.querySelector( '.reveal-viewport' );
|
||||
const viewportElement = this.Reveal.getViewportElement();
|
||||
let presentationBackground;
|
||||
if( viewportElement ) {
|
||||
const viewportStyles = window.getComputedStyle( viewportElement );
|
||||
@@ -223,15 +223,17 @@ export default class Print {
|
||||
// Notify subscribers that the PDF layout is good to go
|
||||
this.Reveal.dispatchEvent({ type: 'pdf-ready' });
|
||||
|
||||
viewportElement.classList.remove( 'loading-scroll-mode' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this instance is being used to print a PDF.
|
||||
* Checks if the print mode is/should be activated.
|
||||
*/
|
||||
isPrintingPDF() {
|
||||
isActive() {
|
||||
|
||||
return ( /print-pdf/gi ).test( window.location.search );
|
||||
return this.Reveal.getConfig().view === 'print';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
923
js/controllers/scrollview.js
Normal file
@@ -0,0 +1,923 @@
|
||||
import { HORIZONTAL_SLIDES_SELECTOR, HORIZONTAL_BACKGROUNDS_SELECTOR } from '../utils/constants.js'
|
||||
import { queryAll } from '../utils/util.js'
|
||||
|
||||
const HIDE_SCROLLBAR_TIMEOUT = 500;
|
||||
const MAX_PROGRESS_SPACING = 4;
|
||||
const MIN_PROGRESS_SEGMENT_HEIGHT = 6;
|
||||
const MIN_PLAYHEAD_HEIGHT = 8;
|
||||
|
||||
/**
|
||||
* The scroll view lets you read a reveal.js presentation
|
||||
* as a linear scrollable page.
|
||||
*/
|
||||
export default class ScrollView {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.active = false;
|
||||
this.activatedCallbacks = [];
|
||||
|
||||
this.onScroll = this.onScroll.bind( this );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the scroll view. This rearranges the presentation DOM
|
||||
* by—among other things—wrapping each slide in a page element.
|
||||
*/
|
||||
activate() {
|
||||
|
||||
if( this.active ) return;
|
||||
|
||||
const stateBeforeActivation = this.Reveal.getState();
|
||||
|
||||
this.active = true;
|
||||
|
||||
// Store the full presentation HTML so that we can restore it
|
||||
// when/if the scroll view is deactivated
|
||||
this.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;
|
||||
|
||||
const horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );
|
||||
const horizontalBackgrounds = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_BACKGROUNDS_SELECTOR );
|
||||
|
||||
this.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-scroll' );
|
||||
|
||||
let presentationBackground;
|
||||
|
||||
const viewportStyles = window.getComputedStyle( this.viewportElement );
|
||||
if( viewportStyles && viewportStyles.background ) {
|
||||
presentationBackground = viewportStyles.background;
|
||||
}
|
||||
|
||||
const pageElements = [];
|
||||
const pageContainer = horizontalSlides[0].parentNode;
|
||||
|
||||
let previousSlide;
|
||||
|
||||
// Creates a new page element and appends the given slide/bg
|
||||
// to it.
|
||||
const createPageElement = ( slide, h, v, isVertical ) => {
|
||||
|
||||
let contentContainer;
|
||||
|
||||
// If this slide is part of an auto-animation sequence, we
|
||||
// group it under the same page element as the previous slide
|
||||
if( previousSlide && this.Reveal.shouldAutoAnimateBetween( previousSlide, slide ) ) {
|
||||
contentContainer = document.createElement( 'div' );
|
||||
contentContainer.className = 'scroll-page-content scroll-auto-animate-page';
|
||||
contentContainer.style.display = 'none';
|
||||
previousSlide.closest( '.scroll-page-content' ).parentNode.appendChild( contentContainer );
|
||||
}
|
||||
else {
|
||||
// Wrap the slide in a page element and hide its overflow
|
||||
// so that no page ever flows onto another
|
||||
const page = document.createElement( 'div' );
|
||||
page.className = 'scroll-page';
|
||||
pageElements.push( page );
|
||||
|
||||
// This transfers over the background of the vertical stack containing
|
||||
// the slide if it exists. Otherwise, it uses the presentation-wide
|
||||
// background.
|
||||
if( isVertical && horizontalBackgrounds.length > h ) {
|
||||
const slideBackground = horizontalBackgrounds[h];
|
||||
const pageBackground = window.getComputedStyle( slideBackground );
|
||||
|
||||
if( pageBackground && pageBackground.background ) {
|
||||
page.style.background = pageBackground.background;
|
||||
}
|
||||
else if( presentationBackground ) {
|
||||
page.style.background = presentationBackground;
|
||||
}
|
||||
} else if( presentationBackground ) {
|
||||
page.style.background = presentationBackground;
|
||||
}
|
||||
|
||||
const stickyContainer = document.createElement( 'div' );
|
||||
stickyContainer.className = 'scroll-page-sticky';
|
||||
page.appendChild( stickyContainer );
|
||||
|
||||
contentContainer = document.createElement( 'div' );
|
||||
contentContainer.className = 'scroll-page-content';
|
||||
stickyContainer.appendChild( contentContainer );
|
||||
}
|
||||
|
||||
contentContainer.appendChild( slide );
|
||||
|
||||
slide.classList.remove( 'past', 'future' );
|
||||
slide.setAttribute( 'data-index-h', h );
|
||||
slide.setAttribute( 'data-index-v', v );
|
||||
|
||||
if( slide.slideBackgroundElement ) {
|
||||
slide.slideBackgroundElement.remove( 'past', 'future' );
|
||||
contentContainer.insertBefore( slide.slideBackgroundElement, slide );
|
||||
}
|
||||
|
||||
previousSlide = slide;
|
||||
|
||||
}
|
||||
|
||||
// Slide and slide background layout
|
||||
horizontalSlides.forEach( ( horizontalSlide, h ) => {
|
||||
|
||||
if( this.Reveal.isVerticalStack( horizontalSlide ) ) {
|
||||
horizontalSlide.querySelectorAll( 'section' ).forEach( ( verticalSlide, v ) => {
|
||||
createPageElement( verticalSlide, h, v, true );
|
||||
});
|
||||
}
|
||||
else {
|
||||
createPageElement( horizontalSlide, h, 0 );
|
||||
}
|
||||
|
||||
}, this );
|
||||
|
||||
this.createProgressBar();
|
||||
|
||||
// Remove leftover stacks
|
||||
queryAll( this.Reveal.getRevealElement(), '.stack' ).forEach( stack => stack.remove() );
|
||||
|
||||
// Add our newly created pages to the DOM
|
||||
pageElements.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() );
|
||||
|
||||
this.Reveal.layout();
|
||||
this.Reveal.setState( stateBeforeActivation );
|
||||
|
||||
this.activatedCallbacks.forEach( callback => callback() );
|
||||
this.activatedCallbacks = [];
|
||||
|
||||
this.restoreScrollPosition();
|
||||
|
||||
this.viewportElement.classList.remove( 'loading-scroll-mode' );
|
||||
this.viewportElement.addEventListener( 'scroll', this.onScroll, { passive: true } );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivates the scroll view and restores the standard slide-based
|
||||
* presentation.
|
||||
*/
|
||||
deactivate() {
|
||||
|
||||
if( !this.active ) return;
|
||||
|
||||
const stateBeforeDeactivation = this.Reveal.getState();
|
||||
|
||||
this.active = false;
|
||||
|
||||
this.viewportElement.removeEventListener( 'scroll', this.onScroll );
|
||||
this.viewportElement.classList.remove( 'reveal-scroll' );
|
||||
|
||||
this.removeProgressBar();
|
||||
|
||||
this.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;
|
||||
this.Reveal.sync();
|
||||
this.Reveal.setState( stateBeforeDeactivation );
|
||||
|
||||
this.slideHTMLBeforeActivation = null;
|
||||
|
||||
}
|
||||
|
||||
toggle( override ) {
|
||||
|
||||
if( typeof override === 'boolean' ) {
|
||||
override ? this.activate() : this.deactivate();
|
||||
}
|
||||
else {
|
||||
this.isActive() ? this.deactivate() : this.activate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the scroll view is currently active.
|
||||
*/
|
||||
isActive() {
|
||||
|
||||
return this.active;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the progress bar component.
|
||||
*/
|
||||
createProgressBar() {
|
||||
|
||||
this.progressBar = document.createElement( 'div' );
|
||||
this.progressBar.className = 'scrollbar';
|
||||
|
||||
this.progressBarInner = document.createElement( 'div' );
|
||||
this.progressBarInner.className = 'scrollbar-inner';
|
||||
this.progressBar.appendChild( this.progressBarInner );
|
||||
|
||||
this.progressBarPlayhead = document.createElement( 'div' );
|
||||
this.progressBarPlayhead.className = 'scrollbar-playhead';
|
||||
this.progressBarInner.appendChild( this.progressBarPlayhead );
|
||||
|
||||
this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );
|
||||
|
||||
const handleDocumentMouseMove = ( event ) => {
|
||||
|
||||
let progress = ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight;
|
||||
progress = Math.max( Math.min( progress, 1 ), 0 );
|
||||
|
||||
this.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
|
||||
|
||||
};
|
||||
|
||||
const handleDocumentMouseUp = ( event ) => {
|
||||
|
||||
this.draggingProgressBar = false;
|
||||
this.showProgressBar();
|
||||
|
||||
document.removeEventListener( 'mousemove', handleDocumentMouseMove );
|
||||
document.removeEventListener( 'mouseup', handleDocumentMouseUp );
|
||||
|
||||
};
|
||||
|
||||
const handleMouseDown = ( event ) => {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.draggingProgressBar = true;
|
||||
|
||||
document.addEventListener( 'mousemove', handleDocumentMouseMove );
|
||||
document.addEventListener( 'mouseup', handleDocumentMouseUp );
|
||||
|
||||
handleDocumentMouseMove( event );
|
||||
|
||||
};
|
||||
|
||||
this.progressBarInner.addEventListener( 'mousedown', handleMouseDown );
|
||||
|
||||
}
|
||||
|
||||
removeProgressBar() {
|
||||
|
||||
if( this.progressBar ) {
|
||||
this.progressBar.remove();
|
||||
this.progressBar = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
layout() {
|
||||
|
||||
if( this.isActive() ) {
|
||||
this.syncPages();
|
||||
this.syncScrollPosition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates our pages to match the latest configuration and
|
||||
* presentation size.
|
||||
*/
|
||||
syncPages() {
|
||||
|
||||
const config = this.Reveal.getConfig();
|
||||
|
||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||
const scale = this.Reveal.getScale();
|
||||
const useCompactLayout = config.scrollLayout === 'compact';
|
||||
|
||||
const viewportHeight = this.viewportElement.offsetHeight;
|
||||
const compactHeight = slideSize.height * scale;
|
||||
const pageHeight = useCompactLayout ? compactHeight : viewportHeight;
|
||||
|
||||
// The height that needs to be scrolled between scroll triggers
|
||||
this.scrollTriggerHeight = useCompactLayout ? compactHeight : viewportHeight;
|
||||
|
||||
this.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
|
||||
this.viewportElement.style.scrollSnapType = typeof config.scrollSnap === 'string' ? `y ${config.scrollSnap}` : '';
|
||||
|
||||
// This will hold all scroll triggers used to show/hide slides
|
||||
this.slideTriggers = [];
|
||||
|
||||
const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.scroll-page' ) );
|
||||
|
||||
this.pages = pageElements.map( pageElement => {
|
||||
const page = this.createPage({
|
||||
pageElement,
|
||||
slideElement: pageElement.querySelector( 'section' ),
|
||||
stickyElement: pageElement.querySelector( '.scroll-page-sticky' ),
|
||||
contentElement: pageElement.querySelector( '.scroll-page-content' ),
|
||||
backgroundElement: pageElement.querySelector( '.slide-background' ),
|
||||
autoAnimateElements: pageElement.querySelectorAll( '.scroll-auto-animate-page' ),
|
||||
autoAnimatePages: []
|
||||
});
|
||||
|
||||
page.pageElement.style.setProperty( '--slide-height', config.center === true ? 'auto' : slideSize.height + 'px' );
|
||||
|
||||
this.slideTriggers.push({
|
||||
page: page,
|
||||
activate: () => this.activatePage( page ),
|
||||
deactivate: () => this.deactivatePage( page )
|
||||
});
|
||||
|
||||
// Create scroll triggers that show/hide fragments
|
||||
this.createFragmentTriggersForPage( page );
|
||||
|
||||
// Create scroll triggers for triggering auto-animate steps
|
||||
if( page.autoAnimateElements.length > 0 ) {
|
||||
this.createAutoAnimateTriggersForPage( page );
|
||||
}
|
||||
|
||||
let totalScrollTriggerCount = Math.max( page.scrollTriggers.length - 1, 0 );
|
||||
|
||||
// Each auto-animate step may include its own scroll triggers
|
||||
// for fragments, ensure we count those as well
|
||||
totalScrollTriggerCount += page.autoAnimatePages.reduce( ( total, page ) => {
|
||||
return total + Math.max( page.scrollTriggers.length - 1, 0 );
|
||||
}, page.autoAnimatePages.length );
|
||||
|
||||
// Clean up from previous renders
|
||||
page.pageElement.querySelectorAll( '.scroll-snap-point' ).forEach( el => el.remove() );
|
||||
|
||||
// Create snap points for all scroll triggers
|
||||
// - Can't be absolute in FF
|
||||
// - Can't be 0-height in Safari
|
||||
// - Can't use snap-align on parent in Safari because then
|
||||
// inner triggers won't work
|
||||
for( let i = 0; i < totalScrollTriggerCount + 1; i++ ) {
|
||||
const triggerStick = document.createElement( 'div' );
|
||||
triggerStick.className = 'scroll-snap-point';
|
||||
triggerStick.style.height = this.scrollTriggerHeight + 'px';
|
||||
triggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';
|
||||
page.pageElement.appendChild( triggerStick );
|
||||
|
||||
if( i === 0 ) {
|
||||
triggerStick.style.marginTop = -this.scrollTriggerHeight + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
// In the compact layout, only slides with scroll triggers cover the
|
||||
// full viewport height. This helps avoid empty gaps before or after
|
||||
// a sticky slide.
|
||||
if( useCompactLayout && page.scrollTriggers.length > 0 ) {
|
||||
page.pageHeight = viewportHeight;
|
||||
page.pageElement.style.setProperty( '--page-height', viewportHeight + 'px' );
|
||||
}
|
||||
else {
|
||||
page.pageHeight = pageHeight;
|
||||
page.pageElement.style.removeProperty( '--page-height' );
|
||||
}
|
||||
|
||||
// Add scroll padding based on how many scroll triggers we have
|
||||
page.scrollPadding = this.scrollTriggerHeight * totalScrollTriggerCount;
|
||||
|
||||
// The total height including scrollable space
|
||||
page.totalHeight = page.pageHeight + page.scrollPadding;
|
||||
|
||||
// This is used to pad the height of our page in CSS
|
||||
page.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );
|
||||
|
||||
// If this is a sticky page, stick it to the vertical center
|
||||
if( totalScrollTriggerCount > 0 ) {
|
||||
page.stickyElement.style.position = 'sticky';
|
||||
page.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';
|
||||
}
|
||||
else {
|
||||
page.stickyElement.style.position = 'relative';
|
||||
page.pageElement.style.scrollSnapAlign = page.pageHeight < viewportHeight ? 'center' : 'start';
|
||||
}
|
||||
|
||||
return page;
|
||||
} );
|
||||
|
||||
this.setTriggerRanges();
|
||||
|
||||
/*
|
||||
console.log(this.slideTriggers.map( t => {
|
||||
return {
|
||||
range: `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`,
|
||||
triggers: t.page.scrollTriggers.map( t => {
|
||||
return `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`
|
||||
}).join( ', ' ),
|
||||
}
|
||||
}))
|
||||
*/
|
||||
|
||||
this.viewportElement.setAttribute( 'data-scrollbar', config.scrollProgress );
|
||||
|
||||
if( config.scrollProgress && this.totalScrollTriggerCount > 1 ) {
|
||||
// Create the progress bar if it doesn't already exist
|
||||
if( !this.progressBar ) this.createProgressBar();
|
||||
|
||||
this.syncProgressBar();
|
||||
}
|
||||
else {
|
||||
this.removeProgressBar();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates and sets the scroll range for all of our scroll
|
||||
* triggers.
|
||||
*/
|
||||
setTriggerRanges() {
|
||||
|
||||
// Calculate the total number of scroll triggers
|
||||
this.totalScrollTriggerCount = this.slideTriggers.reduce( ( total, trigger ) => {
|
||||
return total + Math.max( trigger.page.scrollTriggers.length, 1 );
|
||||
}, 0 );
|
||||
|
||||
let rangeStart = 0;
|
||||
|
||||
// Calculate the scroll range of each scroll trigger on a scale
|
||||
// of 0-1
|
||||
this.slideTriggers.forEach( ( trigger, i ) => {
|
||||
trigger.range = [
|
||||
rangeStart,
|
||||
rangeStart + Math.max( trigger.page.scrollTriggers.length, 1 ) / this.totalScrollTriggerCount
|
||||
];
|
||||
|
||||
const scrollTriggerSegmentSize = ( trigger.range[1] - trigger.range[0] ) / trigger.page.scrollTriggers.length;
|
||||
// Set the range for each inner scroll trigger
|
||||
trigger.page.scrollTriggers.forEach( ( scrollTrigger, i ) => {
|
||||
scrollTrigger.range = [
|
||||
rangeStart + i * scrollTriggerSegmentSize,
|
||||
rangeStart + ( i + 1 ) * scrollTriggerSegmentSize
|
||||
];
|
||||
} );
|
||||
|
||||
rangeStart = trigger.range[1];
|
||||
} );
|
||||
|
||||
// Ensure the last trigger extends to the end of the page, otherwise
|
||||
// rounding errors can cause the last trigger to end at 0.999999...
|
||||
this.slideTriggers[this.slideTriggers.length - 1].range[1] = 1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates one scroll trigger for each fragments in the given page.
|
||||
*
|
||||
* @param {*} page
|
||||
*/
|
||||
createFragmentTriggersForPage( page, slideElement ) {
|
||||
|
||||
slideElement = slideElement || page.slideElement;
|
||||
|
||||
// Each fragment 'group' is an array containing one or more
|
||||
// fragments. Multiple fragments that appear at the same time
|
||||
// are part of the same group.
|
||||
const fragmentGroups = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment' ), true );
|
||||
|
||||
// Create scroll triggers that show/hide fragments
|
||||
if( fragmentGroups.length ) {
|
||||
page.fragments = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment:not(.disabled)' ) );
|
||||
page.scrollTriggers.push(
|
||||
// Trigger for the initial state with no fragments visible
|
||||
{
|
||||
activate: () => {
|
||||
this.Reveal.fragments.update( -1, page.fragments, slideElement );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Triggers for each fragment group
|
||||
fragmentGroups.forEach( ( fragments, i ) => {
|
||||
page.scrollTriggers.push({
|
||||
activate: () => {
|
||||
this.Reveal.fragments.update( i, page.fragments, slideElement );
|
||||
}
|
||||
});
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
return page.scrollTriggers.length;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates scroll triggers for the auto-animate steps in the
|
||||
* given page.
|
||||
*
|
||||
* @param {*} page
|
||||
*/
|
||||
createAutoAnimateTriggersForPage( page ) {
|
||||
|
||||
if( page.autoAnimateElements.length > 0 ) {
|
||||
|
||||
// Triggers for each subsequent auto-animate slide
|
||||
this.slideTriggers.push( ...Array.from( page.autoAnimateElements ).map( ( autoAnimateElement, i ) => {
|
||||
let autoAnimatePage = this.createPage({
|
||||
slideElement: autoAnimateElement.querySelector( 'section' ),
|
||||
contentElement: autoAnimateElement,
|
||||
backgroundElement: autoAnimateElement.querySelector( '.slide-background' )
|
||||
});
|
||||
|
||||
// Create fragment scroll triggers for the auto-animate slide
|
||||
this.createFragmentTriggersForPage( autoAnimatePage, autoAnimatePage.slideElement );
|
||||
|
||||
page.autoAnimatePages.push( autoAnimatePage );
|
||||
|
||||
// Return our slide trigger
|
||||
return {
|
||||
page: autoAnimatePage,
|
||||
activate: () => this.activatePage( autoAnimatePage ),
|
||||
deactivate: () => this.deactivatePage( autoAnimatePage )
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for creating a page definition and adding
|
||||
* required fields. A "page" is a slide or auto-animate step.
|
||||
*/
|
||||
createPage( page ) {
|
||||
|
||||
page.scrollTriggers = [];
|
||||
page.indexh = parseInt( page.slideElement.getAttribute( 'data-index-h' ), 10 );
|
||||
page.indexv = parseInt( page.slideElement.getAttribute( 'data-index-v' ), 10 );
|
||||
|
||||
return page;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Rerenders progress bar segments so that they match the current
|
||||
* reveal.js config and size.
|
||||
*/
|
||||
syncProgressBar() {
|
||||
|
||||
this.progressBarInner.querySelectorAll( '.scrollbar-slide' ).forEach( slide => slide.remove() );
|
||||
|
||||
const scrollHeight = this.viewportElement.scrollHeight;
|
||||
const viewportHeight = this.viewportElement.offsetHeight;
|
||||
const viewportHeightFactor = viewportHeight / scrollHeight;
|
||||
|
||||
this.progressBarHeight = this.progressBarInner.offsetHeight;
|
||||
this.playheadHeight = Math.max( viewportHeightFactor * this.progressBarHeight, MIN_PLAYHEAD_HEIGHT );
|
||||
this.progressBarScrollableHeight = this.progressBarHeight - this.playheadHeight;
|
||||
|
||||
const progressSegmentHeight = viewportHeight / scrollHeight * this.progressBarHeight;
|
||||
const spacing = Math.min( progressSegmentHeight / 8, MAX_PROGRESS_SPACING );
|
||||
|
||||
this.progressBarPlayhead.style.height = this.playheadHeight - spacing + 'px';
|
||||
|
||||
// Don't show individual segments if they're too small
|
||||
if( progressSegmentHeight > MIN_PROGRESS_SEGMENT_HEIGHT ) {
|
||||
|
||||
this.slideTriggers.forEach( slideTrigger => {
|
||||
|
||||
const { page } = slideTrigger;
|
||||
|
||||
// Visual representation of a slide
|
||||
page.progressBarSlide = document.createElement( 'div' );
|
||||
page.progressBarSlide.className = 'scrollbar-slide';
|
||||
page.progressBarSlide.style.top = slideTrigger.range[0] * this.progressBarHeight + 'px';
|
||||
page.progressBarSlide.style.height = ( slideTrigger.range[1] - slideTrigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||
page.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );
|
||||
this.progressBarInner.appendChild( page.progressBarSlide );
|
||||
|
||||
// Visual representations of each scroll trigger
|
||||
page.scrollTriggerElements = page.scrollTriggers.map( ( trigger, i ) => {
|
||||
|
||||
const triggerElement = document.createElement( 'div' );
|
||||
triggerElement.className = 'scrollbar-trigger';
|
||||
triggerElement.style.top = ( trigger.range[0] - slideTrigger.range[0] ) * this.progressBarHeight + 'px';
|
||||
triggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||
page.progressBarSlide.appendChild( triggerElement );
|
||||
|
||||
if( i === 0 ) triggerElement.style.display = 'none';
|
||||
|
||||
return triggerElement;
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
this.pages.forEach( page => page.progressBarSlide = null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current scroll position and updates our active
|
||||
* trigger states accordingly.
|
||||
*/
|
||||
syncScrollPosition() {
|
||||
|
||||
const viewportHeight = this.viewportElement.offsetHeight;
|
||||
const viewportHeightFactor = viewportHeight / this.viewportElement.scrollHeight;
|
||||
|
||||
const scrollTop = this.viewportElement.scrollTop;
|
||||
const scrollHeight = this.viewportElement.scrollHeight - viewportHeight
|
||||
const scrollProgress = Math.max( Math.min( scrollTop / scrollHeight, 1 ), 0 );
|
||||
const scrollProgressMid = Math.max( Math.min( ( scrollTop + viewportHeight / 2 ) / this.viewportElement.scrollHeight, 1 ), 0 );
|
||||
|
||||
let activePage;
|
||||
|
||||
this.slideTriggers.forEach( ( trigger ) => {
|
||||
const { page } = trigger;
|
||||
|
||||
const shouldPreload = scrollProgress >= trigger.range[0] - viewportHeightFactor*2 &&
|
||||
scrollProgress <= trigger.range[1] + viewportHeightFactor*2;
|
||||
|
||||
// Load slides that are within the preload range
|
||||
if( shouldPreload && !page.loaded ) {
|
||||
page.loaded = true;
|
||||
this.Reveal.slideContent.load( page.slideElement );
|
||||
}
|
||||
else if( page.loaded ) {
|
||||
page.loaded = false;
|
||||
this.Reveal.slideContent.unload( page.slideElement );
|
||||
}
|
||||
|
||||
// If we're within this trigger range, activate it
|
||||
if( scrollProgress >= trigger.range[0] && scrollProgress <= trigger.range[1] ) {
|
||||
this.activateTrigger( trigger );
|
||||
activePage = trigger.page;
|
||||
}
|
||||
// .. otherwise deactivate
|
||||
else if( trigger.active ) {
|
||||
this.deactivateTrigger( trigger );
|
||||
}
|
||||
} );
|
||||
|
||||
// Each page can have its own scroll triggers, check if any of those
|
||||
// need to be activated/deactivated
|
||||
if( activePage ) {
|
||||
activePage.scrollTriggers.forEach( ( trigger ) => {
|
||||
if( scrollProgressMid >= trigger.range[0] && scrollProgressMid <= trigger.range[1] ) {
|
||||
this.activateTrigger( trigger );
|
||||
}
|
||||
else if( trigger.active ) {
|
||||
this.deactivateTrigger( trigger );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// Update our visual progress indication
|
||||
this.setProgressBarValue( scrollTop / ( this.viewportElement.scrollHeight - viewportHeight ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the progress bar playhead to the specified position.
|
||||
*
|
||||
* @param {number} progress 0-1
|
||||
*/
|
||||
setProgressBarValue( progress ) {
|
||||
|
||||
if( this.progressBar ) {
|
||||
|
||||
this.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;
|
||||
|
||||
this.getAllPages()
|
||||
.filter( page => page.progressBarSlide )
|
||||
.forEach( ( page ) => {
|
||||
page.progressBarSlide.classList.toggle( 'active', page.active === true );
|
||||
|
||||
page.scrollTriggers.forEach( ( trigger, i ) => {
|
||||
page.scrollTriggerElements[i].classList.toggle( 'active', page.active === true && trigger.active === true );
|
||||
} );
|
||||
} );
|
||||
|
||||
this.showProgressBar();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the progress bar and, if configured, automatically hide
|
||||
* it after a delay.
|
||||
*/
|
||||
showProgressBar() {
|
||||
|
||||
this.progressBar.classList.add( 'visible' );
|
||||
|
||||
clearTimeout( this.hideProgressBarTimeout );
|
||||
|
||||
if( this.Reveal.getConfig().scrollProgress === 'auto' && !this.draggingProgressBar ) {
|
||||
|
||||
this.hideProgressBarTimeout = setTimeout( () => {
|
||||
if( this.progressBar ) {
|
||||
this.progressBar.classList.remove( 'visible' );
|
||||
}
|
||||
}, HIDE_SCROLLBAR_TIMEOUT );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to the previous page.
|
||||
*/
|
||||
prev() {
|
||||
|
||||
this.viewportElement.scrollTop -= this.scrollTriggerHeight;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to the next page.
|
||||
*/
|
||||
next() {
|
||||
|
||||
this.viewportElement.scrollTop += this.scrollTriggerHeight;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the given slide element into view.
|
||||
*
|
||||
* @param {HTMLElement} slideElement
|
||||
*/
|
||||
scrollToSlide( slideElement ) {
|
||||
|
||||
// If the scroll view isn't active yet, queue this action
|
||||
if( !this.active ) {
|
||||
this.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );
|
||||
}
|
||||
else {
|
||||
// Find the trigger for this slide
|
||||
const trigger = this.getScrollTriggerBySlide( slideElement );
|
||||
|
||||
if( trigger ) {
|
||||
// Use the trigger's range to calculate the scroll position
|
||||
this.viewportElement.scrollTop = trigger.range[0] * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the current scroll position to session storage
|
||||
* so that it can be restored.
|
||||
*/
|
||||
storeScrollPosition() {
|
||||
|
||||
clearTimeout( this.storeScrollPositionTimeout );
|
||||
|
||||
this.storeScrollPositionTimeout = setTimeout( () => {
|
||||
sessionStorage.setItem( 'reveal-scroll-top', this.viewportElement.scrollTop );
|
||||
sessionStorage.setItem( 'reveal-scroll-origin', location.origin + location.pathname );
|
||||
|
||||
this.storeScrollPositionTimeout = null;
|
||||
}, 50 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the scroll position when a deck is reloader.
|
||||
*/
|
||||
restoreScrollPosition() {
|
||||
|
||||
const scrollPosition = sessionStorage.getItem( 'reveal-scroll-top' );
|
||||
const scrollOrigin = sessionStorage.getItem( 'reveal-scroll-origin' );
|
||||
|
||||
if( scrollPosition && scrollOrigin === location.origin + location.pathname ) {
|
||||
this.viewportElement.scrollTop = parseInt( scrollPosition, 10 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the given page and starts its embedded content
|
||||
* if there is any.
|
||||
*
|
||||
* @param {object} page
|
||||
*/
|
||||
activatePage( page ) {
|
||||
|
||||
if( !page.active ) {
|
||||
|
||||
page.active = true;
|
||||
|
||||
const { slideElement, backgroundElement, contentElement, indexh, indexv } = page;
|
||||
|
||||
contentElement.style.display = 'block';
|
||||
|
||||
slideElement.classList.add( 'present' );
|
||||
|
||||
if( backgroundElement ) {
|
||||
backgroundElement.classList.add( 'present' );
|
||||
}
|
||||
|
||||
this.Reveal.setCurrentScrollPage( slideElement, indexh, indexv );
|
||||
this.Reveal.backgrounds.bubbleSlideContrastClassToElement( slideElement, this.viewportElement );
|
||||
|
||||
// If this page is part of an auto-animation there will be one
|
||||
// content element per auto-animated page. We need to show the
|
||||
// current page and hide all others.
|
||||
Array.from( contentElement.parentNode.querySelectorAll( '.scroll-page-content' ) ).forEach( sibling => {
|
||||
if( sibling !== contentElement ) {
|
||||
sibling.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivates the page after it has been visible.
|
||||
*
|
||||
* @param {object} page
|
||||
*/
|
||||
deactivatePage( page ) {
|
||||
|
||||
if( page.active ) {
|
||||
|
||||
page.active = false;
|
||||
if( page.slideElement ) page.slideElement.classList.remove( 'present' );
|
||||
if( page.backgroundElement ) page.backgroundElement.classList.remove( 'present' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
activateTrigger( trigger ) {
|
||||
|
||||
if( !trigger.active ) {
|
||||
trigger.active = true;
|
||||
trigger.activate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deactivateTrigger( trigger ) {
|
||||
|
||||
if( trigger.active ) {
|
||||
trigger.active = false;
|
||||
|
||||
if( trigger.deactivate ) {
|
||||
trigger.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a slide by its original h/v index (i.e. the indices the
|
||||
* slide had before being linearized).
|
||||
*
|
||||
* @param {number} h
|
||||
* @param {number} v
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
getSlideByIndices( h, v ) {
|
||||
|
||||
const page = this.getAllPages().find( page => {
|
||||
return page.indexh === h && page.indexv === v;
|
||||
} );
|
||||
|
||||
return page ? page.slideElement : null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of all scroll triggers for the given slide
|
||||
* DOM element.
|
||||
*
|
||||
* @param {HTMLElement} slide
|
||||
* @returns {Array}
|
||||
*/
|
||||
getScrollTriggerBySlide( slide ) {
|
||||
|
||||
return this.slideTriggers.find( trigger => trigger.page.slideElement === slide );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all pages in the scroll view. This includes
|
||||
* both top-level slides and auto-animate steps.
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
getAllPages() {
|
||||
|
||||
return this.pages.flatMap( page => [page, ...(page.autoAnimatePages || [])] );
|
||||
|
||||
}
|
||||
|
||||
onScroll() {
|
||||
|
||||
this.syncScrollPosition();
|
||||
this.storeScrollPosition();
|
||||
|
||||
}
|
||||
|
||||
get viewportElement() {
|
||||
|
||||
return this.Reveal.getViewportElement();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { extend, queryAll, closest, getMimeTypeFromFile } from '../utils/util.js'
|
||||
import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'
|
||||
import { isMobile } from '../utils/device.js'
|
||||
|
||||
import fitty from 'fitty';
|
||||
@@ -9,11 +9,15 @@ import fitty from 'fitty';
|
||||
*/
|
||||
export default class SlideContent {
|
||||
|
||||
allowedToPlay = true;
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
|
||||
this.preventIframeAutoFocus = this.preventIframeAutoFocus.bind( this );
|
||||
this.ensureMobileMediaPlaying = this.ensureMobileMediaPlaying.bind( this );
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +29,10 @@ export default class SlideContent {
|
||||
*/
|
||||
shouldPreload( element ) {
|
||||
|
||||
if( this.Reveal.isScrollView() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prefer an explicit global preload setting
|
||||
let preload = this.Reveal.getConfig().preloadIframes;
|
||||
|
||||
@@ -47,14 +55,25 @@ export default class SlideContent {
|
||||
load( slide, options = {} ) {
|
||||
|
||||
// Show the slide element
|
||||
slide.style.display = this.Reveal.getConfig().display;
|
||||
const displayValue = this.Reveal.getConfig().display;
|
||||
if( displayValue.includes('!important') ) {
|
||||
const value = displayValue.replace(/\s*!important\s*$/, '').trim();
|
||||
slide.style.setProperty('display', value, 'important');
|
||||
} else {
|
||||
slide.style.display = displayValue;
|
||||
}
|
||||
|
||||
// Media elements with data-src attributes
|
||||
// Media and iframe elements with data-src attributes
|
||||
queryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {
|
||||
if( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {
|
||||
const isIframe = element.tagName === 'IFRAME';
|
||||
if( !isIframe || this.shouldPreload( element ) ) {
|
||||
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
||||
element.setAttribute( 'data-lazy-loaded', '' );
|
||||
element.removeAttribute( 'data-src' );
|
||||
|
||||
if( isIframe ) {
|
||||
element.addEventListener( 'load', this.preventIframeAutoFocus );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
@@ -108,19 +127,21 @@ export default class SlideContent {
|
||||
// URL(s)
|
||||
else {
|
||||
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
|
||||
return `url(${encodeURI(background.trim())})`;
|
||||
// Decode URL(s) that are already encoded first
|
||||
let decoded = decodeURI(background.trim());
|
||||
return `url(${encodeRFC3986URI(decoded)})`;
|
||||
}).join( ',' );
|
||||
}
|
||||
}
|
||||
// Videos
|
||||
else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
|
||||
else if ( backgroundVideo ) {
|
||||
let video = document.createElement( 'video' );
|
||||
|
||||
if( backgroundVideoLoop ) {
|
||||
video.setAttribute( 'loop', '' );
|
||||
}
|
||||
|
||||
if( backgroundVideoMuted ) {
|
||||
if( backgroundVideoMuted || this.Reveal.isSpeakerNotes() ) {
|
||||
video.muted = true;
|
||||
}
|
||||
|
||||
@@ -136,13 +157,15 @@ export default class SlideContent {
|
||||
|
||||
// Support comma separated lists of video sources
|
||||
backgroundVideo.split( ',' ).forEach( source => {
|
||||
const sourceElement = document.createElement( 'source' );
|
||||
sourceElement.setAttribute( 'src', source );
|
||||
|
||||
let type = getMimeTypeFromFile( source );
|
||||
if( type ) {
|
||||
video.innerHTML += `<source src="${source}" type="${type}">`;
|
||||
}
|
||||
else {
|
||||
video.innerHTML += `<source src="${source}">`;
|
||||
sourceElement.setAttribute( 'type', type );
|
||||
}
|
||||
|
||||
video.appendChild( sourceElement );
|
||||
} );
|
||||
|
||||
backgroundContent.appendChild( video );
|
||||
@@ -272,7 +295,9 @@ export default class SlideContent {
|
||||
*/
|
||||
startEmbeddedContent( element ) {
|
||||
|
||||
if( element && !this.Reveal.isSpeakerNotes() ) {
|
||||
if( element ) {
|
||||
|
||||
const isSpeakerNotesWindow = this.Reveal.isSpeakerNotes();
|
||||
|
||||
// Restart GIFs
|
||||
queryAll( element, 'img[src$=".gif"]' ).forEach( el => {
|
||||
@@ -298,6 +323,9 @@ export default class SlideContent {
|
||||
|
||||
if( autoplay && typeof el.play === 'function' ) {
|
||||
|
||||
// In the speaker view we only auto-play muted media
|
||||
if( isSpeakerNotesWindow && !el.muted ) return;
|
||||
|
||||
// If the media is ready, start playback
|
||||
if( el.readyState > 1 ) {
|
||||
this.startEmbeddedMedia( { target: el } );
|
||||
@@ -307,10 +335,16 @@ export default class SlideContent {
|
||||
else if( isMobile ) {
|
||||
let promise = el.play();
|
||||
|
||||
el.addEventListener( 'canplay', this.ensureMobileMediaPlaying );
|
||||
|
||||
// If autoplay does not work, ensure that the controls are visible so
|
||||
// that the viewer can start the media on their own
|
||||
if( promise && typeof promise.catch === 'function' && el.controls === false ) {
|
||||
promise.catch( () => {
|
||||
promise
|
||||
.then( () => {
|
||||
this.allowedToPlay = true;
|
||||
})
|
||||
.catch( () => {
|
||||
el.controls = true;
|
||||
|
||||
// Once the video does start playing, hide the controls again
|
||||
@@ -329,32 +363,72 @@ export default class SlideContent {
|
||||
}
|
||||
} );
|
||||
|
||||
// Normal iframes
|
||||
queryAll( element, 'iframe[src]' ).forEach( el => {
|
||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||
return;
|
||||
}
|
||||
// Don't play iframe content in the speaker view since we can't
|
||||
// guarantee that it's muted
|
||||
if( !isSpeakerNotesWindow ) {
|
||||
|
||||
this.startEmbeddedIframe( { target: el } );
|
||||
} );
|
||||
// Normal iframes
|
||||
queryAll( element, 'iframe[src]' ).forEach( el => {
|
||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Lazy loading iframes
|
||||
queryAll( element, 'iframe[data-src]' ).forEach( el => {
|
||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||
return;
|
||||
}
|
||||
this.startEmbeddedIframe( { target: el } );
|
||||
} );
|
||||
|
||||
if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
|
||||
el.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes
|
||||
el.addEventListener( 'load', this.startEmbeddedIframe );
|
||||
el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
|
||||
}
|
||||
} );
|
||||
// Lazy loading iframes
|
||||
queryAll( element, 'iframe[data-src]' ).forEach( el => {
|
||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
|
||||
el.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes
|
||||
el.addEventListener( 'load', this.startEmbeddedIframe );
|
||||
el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that an HTMLMediaElement is playing on mobile devices.
|
||||
*
|
||||
* This is a workaround for a bug in mobile Safari where
|
||||
* the media fails to display if many videos are started
|
||||
* at the same moment. When this happens, Mobile Safari
|
||||
* reports the video is playing, and the current time
|
||||
* advances, but nothing is visible.
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
ensureMobileMediaPlaying( event ) {
|
||||
|
||||
const el = event.target;
|
||||
|
||||
// Ignore this check incompatible browsers
|
||||
if( typeof el.getVideoPlaybackQuality !== 'function' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout( () => {
|
||||
|
||||
const playing = el.paused === false;
|
||||
const totalFrames = el.getVideoPlaybackQuality().totalVideoFrames;
|
||||
|
||||
if( playing && totalFrames === 0 ) {
|
||||
el.load();
|
||||
el.play();
|
||||
}
|
||||
|
||||
}, 1000 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts playing an embedded video/audio element after
|
||||
* it has finished loading.
|
||||
@@ -367,8 +441,23 @@ export default class SlideContent {
|
||||
isVisible = !!closest( event.target, '.present' );
|
||||
|
||||
if( isAttachedToDOM && isVisible ) {
|
||||
event.target.currentTime = 0;
|
||||
event.target.play();
|
||||
// Don't restart if media is already playing
|
||||
if( event.target.paused || event.target.ended ) {
|
||||
event.target.currentTime = 0;
|
||||
const promise = event.target.play();
|
||||
|
||||
if( promise && typeof promise.catch === 'function' ) {
|
||||
promise
|
||||
.then( () => {
|
||||
this.allowedToPlay = true;
|
||||
} )
|
||||
.catch( ( error ) => {
|
||||
if( error.name === 'NotAllowedError' ) {
|
||||
this.allowedToPlay = false;
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );
|
||||
@@ -385,6 +474,8 @@ export default class SlideContent {
|
||||
|
||||
let iframe = event.target;
|
||||
|
||||
this.preventIframeAutoFocus( event );
|
||||
|
||||
if( iframe && iframe.contentWindow ) {
|
||||
|
||||
let isAttachedToDOM = !!closest( event.target, 'html' ),
|
||||
@@ -439,12 +530,17 @@ export default class SlideContent {
|
||||
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
|
||||
el.setAttribute('data-paused-by-reveal', '');
|
||||
el.pause();
|
||||
|
||||
if( isMobile ) {
|
||||
el.removeEventListener( 'canplay', this.ensureMobileMediaPlaying );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
// Generic postMessage API for non-lazy loaded iframes
|
||||
queryAll( element, 'iframe' ).forEach( el => {
|
||||
if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );
|
||||
el.removeEventListener( 'load', this.preventIframeAutoFocus );
|
||||
el.removeEventListener( 'load', this.startEmbeddedIframe );
|
||||
});
|
||||
|
||||
@@ -475,4 +571,46 @@ export default class SlideContent {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether media playback is blocked by the browser. This
|
||||
* typically happens when media playback is initiated without a
|
||||
* direct user interaction.
|
||||
*/
|
||||
isNotAllowedToPlay() {
|
||||
|
||||
return !this.allowedToPlay;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents iframes from automatically focusing themselves.
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
preventIframeAutoFocus( event ) {
|
||||
|
||||
const iframe = event.target;
|
||||
|
||||
console.log(111)
|
||||
|
||||
if( iframe && this.Reveal.getConfig().preventIframeAutoFocus ) {
|
||||
|
||||
let elapsed = 0;
|
||||
const interval = 100;
|
||||
const maxTime = 1000;
|
||||
const checkFocus = () => {
|
||||
if( document.activeElement === iframe ) {
|
||||
document.activeElement.blur();
|
||||
} else if( elapsed < maxTime ) {
|
||||
elapsed += interval;
|
||||
setTimeout( checkFocus, interval );
|
||||
}
|
||||
};
|
||||
|
||||
setTimeout( checkFocus, interval );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import {
|
||||
SLIDE_NUMBER_FORMAT_CURRENT,
|
||||
SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL,
|
||||
SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL,
|
||||
SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL
|
||||
} from "../utils/constants";
|
||||
|
||||
/**
|
||||
* Handles the display of reveal.js' optional slide number.
|
||||
*/
|
||||
@@ -23,7 +30,7 @@ export default class SlideNumber {
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
let slideNumberDisplay = 'none';
|
||||
if( config.slideNumber && !this.Reveal.isPrintingPDF() ) {
|
||||
if( config.slideNumber && !this.Reveal.isPrintView() ) {
|
||||
if( config.showSlideNumber === 'all' ) {
|
||||
slideNumberDisplay = 'block';
|
||||
}
|
||||
@@ -56,7 +63,7 @@ export default class SlideNumber {
|
||||
|
||||
let config = this.Reveal.getConfig();
|
||||
let value;
|
||||
let format = 'h.v';
|
||||
let format = SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL;
|
||||
|
||||
if ( typeof config.slideNumber === 'function' ) {
|
||||
value = config.slideNumber( slide );
|
||||
@@ -69,7 +76,7 @@ export default class SlideNumber {
|
||||
// If there are ONLY vertical slides in this deck, always use
|
||||
// a flattened slide number
|
||||
if( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {
|
||||
format = 'c';
|
||||
format = SLIDE_NUMBER_FORMAT_CURRENT;
|
||||
}
|
||||
|
||||
// Offset the current slide number by 1 to make it 1-indexed
|
||||
@@ -77,16 +84,16 @@ export default class SlideNumber {
|
||||
|
||||
value = [];
|
||||
switch( format ) {
|
||||
case 'c':
|
||||
case SLIDE_NUMBER_FORMAT_CURRENT:
|
||||
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );
|
||||
break;
|
||||
case 'c/t':
|
||||
case SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL:
|
||||
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );
|
||||
break;
|
||||
default:
|
||||
let indices = this.Reveal.getIndices( slide );
|
||||
value.push( indices.h + horizontalOffset );
|
||||
let sep = format === 'h/v' ? '/' : '.';
|
||||
let sep = format === SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL ? '/' : '.';
|
||||
if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ export default class Touch {
|
||||
isSwipePrevented( target ) {
|
||||
|
||||
// Prevent accidental swipes when scrubbing timelines
|
||||
if( matches( target, 'video, audio' ) ) return true;
|
||||
if( matches( target, 'video[controls], audio[controls]' ) ) return true;
|
||||
|
||||
while( target && typeof target.hasAttribute === 'function' ) {
|
||||
if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
|
||||
@@ -103,6 +103,8 @@ export default class Touch {
|
||||
*/
|
||||
onTouchStart( event ) {
|
||||
|
||||
this.touchCaptured = false;
|
||||
|
||||
if( this.isSwipePrevented( event.target ) ) return true;
|
||||
|
||||
this.touchStartX = event.touches[0].clientX;
|
||||
@@ -214,6 +216,14 @@ export default class Touch {
|
||||
*/
|
||||
onTouchEnd( event ) {
|
||||
|
||||
// Media playback is only allowed as a direct result of a
|
||||
// user interaction. Some mobile devices do not consider a
|
||||
// 'touchmove' to be a direct user action. If this is the
|
||||
// case, we fall back to starting playback here instead.
|
||||
if( this.touchCaptured && this.Reveal.slideContent.isNotAllowedToPlay() ) {
|
||||
this.Reveal.startEmbeddedContent( this.Reveal.getCurrentSlide() );
|
||||
}
|
||||
|
||||
this.touchCaptured = false;
|
||||
|
||||
}
|
||||
|
||||
671
js/reveal.js
@@ -44,7 +44,7 @@ export const colorToRgb = ( color ) => {
|
||||
};
|
||||
}
|
||||
|
||||
let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
|
||||
let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
|
||||
if( rgba ) {
|
||||
return {
|
||||
r: parseInt( rgba[1], 10 ),
|
||||
|
||||
@@ -2,9 +2,16 @@
|
||||
export const SLIDES_SELECTOR = '.slides section';
|
||||
export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
|
||||
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
|
||||
export const HORIZONTAL_BACKGROUNDS_SELECTOR = '.backgrounds>.slide-background';
|
||||
|
||||
// Methods that may not be invoked via the postMessage API
|
||||
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/;
|
||||
|
||||
// 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/;
|
||||
|
||||
// Slide number formats
|
||||
export const SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL = 'h.v';
|
||||
export const SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL = 'h/v';
|
||||
export const SLIDE_NUMBER_FORMAT_CURRENT = 'c';
|
||||
export const SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL = 'c/t';
|
||||
@@ -294,4 +294,20 @@ const fileExtensionToMimeMap = {
|
||||
*/
|
||||
export const getMimeTypeFromFile = ( filename='' ) => {
|
||||
return fileExtensionToMimeMap[filename.split('.').pop()]
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a string for RFC3986-compliant URL format.
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#encoding_for_rfc3986
|
||||
*
|
||||
* @param {string} url
|
||||
*/
|
||||
export const encodeRFC3986URI = ( url='' ) => {
|
||||
return encodeURI(url)
|
||||
.replace(/%5B/g, "[")
|
||||
.replace(/%5D/g, "]")
|
||||
.replace(
|
||||
/[!'()*]/g,
|
||||
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
||||
);
|
||||
}
|
||||
17496
package-lock.json
generated
58
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reveal.js",
|
||||
"version": "4.4.0",
|
||||
"version": "5.2.1",
|
||||
"description": "The HTML Presentation Framework",
|
||||
"homepage": "https://revealjs.com",
|
||||
"subdomain": "revealjs",
|
||||
@@ -22,7 +22,7 @@
|
||||
"url": "git://github.com/hakimel/reveal.js.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"reveal",
|
||||
@@ -30,33 +30,41 @@
|
||||
"presentation"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/eslint-parser": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^19.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||
"babel-plugin-transform-html-import-to-string": "0.0.1",
|
||||
"@babel/core": "^7.23.2",
|
||||
"@babel/eslint-parser": "^7.22.15",
|
||||
"@babel/preset-env": "^7.23.2",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"babel-plugin-transform-html-import-to-string": "2.0.0",
|
||||
"colors": "^1.4.0",
|
||||
"core-js": "^3.12.1",
|
||||
"fitty": "^2.3.0",
|
||||
"glob": "^7.1.7",
|
||||
"gulp": "^4.0.2",
|
||||
"core-js": "^3.33.1",
|
||||
"fitty": "^2.3.7",
|
||||
"glob": "^10.3.10",
|
||||
"gulp": "^5.0.0",
|
||||
"gulp-autoprefixer": "^8.0.0",
|
||||
"gulp-clean-css": "^4.2.0",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-connect": "^5.7.0",
|
||||
"gulp-eslint": "^6.0.0",
|
||||
"gulp-header": "^2.0.9",
|
||||
"gulp-tap": "^2.0.0",
|
||||
"gulp-zip": "^4.2.0",
|
||||
"highlight.js": "^10.0.3",
|
||||
"marked": "^4.0.12",
|
||||
"node-qunit-puppeteer": "^2.1.0",
|
||||
"qunit": "^2.17.2",
|
||||
"rollup": "^2.48.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"sass": "^1.39.2",
|
||||
"yargs": "^15.1.0"
|
||||
"gulp-header-comment": "^0.10.0",
|
||||
"gulp-zip": "^5.1.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"marked": "^4.3.0",
|
||||
"node-qunit-puppeteer": "^2.2.0",
|
||||
"through2": "^4.0.2",
|
||||
"qunit": "^2.22.0",
|
||||
"rollup": "^4.1.5",
|
||||
"sass": "^1.79.4",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"overrides": {
|
||||
"gulp-connect": {
|
||||
"send": "0.19.0"
|
||||
},
|
||||
"gulp-header-comment": {
|
||||
"moment": "2.30.1"
|
||||
}
|
||||
},
|
||||
"browserslist": "> 2%, not dead",
|
||||
"eslintConfig": {
|
||||
|
||||
@@ -52,7 +52,7 @@ const Plugin = {
|
||||
block.innerHTML = betterTrim( block );
|
||||
}
|
||||
|
||||
// Escape HTML tags unless the "data-noescape" attrbute is present
|
||||
// Escape HTML tags unless the "data-noescape" attribute is present
|
||||
if( config.escapeHTML && !block.hasAttribute( 'data-noescape' )) {
|
||||
block.innerHTML = block.innerHTML.replace( /</g,"<").replace(/>/g, '>' );
|
||||
}
|
||||
@@ -138,7 +138,7 @@ const Plugin = {
|
||||
|
||||
// Scroll highlights into view as we step through them
|
||||
fragmentBlock.addEventListener( 'visible', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock, scrollState ) );
|
||||
fragmentBlock.addEventListener( 'hidden', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousSibling, scrollState ) );
|
||||
fragmentBlock.addEventListener( 'hidden', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousElementSibling, scrollState ) );
|
||||
|
||||
} );
|
||||
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
import { marked } from 'marked';
|
||||
|
||||
const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
|
||||
DEFAULT_NOTES_SEPARATOR = 'notes?:',
|
||||
DEFAULT_VERTICAL_SEPARATOR = null,
|
||||
DEFAULT_NOTES_SEPARATOR = '^\s*notes?:',
|
||||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
||||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
||||
|
||||
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
|
||||
|
||||
const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
|
||||
// match an optional line number offset and highlight line numbers
|
||||
// [<line numbers>] or [<offset>: <line numbers>]
|
||||
const CODE_LINE_NUMBER_REGEX = /\[\s*((\d*):)?\s*([\s\d,|-]*)\]/;
|
||||
|
||||
const HTML_ESCAPE_MAP = {
|
||||
'&': '&',
|
||||
@@ -35,22 +38,22 @@ const Plugin = () => {
|
||||
function getMarkdownFromSlide( section ) {
|
||||
|
||||
// look for a <script> or <textarea data-template> wrapper
|
||||
var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
||||
const template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
||||
|
||||
// strip leading whitespace so it isn't evaluated as code
|
||||
var text = ( template || section ).textContent;
|
||||
let text = ( template || section ).textContent;
|
||||
|
||||
// restore script end tags
|
||||
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
|
||||
|
||||
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
||||
const leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
||||
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
|
||||
|
||||
if( leadingTabs > 0 ) {
|
||||
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
|
||||
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}(.*)','g'), function(m, p1) { return '\n' + p1 ; } );
|
||||
}
|
||||
else if( leadingWs > 1 ) {
|
||||
text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
|
||||
text = text.replace( new RegExp('\\n? {' + leadingWs + '}(.*)', 'g'), function(m, p1) { return '\n' + p1 ; } );
|
||||
}
|
||||
|
||||
return text;
|
||||
@@ -65,11 +68,11 @@ const Plugin = () => {
|
||||
*/
|
||||
function getForwardedAttributes( section ) {
|
||||
|
||||
var attributes = section.attributes;
|
||||
var result = [];
|
||||
const attributes = section.attributes;
|
||||
const result = [];
|
||||
|
||||
for( var i = 0, len = attributes.length; i < len; i++ ) {
|
||||
var name = attributes[i].name,
|
||||
for( let i = 0, len = attributes.length; i < len; i++ ) {
|
||||
const name = attributes[i].name,
|
||||
value = attributes[i].value;
|
||||
|
||||
// disregard attributes that are used for markdown loading/parsing
|
||||
@@ -92,10 +95,12 @@ const Plugin = () => {
|
||||
* values for what's not defined.
|
||||
*/
|
||||
function getSlidifyOptions( options ) {
|
||||
const markdownConfig = deck?.getConfig?.().markdown;
|
||||
|
||||
options = options || {};
|
||||
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
||||
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
||||
options.separator = options.separator || markdownConfig?.separator || DEFAULT_SLIDE_SEPARATOR;
|
||||
options.verticalSeparator = options.verticalSeparator || markdownConfig?.verticalSeparator || DEFAULT_VERTICAL_SEPARATOR;
|
||||
options.notesSeparator = options.notesSeparator || markdownConfig?.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
||||
options.attributes = options.attributes || '';
|
||||
|
||||
return options;
|
||||
@@ -109,7 +114,7 @@ const Plugin = () => {
|
||||
|
||||
options = getSlidifyOptions( options );
|
||||
|
||||
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
||||
const notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
||||
|
||||
if( notesMatch.length === 2 ) {
|
||||
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
|
||||
@@ -131,10 +136,10 @@ const Plugin = () => {
|
||||
|
||||
options = getSlidifyOptions( options );
|
||||
|
||||
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
||||
const separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
||||
horizontalSeparatorRegex = new RegExp( options.separator );
|
||||
|
||||
var matches,
|
||||
let matches,
|
||||
lastIndex = 0,
|
||||
isHorizontal,
|
||||
wasHorizontal = true,
|
||||
@@ -143,7 +148,7 @@ const Plugin = () => {
|
||||
|
||||
// iterate until all blocks between separators are stacked up
|
||||
while( matches = separatorRegex.exec( markdown ) ) {
|
||||
var notes = null;
|
||||
const notes = null;
|
||||
|
||||
// determine direction (horizontal by default)
|
||||
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
|
||||
@@ -172,10 +177,10 @@ const Plugin = () => {
|
||||
// add the remaining slide
|
||||
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
||||
|
||||
var markdownSections = '';
|
||||
let markdownSections = '';
|
||||
|
||||
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
||||
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
||||
for( let i = 0, len = sectionStack.length; i < len; i++ ) {
|
||||
// vertical
|
||||
if( sectionStack[i] instanceof Array ) {
|
||||
markdownSections += '<section '+ options.attributes +'>';
|
||||
@@ -204,7 +209,7 @@ const Plugin = () => {
|
||||
|
||||
return new Promise( function( resolve ) {
|
||||
|
||||
var externalPromises = [];
|
||||
const externalPromises = [];
|
||||
|
||||
[].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
|
||||
|
||||
@@ -257,13 +262,13 @@ const Plugin = () => {
|
||||
|
||||
return new Promise( function( resolve, reject ) {
|
||||
|
||||
var xhr = new XMLHttpRequest(),
|
||||
const xhr = new XMLHttpRequest(),
|
||||
url = section.getAttribute( 'data-markdown' );
|
||||
|
||||
var datacharset = section.getAttribute( 'data-charset' );
|
||||
const datacharset = section.getAttribute( 'data-charset' );
|
||||
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
||||
if( datacharset != null && datacharset != '' ) {
|
||||
if( datacharset !== null && datacharset !== '' ) {
|
||||
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
||||
}
|
||||
|
||||
@@ -308,17 +313,17 @@ const Plugin = () => {
|
||||
*/
|
||||
function addAttributeInElement( node, elementTarget, separator ) {
|
||||
|
||||
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
||||
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
||||
var nodeValue = node.nodeValue;
|
||||
var matches,
|
||||
const markdownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
||||
const markdownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
||||
let nodeValue = node.nodeValue;
|
||||
let matches,
|
||||
matchesClass;
|
||||
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
|
||||
if( matches = markdownClassesInElementsRegex.exec( nodeValue ) ) {
|
||||
|
||||
var classes = matches[1];
|
||||
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
|
||||
const classes = matches[1];
|
||||
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( markdownClassesInElementsRegex.lastIndex );
|
||||
node.nodeValue = nodeValue;
|
||||
while( matchesClass = mardownClassRegex.exec( classes ) ) {
|
||||
while( matchesClass = markdownClassRegex.exec( classes ) ) {
|
||||
if( matchesClass[2] ) {
|
||||
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
||||
} else {
|
||||
@@ -336,34 +341,34 @@ const Plugin = () => {
|
||||
*/
|
||||
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
||||
|
||||
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
|
||||
var previousParentElement = element;
|
||||
for( var i = 0; i < element.childNodes.length; i++ ) {
|
||||
var childElement = element.childNodes[i];
|
||||
if ( element !== null && element.childNodes !== undefined && element.childNodes.length > 0 ) {
|
||||
let previousParentElement = element;
|
||||
for( let i = 0; i < element.childNodes.length; i++ ) {
|
||||
const childElement = element.childNodes[i];
|
||||
if ( i > 0 ) {
|
||||
var j = i - 1;
|
||||
let j = i - 1;
|
||||
while ( j >= 0 ) {
|
||||
var aPreviousChildElement = element.childNodes[j];
|
||||
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
|
||||
const aPreviousChildElement = element.childNodes[j];
|
||||
if ( typeof aPreviousChildElement.setAttribute === 'function' && aPreviousChildElement.tagName !== "BR" ) {
|
||||
previousParentElement = aPreviousChildElement;
|
||||
break;
|
||||
}
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
var parentSection = section;
|
||||
if( childElement.nodeName == "section" ) {
|
||||
let parentSection = section;
|
||||
if( childElement.nodeName === "section" ) {
|
||||
parentSection = childElement ;
|
||||
previousParentElement = childElement ;
|
||||
}
|
||||
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
|
||||
if ( typeof childElement.setAttribute === 'function' || childElement.nodeType === Node.COMMENT_NODE ) {
|
||||
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( element.nodeType == Node.COMMENT_NODE ) {
|
||||
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
|
||||
if ( element.nodeType === Node.COMMENT_NODE ) {
|
||||
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) === false ) {
|
||||
addAttributeInElement( element, section, separatorSectionAttributes );
|
||||
}
|
||||
}
|
||||
@@ -375,14 +380,14 @@ const Plugin = () => {
|
||||
*/
|
||||
function convertSlides() {
|
||||
|
||||
var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
||||
const sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
||||
|
||||
[].slice.call( sections ).forEach( function( section ) {
|
||||
|
||||
section.setAttribute( 'data-markdown-parsed', true )
|
||||
|
||||
var notes = section.querySelector( 'aside.notes' );
|
||||
var markdown = getMarkdownFromSlide( section );
|
||||
const notes = section.querySelector( 'aside.notes' );
|
||||
const markdown = getMarkdownFromSlide( section );
|
||||
|
||||
section.innerHTML = marked( markdown );
|
||||
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
||||
@@ -429,14 +434,23 @@ const Plugin = () => {
|
||||
renderer.code = ( code, language ) => {
|
||||
|
||||
// Off by default
|
||||
let lineNumberOffset = '';
|
||||
let lineNumbers = '';
|
||||
|
||||
// Users can opt in to show line numbers and highlight
|
||||
// specific lines.
|
||||
// ```javascript [] show line numbers
|
||||
// ```javascript [1,4-8] highlights lines 1 and 4-8
|
||||
// optional line number offset:
|
||||
// ```javascript [25: 1,4-8] start line numbering at 25,
|
||||
// highlights lines 1 (numbered as 25) and 4-8 (numbered as 28-32)
|
||||
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
|
||||
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
|
||||
let lineNumberOffsetMatch = language.match( CODE_LINE_NUMBER_REGEX )[2];
|
||||
if (lineNumberOffsetMatch){
|
||||
lineNumberOffset = `data-ln-start-from="${lineNumberOffsetMatch.trim()}"`;
|
||||
}
|
||||
|
||||
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[3].trim();
|
||||
lineNumbers = `data-line-numbers="${lineNumbers}"`;
|
||||
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
|
||||
}
|
||||
@@ -446,7 +460,9 @@ const Plugin = () => {
|
||||
// highlight.js is able to read it
|
||||
code = escapeForHTML( code );
|
||||
|
||||
return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
||||
// return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
||||
|
||||
return `<pre><code ${lineNumbers} ${lineNumberOffset} class="${language}">${code}</code></pre>`;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export const KaTeX = () => {
|
||||
{left: '\\(', right: '\\)', display: false},
|
||||
{left: '\\[', right: '\\]', display: true}
|
||||
],
|
||||
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre']
|
||||
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
|
||||
}
|
||||
|
||||
const loadCss = src => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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;
|
||||
const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre","code"]},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;
|
||||
/*!
|
||||
* 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;
|
||||
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","code"]};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:o,version:l,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","code"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{t.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(){t.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export{a as default};
|
||||
|
||||
@@ -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(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","code"]},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","code"]};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:c,...r}=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(),r),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","code"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{t.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(){t.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}})}));
|
||||
|
||||
@@ -13,7 +13,7 @@ export const MathJax2 = () => {
|
||||
messageStyle: 'none',
|
||||
tex2jax: {
|
||||
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
|
||||
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
|
||||
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre', 'code' ]
|
||||
},
|
||||
skipStartupTypeset: true
|
||||
};
|
||||
|
||||