Compare commits
2 Commits
advance-to
...
magic-pyth
| Author | SHA1 | Date | |
|---|---|---|---|
|
c2b09ece24
|
|||
|
47df4cda71
|
@@ -1,8 +0,0 @@
|
|||||||
[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
Normal file
24
.github/workflows/js.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
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
23
.github/workflows/spellcheck.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
# 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
31
.github/workflows/test.yml
vendored
@@ -1,31 +0,0 @@
|
|||||||
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
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,4 +8,5 @@ out/
|
|||||||
log/*.log
|
log/*.log
|
||||||
tmp/**
|
tmp/**
|
||||||
node_modules/
|
node_modules/
|
||||||
.sass-cache
|
.sass-cache
|
||||||
|
dist/*.map
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
/test
|
/test
|
||||||
/examples
|
/examples
|
||||||
.github
|
.github
|
||||||
|
.gulpfile
|
||||||
.sass-cache
|
.sass-cache
|
||||||
gulpfile.js
|
gulpfile.js
|
||||||
|
CONTRIBUTING.md
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
## Contributing
|
## Contributing
|
||||||
Please keep the [issue tracker](https://github.com/hakimel/reveal.js/issues) limited to **bug reports**.
|
|
||||||
|
Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**.
|
||||||
|
|
||||||
|
|
||||||
### General Questions and Support
|
### Personal Support
|
||||||
If you have questions about how to use reveal.js the best place to ask is in the [Discussions](https://github.com/hakimel/reveal.js/discussions). Anything that isn't a bug report should be posted as a dicussion instead.
|
If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
|
||||||
|
|
||||||
|
|
||||||
### Bug Reports
|
### Bug Reports
|
||||||
@@ -11,10 +12,11 @@ When reporting a bug make sure to include information about which browser and op
|
|||||||
|
|
||||||
|
|
||||||
### Pull Requests
|
### Pull Requests
|
||||||
- Should be submitted from a feature/topic branch (not your master)
|
|
||||||
- Should follow the coding style of the file you work in, most importantly:
|
- Should follow the coding style of the file you work in, most importantly:
|
||||||
- Tabs to indent
|
- Tabs to indent
|
||||||
- Single-quoted strings
|
- Single-quoted strings
|
||||||
|
- Should be made towards the **dev branch**
|
||||||
|
- Should be submitted from a feature/topic branch (not your master)
|
||||||
|
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (C) 2011-2024 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
Copyright (C) 2020 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -1,30 +1,28 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://revealjs.com">
|
<a href="https://revealjs.com">
|
||||||
<img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text-sticker.png" alt="reveal.js" width="500">
|
<img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text.svg" alt="reveal.js" width="450">
|
||||||
</a>
|
</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a>
|
<a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a>
|
||||||
<a href="https://slides.com/"><img src="https://static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
|
<a href="https://slides.com/"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create beautiful presentations for free. Check out the live demo at [revealjs.com](https://revealjs.com/).
|
reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create fully featured and beautiful presentations for free. [Check out the live demo](https://revealjs.com/).
|
||||||
|
|
||||||
The framework comes with a powerful feature set including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX typesetting](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and an [extensive API](https://revealjs.com/api/).
|
The framework comes with a broad range of features including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX support](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and much more.
|
||||||
|
|
||||||
---
|
<h1>
|
||||||
|
<a href="https://revealjs.com/installation" style="font-size: 3em;">Get Started</a>
|
||||||
|
</h1>
|
||||||
|
|
||||||
Want to create reveal.js presentation in a graphical editor? Try <https://slides.com>. It's made by the same people behind reveal.js.
|
## Documentation
|
||||||
|
The full reveal.js documentation is available at [revealjs.com](https://revealjs.com).
|
||||||
|
|
||||||
---
|
## Online Editor
|
||||||
|
Want to create your presentation using a visual editor? Try the official reveal.js presentation platform for free at [Slides.com](https://slides.com). It's made by the same people behind reveal.js.
|
||||||
|
|
||||||
### Getting started
|
## License
|
||||||
- 🚀 [Install reveal.js](https://revealjs.com/installation)
|
|
||||||
- 👀 [View the demo presentation](https://revealjs.com/demo)
|
|
||||||
- 📖 [Read the documentation](https://revealjs.com/markup/)
|
|
||||||
- 🖌 [Try the visual editor for reveal.js at Slides.com](https://slides.com/)
|
|
||||||
- 🎬 [Watch the reveal.js video course (paid)](https://revealjs.com/course)
|
|
||||||
|
|
||||||
---
|
MIT licensed
|
||||||
<div align="center">
|
|
||||||
MIT licensed | Copyright © 2011-2024 Hakim El Hattab, https://hakim.se
|
Copyright (C) 2011-2021 Hakim El Hattab, https://hakim.se
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text that auto-fits its container
|
// Text that auto-fits it's container
|
||||||
.reveal .r-fit-text {
|
.reveal .r-fit-text {
|
||||||
display: inline-block; // https://github.com/rikschennink/fitty#performance
|
display: inline-block; // https://github.com/rikschennink/fitty#performance
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
// Stack multiple elements on top of each other
|
// Stack multiple elements on top of each other
|
||||||
.reveal .r-stack {
|
.reveal .r-stack {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .r-stack > * {
|
.reveal .r-stack > * {
|
||||||
|
|||||||
@@ -1,30 +1,42 @@
|
|||||||
|
/* 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 {
|
@media print {
|
||||||
html:not(.print-pdf) {
|
html:not(.print-pdf) {
|
||||||
overflow: visible;
|
|
||||||
|
background: #fff;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
background: #fff;
|
||||||
|
font-size: 20pt;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
border: 0;
|
||||||
|
margin: 0 5%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
float: none !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
html:not(.print-pdf) .reveal {
|
|
||||||
background: #fff;
|
|
||||||
font-size: 20pt;
|
|
||||||
|
|
||||||
|
.nestedarrow,
|
||||||
.controls,
|
.controls,
|
||||||
|
.fork-reveal,
|
||||||
|
.share-reveal,
|
||||||
.state-background,
|
.state-background,
|
||||||
.progress,
|
.reveal .progress,
|
||||||
.backgrounds,
|
.reveal .backgrounds,
|
||||||
.slide-number {
|
.reveal .slide-number {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
p, td, li {
|
body, p, td, li {
|
||||||
font-size: 20pt!important;
|
font-size: 20pt!important;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
@@ -37,6 +49,7 @@
|
|||||||
letter-spacing: normal;
|
letter-spacing: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Need to reduce the size of the fonts for printing */
|
||||||
h1 { font-size: 28pt !important; }
|
h1 { font-size: 28pt !important; }
|
||||||
h2 { font-size: 24pt !important; }
|
h2 { font-size: 24pt !important; }
|
||||||
h3 { font-size: 22pt !important; }
|
h3 { font-size: 22pt !important; }
|
||||||
@@ -61,19 +74,18 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
pre,
|
.reveal pre,
|
||||||
table {
|
.reveal table {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
pre code {
|
.reveal pre code {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
blockquote {
|
.reveal blockquote {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
.reveal .slides {
|
||||||
.slides {
|
|
||||||
position: static !important;
|
position: static !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
@@ -94,7 +106,7 @@
|
|||||||
|
|
||||||
perspective-origin: 50% 50%;
|
perspective-origin: 50% 50%;
|
||||||
}
|
}
|
||||||
.slides section {
|
.reveal .slides section {
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
position: static !important;
|
position: static !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
@@ -117,24 +129,19 @@
|
|||||||
transform: none !important;
|
transform: none !important;
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
.slides section.stack {
|
.reveal .slides section.stack {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
.slides section:last-of-type {
|
.reveal section:last-of-type {
|
||||||
page-break-after: avoid !important;
|
page-break-after: avoid !important;
|
||||||
}
|
}
|
||||||
.slides section .fragment {
|
.reveal section .fragment {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
|
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
|
.reveal section img {
|
||||||
.r-fit-text {
|
|
||||||
white-space: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
section img {
|
|
||||||
display: block;
|
display: block;
|
||||||
margin: 15px 0px;
|
margin: 15px 0px;
|
||||||
background: rgba(255,255,255,1);
|
background: rgba(255,255,255,1);
|
||||||
@@ -142,11 +149,11 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
section small {
|
.reveal section small {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs {
|
.reveal .hljs {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
@@ -154,11 +161,11 @@
|
|||||||
font-size: 15pt;
|
font-size: 15pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs .hljs-ln-numbers {
|
.reveal .hljs .hljs-ln-numbers {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs td {
|
.reveal .hljs td {
|
||||||
font-size: inherit !important;
|
font-size: inherit !important;
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* https://revealjs.com/pdf-export/
|
* https://revealjs.com/pdf-export/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
html.reveal-print {
|
html.print-pdf {
|
||||||
* {
|
* {
|
||||||
-webkit-print-color-adjust: exact;
|
-webkit-print-color-adjust: exact;
|
||||||
}
|
}
|
||||||
@@ -36,6 +36,7 @@ html.reveal-print {
|
|||||||
|
|
||||||
.reveal pre code {
|
.reveal pre code {
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
|
font-family: Courier, 'Courier New', monospace !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal {
|
.reveal {
|
||||||
@@ -70,10 +71,6 @@ html.reveal-print {
|
|||||||
page-break-after: always;
|
page-break-after: always;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides .pdf-page:last-of-type {
|
|
||||||
page-break-after: avoid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reveal .slides section {
|
.reveal .slides section {
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
display: block !important;
|
display: block !important;
|
||||||
@@ -103,6 +100,7 @@ html.reveal-print {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
|
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
|
||||||
.reveal .backgrounds {
|
.reveal .backgrounds {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -149,7 +147,6 @@ html.reveal-print {
|
|||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
visibility: visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This accessibility tool is not useful in PDF and breaks it visually */
|
/* This accessibility tool is not useful in PDF and breaks it visually */
|
||||||
|
|||||||
791
css/reveal.scss
791
css/reveal.scss
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -24,13 +23,10 @@ $headingColor: #333;
|
|||||||
$headingTextShadow: none;
|
$headingTextShadow: none;
|
||||||
$backgroundColor: #f7f3de;
|
$backgroundColor: #f7f3de;
|
||||||
$linkColor: #8b743d;
|
$linkColor: #8b743d;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
|
$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);
|
$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
|
// Background generator
|
||||||
@mixin bodyBackground() {
|
@mixin bodyBackground() {
|
||||||
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
|
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -30,8 +29,8 @@ $headingLetterSpacing: normal;
|
|||||||
$headingTextTransform: uppercase;
|
$headingTextTransform: uppercase;
|
||||||
$headingFontWeight: 600;
|
$headingFontWeight: 600;
|
||||||
$linkColor: #42affa;
|
$linkColor: #42affa;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
$selectionBackgroundColor: rgba( $linkColor, 0.75 );
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
$heading1Size: 2.5em;
|
$heading1Size: 2.5em;
|
||||||
$heading2Size: 1.6em;
|
$heading2Size: 1.6em;
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -41,7 +40,7 @@ $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b
|
|||||||
|
|
||||||
// Links
|
// Links
|
||||||
$linkColor: $blood;
|
$linkColor: $blood;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
|
||||||
// Text selection
|
// Text selection
|
||||||
$selectionBackgroundColor: $blood;
|
$selectionBackgroundColor: $blood;
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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,7 +5,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -19,6 +18,10 @@
|
|||||||
/**
|
/**
|
||||||
* Solarized colors by Ethan Schoonover
|
* Solarized colors by Ethan Schoonover
|
||||||
*/
|
*/
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
// Solarized colors
|
// Solarized colors
|
||||||
$base03: #002b36;
|
$base03: #002b36;
|
||||||
@@ -44,7 +47,7 @@ $headingColor: $base2;
|
|||||||
$headingTextShadow: none;
|
$headingTextShadow: none;
|
||||||
$backgroundColor: $base03;
|
$backgroundColor: $base03;
|
||||||
$linkColor: $blue;
|
$linkColor: $blue;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: $magenta;
|
$selectionBackgroundColor: $magenta;
|
||||||
|
|
||||||
// Change text colors against light slide backgrounds
|
// Change text colors against light slide backgrounds
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -22,7 +21,7 @@ $backgroundColor: #111;
|
|||||||
|
|
||||||
$mainFont: 'Open Sans', sans-serif;
|
$mainFont: 'Open Sans', sans-serif;
|
||||||
$linkColor: #e7ad52;
|
$linkColor: #e7ad52;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$headingFont: 'Montserrat', Impact, sans-serif;
|
$headingFont: 'Montserrat', Impact, sans-serif;
|
||||||
$headingTextShadow: none;
|
$headingTextShadow: none;
|
||||||
$headingLetterSpacing: -0.03em;
|
$headingLetterSpacing: -0.03em;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -23,12 +22,9 @@ $headingTextShadow: none;
|
|||||||
$headingTextTransform: none;
|
$headingTextTransform: none;
|
||||||
$backgroundColor: #F0F1EB;
|
$backgroundColor: #F0F1EB;
|
||||||
$linkColor: #51483D;
|
$linkColor: #51483D;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: #26351C;
|
$selectionBackgroundColor: #26351C;
|
||||||
|
|
||||||
$overlayElementBgColor: 0, 0, 0;
|
|
||||||
$overlayElementFgColor: 240, 240, 240;
|
|
||||||
|
|
||||||
.reveal a {
|
.reveal a {
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -29,12 +28,9 @@ $headingTextShadow: none;
|
|||||||
$headingTextTransform: none;
|
$headingTextTransform: none;
|
||||||
$backgroundColor: #fff;
|
$backgroundColor: #fff;
|
||||||
$linkColor: #00008B;
|
$linkColor: #00008B;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
|
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
|
||||||
|
|
||||||
$overlayElementBgColor: 0, 0, 0;
|
|
||||||
$overlayElementFgColor: 240, 240, 240;
|
|
||||||
|
|
||||||
// Change text colors against dark slide backgrounds
|
// Change text colors against dark slide backgrounds
|
||||||
@include dark-bg-text-color(#fff);
|
@include dark-bg-text-color(#fff);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -27,12 +26,9 @@ $headingLetterSpacing: -0.08em;
|
|||||||
$headingTextShadow: none;
|
$headingTextShadow: none;
|
||||||
$backgroundColor: #f7fbfc;
|
$backgroundColor: #f7fbfc;
|
||||||
$linkColor: #3b759e;
|
$linkColor: #3b759e;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: #134674;
|
$selectionBackgroundColor: #134674;
|
||||||
|
|
||||||
$overlayElementBgColor: 0, 0, 0;
|
|
||||||
$overlayElementFgColor: 240, 240, 240;
|
|
||||||
|
|
||||||
// Fix links so they are not cut off
|
// Fix links so they are not cut off
|
||||||
.reveal a {
|
.reveal a {
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -49,12 +48,9 @@ $headingColor: $base01;
|
|||||||
$headingTextShadow: none;
|
$headingTextShadow: none;
|
||||||
$backgroundColor: $base3;
|
$backgroundColor: $base3;
|
||||||
$linkColor: $blue;
|
$linkColor: $blue;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: $magenta;
|
$selectionBackgroundColor: $magenta;
|
||||||
|
|
||||||
$overlayElementBgColor: 0, 0, 0;
|
|
||||||
$overlayElementFgColor: 240, 240, 240;
|
|
||||||
|
|
||||||
// Background generator
|
// Background generator
|
||||||
// @mixin bodyBackground() {
|
// @mixin bodyBackground() {
|
||||||
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// Default mixins and settings -----------------
|
// Default mixins and settings -----------------
|
||||||
@use "sass:color";
|
|
||||||
@import "../template/mixins";
|
@import "../template/mixins";
|
||||||
@import "../template/settings";
|
@import "../template/settings";
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
@@ -30,17 +29,14 @@ $headingLetterSpacing: normal;
|
|||||||
$headingTextTransform: uppercase;
|
$headingTextTransform: uppercase;
|
||||||
$headingFontWeight: 600;
|
$headingFontWeight: 600;
|
||||||
$linkColor: #2a76dd;
|
$linkColor: #2a76dd;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 15% );
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
$selectionBackgroundColor: color.scale( $linkColor, $lightness: 25% );
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
$heading1Size: 2.5em;
|
$heading1Size: 2.5em;
|
||||||
$heading2Size: 1.6em;
|
$heading2Size: 1.6em;
|
||||||
$heading3Size: 1.3em;
|
$heading3Size: 1.3em;
|
||||||
$heading4Size: 1.0em;
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
$overlayElementBgColor: 0, 0, 0;
|
|
||||||
$overlayElementFgColor: 240, 240, 240;
|
|
||||||
|
|
||||||
// Change text colors against dark slide backgrounds
|
// Change text colors against dark slide backgrounds
|
||||||
@include dark-bg-text-color(#fff);
|
@include dark-bg-text-color(#fff);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// Exposes theme's variables for easy reuse in CSS for plugin authors
|
// Exposes theme's variables for easy re-use in CSS for plugin authors
|
||||||
|
|
||||||
@use "sass:color";
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--r-background-color: #{$backgroundColor};
|
--r-background-color: #{$backgroundColor};
|
||||||
@@ -23,10 +21,8 @@
|
|||||||
--r-heading4-size: #{$heading4Size};
|
--r-heading4-size: #{$heading4Size};
|
||||||
--r-code-font: #{$codeFont};
|
--r-code-font: #{$codeFont};
|
||||||
--r-link-color: #{$linkColor};
|
--r-link-color: #{$linkColor};
|
||||||
--r-link-color-dark: #{color.scale( $linkColor, $lightness: -15% )};
|
--r-link-color-dark: #{darken($linkColor , 15% )};
|
||||||
--r-link-color-hover: #{$linkColorHover};
|
--r-link-color-hover: #{$linkColorHover};
|
||||||
--r-selection-background-color: #{$selectionBackgroundColor};
|
--r-selection-background-color: #{$selectionBackgroundColor};
|
||||||
--r-selection-color: #{$selectionColor};
|
--r-selection-color: #{$selectionColor};
|
||||||
--r-overlay-element-bg-color: #{$overlayElementBgColor};
|
|
||||||
--r-overlay-element-fg-color: #{$overlayElementFgColor};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
@use "sass:color";
|
|
||||||
|
|
||||||
// Base settings for all themes that can optionally be
|
// Base settings for all themes that can optionally be
|
||||||
// overridden by the super-theme
|
// overridden by the super-theme
|
||||||
|
|
||||||
@@ -34,17 +32,12 @@ $codeFont: monospace;
|
|||||||
|
|
||||||
// Links and actions
|
// Links and actions
|
||||||
$linkColor: #13DAEC;
|
$linkColor: #13DAEC;
|
||||||
$linkColorHover: color.scale( $linkColor, $lightness: 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
|
||||||
// Text selection
|
// Text selection
|
||||||
$selectionBackgroundColor: #FF5E99;
|
$selectionBackgroundColor: #FF5E99;
|
||||||
$selectionColor: #fff;
|
$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
|
// Generates the presentation background, can be overridden
|
||||||
// to return a background image or gradient
|
// to return a background image or gradient
|
||||||
@mixin bodyBackground() {
|
@mixin bodyBackground() {
|
||||||
|
|||||||
@@ -278,7 +278,8 @@
|
|||||||
|
|
||||||
.reveal .roll span:after {
|
.reveal .roll span:after {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: var(--r-link-color-dark);
|
// background: darken( var(--r-link-color), 15% );
|
||||||
|
background: var(--r-link-color-dark);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
66
demo.html
66
demo.html
@@ -52,7 +52,7 @@
|
|||||||
<p>Slides can be nested inside of each other.</p>
|
<p>Slides can be nested inside of each other.</p>
|
||||||
<p>Use the <em>Space</em> key to navigate through all slides.</p>
|
<p>Use the <em>Space</em> key to navigate through all slides.</p>
|
||||||
<br>
|
<br>
|
||||||
<a href="#/2/1" class="navigate-down">
|
<a href="#" class="navigate-down">
|
||||||
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h2 data-id="code-title">Pretty Code</h2>
|
<h2 data-id="code-title">Pretty Code</h2>
|
||||||
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers>
|
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
function Example() {
|
function Example() {
|
||||||
@@ -101,8 +101,8 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h2 data-id="code-title">With Animations</h2>
|
<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">
|
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
function Example() {
|
function Example() {
|
||||||
@@ -165,9 +165,9 @@
|
|||||||
</section>
|
</section>
|
||||||
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||||
<div class="r-stack">
|
<div class="r-stack">
|
||||||
<div data-id="box1" style="background: cyan; width: 300px; height: 300px;"></div>
|
<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;"></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;"></div>
|
<div data-id="box3" style="background: yellow; width: 100px; height: 100px; border-radius: 200px;"></div>
|
||||||
</div>
|
</div>
|
||||||
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||||
</section>
|
</section>
|
||||||
@@ -181,14 +181,14 @@
|
|||||||
|
|
||||||
<section data-markdown>
|
<section data-markdown>
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
## Markdown Support
|
## Markdown support
|
||||||
|
|
||||||
Write content using inline or external Markdown.
|
Write content using inline or external Markdown.
|
||||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||||
|
|
||||||
```html []
|
```html []
|
||||||
<section data-markdown>
|
<section data-markdown>
|
||||||
## Markdown Support
|
## Markdown support
|
||||||
|
|
||||||
Write content using inline or external Markdown.
|
Write content using inline or external Markdown.
|
||||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||||
@@ -197,25 +197,6 @@
|
|||||||
</script>
|
</script>
|
||||||
</section>
|
</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>
|
<section>
|
||||||
<p>Add the <code>r-fit-text</code> class to auto-size text</p>
|
<p>Add the <code>r-fit-text</code> class to auto-size text</p>
|
||||||
<h2 class="r-fit-text">FIT TEXT</h2>
|
<h2 class="r-fit-text">FIT TEXT</h2>
|
||||||
@@ -268,17 +249,17 @@
|
|||||||
<p>
|
<p>
|
||||||
reveal.js comes with a few themes built in: <br>
|
reveal.js comes with a few themes built in: <br>
|
||||||
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
|
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
|
||||||
<a href="#/themes" 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/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="#" 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="#" 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="#" 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="#" 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="#" 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="#" 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="#" 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="#" 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="#" 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>
|
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -292,11 +273,6 @@
|
|||||||
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)">
|
|
||||||
<h2>Gradient Backgrounds</h2>
|
|
||||||
<pre><code class="hljs html wrap"><section data-background-gradient=
|
|
||||||
"linear-gradient(to bottom, #ddd, #191919)"></code></pre>
|
|
||||||
</section>
|
|
||||||
<section data-background="https://static.slid.es/reveal/image-placeholder.png">
|
<section data-background="https://static.slid.es/reveal/image-placeholder.png">
|
||||||
<h2>Image Backgrounds</h2>
|
<h2>Image Backgrounds</h2>
|
||||||
<pre><code class="hljs html"><section data-background="image.png"></code></pre>
|
<pre><code class="hljs html"><section data-background="image.png"></code></pre>
|
||||||
@@ -305,7 +281,7 @@
|
|||||||
<h2>Tiled Backgrounds</h2>
|
<h2>Tiled Backgrounds</h2>
|
||||||
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"></code></pre>
|
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"></code></pre>
|
||||||
</section>
|
</section>
|
||||||
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000">
|
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000">
|
||||||
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
|
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
|
||||||
<h2>Video Backgrounds</h2>
|
<h2>Video Backgrounds</h2>
|
||||||
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background-video="video.mp4,video.webm"></code></pre>
|
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background-video="video.mp4,video.webm"></code></pre>
|
||||||
|
|||||||
17
dist/reveal.css
vendored
17
dist/reveal.css
vendored
File diff suppressed because one or more lines are too long
14
dist/reveal.esm.js
vendored
14
dist/reveal.esm.js
vendored
File diff suppressed because one or more lines are too long
1
dist/reveal.esm.js.map
vendored
1
dist/reveal.esm.js.map
vendored
File diff suppressed because one or more lines are too long
14
dist/reveal.js
vendored
14
dist/reveal.js
vendored
File diff suppressed because one or more lines are too long
1
dist/reveal.js.map
vendored
1
dist/reveal.js.map
vendored
File diff suppressed because one or more lines are too long
20
dist/theme/beige.css
vendored
20
dist/theme/beige.css
vendored
@@ -33,22 +33,20 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #8b743d;
|
--r-link-color: #8b743d;
|
||||||
--r-link-color-dark: rgb(118.15, 98.6, 51.85);
|
--r-link-color-dark: #564826;
|
||||||
--r-link-color-hover: rgb(179.36, 150.84, 82.64);
|
--r-link-color-hover: #c0a86e;
|
||||||
--r-selection-background-color: rgba(79, 64, 28, 0.99);
|
--r-selection-background-color: rgba(79, 64, 28, 0.99);
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
background: rgb(247, 242, 211);
|
background: #f7f2d3;
|
||||||
background: -moz-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 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-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
|
||||||
background: -webkit-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||||
background: -o-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||||
background: -ms-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||||
background: radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
||||||
background-color: var(--r-background-color);
|
background-color: var(--r-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
362
dist/theme/black-contrast.css
vendored
362
dist/theme/black-contrast.css
vendored
@@ -1,362 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
8
dist/theme/black.css
vendored
@@ -32,12 +32,10 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #42affa;
|
--r-link-color: #42affa;
|
||||||
--r-link-color-dark: rgb(19.8216494845, 155.4536082474, 248.7783505155);
|
--r-link-color-dark: #068de9;
|
||||||
--r-link-color-hover: rgb(94.35, 187, 250.75);
|
--r-link-color-hover: #8dcffc;
|
||||||
--r-selection-background-color: rgba(66, 175, 250, 0.75);
|
--r-selection-background-color: #bee4fd;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 240, 240, 240;
|
|
||||||
--r-overlay-element-fg-color: 0, 0, 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/blood.css
vendored
6
dist/theme/blood.css
vendored
@@ -38,12 +38,10 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #a23;
|
--r-link-color: #a23;
|
||||||
--r-link-color-dark: rgb(144.5, 28.9, 43.35);
|
--r-link-color-dark: #6a1520;
|
||||||
--r-link-color-hover: rgb(214.2, 51, 71.4);
|
--r-link-color-hover: #dd5566;
|
||||||
--r-selection-background-color: #a23;
|
--r-selection-background-color: #a23;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 240, 240, 240;
|
|
||||||
--r-overlay-element-fg-color: 0, 0, 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
387
dist/theme/dracula.css
vendored
387
dist/theme/dracula.css
vendored
@@ -1,387 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
20
dist/theme/league.css
vendored
@@ -35,22 +35,20 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #13DAEC;
|
--r-link-color: #13DAEC;
|
||||||
--r-link-color-dark: rgb(16.15, 185.3, 200.6);
|
--r-link-color-dark: #0d99a5;
|
||||||
--r-link-color-hover: rgb(66.2, 225.4, 239.8);
|
--r-link-color-hover: #71e9f4;
|
||||||
--r-selection-background-color: #FF5E99;
|
--r-selection-background-color: #FF5E99;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 240, 240, 240;
|
|
||||||
--r-overlay-element-fg-color: 0, 0, 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
background: rgb(28, 30, 32);
|
background: #1c1e20;
|
||||||
background: -moz-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 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-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
|
||||||
background: -webkit-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||||
background: -o-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||||
background: -ms-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||||
background: radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
||||||
background-color: var(--r-background-color);
|
background-color: var(--r-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
dist/theme/moon.css
vendored
11
dist/theme/moon.css
vendored
@@ -7,6 +7,11 @@
|
|||||||
/**
|
/**
|
||||||
* Solarized colors by Ethan Schoonover
|
* 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 {
|
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;
|
color: #222;
|
||||||
}
|
}
|
||||||
@@ -35,12 +40,10 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #268bd2;
|
--r-link-color: #268bd2;
|
||||||
--r-link-color-dark: rgb(32.3, 118.15, 178.5);
|
--r-link-color-dark: #1a6091;
|
||||||
--r-link-color-hover: rgb(77.5161290323, 162.8774193548, 222.8838709677);
|
--r-link-color-hover: #78b9e6;
|
||||||
--r-selection-background-color: #d33682;
|
--r-selection-background-color: #d33682;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 240, 240, 240;
|
|
||||||
--r-overlay-element-fg-color: 0, 0, 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/night.css
vendored
6
dist/theme/night.css
vendored
@@ -33,12 +33,10 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #e7ad52;
|
--r-link-color: #e7ad52;
|
||||||
--r-link-color-dark: rgb(225.2802030457, 153.4573604061, 40.7697969543);
|
--r-link-color-dark: #d08a1d;
|
||||||
--r-link-color-hover: rgb(235.8, 189.4, 116.6);
|
--r-link-color-hover: #f3d7ac;
|
||||||
--r-selection-background-color: #e7ad52;
|
--r-selection-background-color: #e7ad52;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 240, 240, 240;
|
|
||||||
--r-overlay-element-fg-color: 0, 0, 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/serif.css
vendored
6
dist/theme/serif.css
vendored
@@ -36,12 +36,10 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #51483D;
|
--r-link-color: #51483D;
|
||||||
--r-link-color-dark: rgb(68.85, 61.2, 51.85);
|
--r-link-color-dark: #25211c;
|
||||||
--r-link-color-hover: rgb(122.9830985915, 109.3183098592, 92.6169014085);
|
--r-link-color-hover: #8b7c69;
|
||||||
--r-selection-background-color: #26351C;
|
--r-selection-background-color: #26351C;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/simple.css
vendored
6
dist/theme/simple.css
vendored
@@ -35,12 +35,10 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #00008B;
|
--r-link-color: #00008B;
|
||||||
--r-link-color-dark: rgb(0, 0, 118.15);
|
--r-link-color-dark: #00003f;
|
||||||
--r-link-color-hover: rgb(0, 0, 213.2);
|
--r-link-color-hover: #0000f1;
|
||||||
--r-selection-background-color: rgba(0, 0, 0, 0.99);
|
--r-selection-background-color: rgba(0, 0, 0, 0.99);
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/sky.css
vendored
6
dist/theme/sky.css
vendored
@@ -37,12 +37,10 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #3b759e;
|
--r-link-color: #3b759e;
|
||||||
--r-link-color-dark: rgb(50.15, 99.45, 134.3);
|
--r-link-color-dark: #264c66;
|
||||||
--r-link-color-hover: rgb(84.330875576, 146.9815668203, 191.269124424);
|
--r-link-color-hover: #74a7cb;
|
||||||
--r-selection-background-color: #134674;
|
--r-selection-background-color: #134674;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
6
dist/theme/solarized.css
vendored
6
dist/theme/solarized.css
vendored
@@ -36,12 +36,10 @@ html * {
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #268bd2;
|
--r-link-color: #268bd2;
|
||||||
--r-link-color-dark: rgb(32.3, 118.15, 178.5);
|
--r-link-color-dark: #1a6091;
|
||||||
--r-link-color-hover: rgb(77.5161290323, 162.8774193548, 222.8838709677);
|
--r-link-color-hover: #78b9e6;
|
||||||
--r-selection-background-color: #d33682;
|
--r-selection-background-color: #d33682;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
362
dist/theme/white-contrast.css
vendored
362
dist/theme/white-contrast.css
vendored
@@ -1,362 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
8
dist/theme/white.css
vendored
@@ -32,12 +32,10 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-heading4-size: 1em;
|
--r-heading4-size: 1em;
|
||||||
--r-code-font: monospace;
|
--r-code-font: monospace;
|
||||||
--r-link-color: #2a76dd;
|
--r-link-color: #2a76dd;
|
||||||
--r-link-color-dark: rgb(30.7720647773, 99.5566801619, 192.7779352227);
|
--r-link-color-dark: #1a53a1;
|
||||||
--r-link-color-hover: rgb(73.95, 138.55, 226.1);
|
--r-link-color-hover: #6ca0e8;
|
||||||
--r-selection-background-color: rgb(95.25, 152.25, 229.5);
|
--r-selection-background-color: #98bdef;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
--r-overlay-element-bg-color: 0, 0, 0;
|
|
||||||
--r-overlay-element-fg-color: 240, 240, 240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
@@ -1,360 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,526 +0,0 @@
|
|||||||
<!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>
|
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h3>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h2>
|
||||||
<h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2>
|
<h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2>
|
||||||
<div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div>
|
<div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div>
|
<div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h3>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h2>
|
||||||
<h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div>
|
<div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div>
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
<div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div>
|
<div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
|
||||||
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div>
|
<div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div>
|
||||||
<div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div>
|
<div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div>
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
<div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div>
|
<div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
|
||||||
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div>
|
<div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div>
|
||||||
@@ -176,37 +176,6 @@
|
|||||||
<h3>B2</h3>
|
<h3>B2</h3>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
|
||||||
<section id="stacked-slide-1" data-auto-animate>
|
|
||||||
<a href="#/stacked-slide-1">Slide 1</a><br>
|
|
||||||
<a href="#/stacked-slide-2">Slide 2</a><br>
|
|
||||||
<a href="#/stacked-slide-3">Slide 3</a><br>
|
|
||||||
<a href="#/stacked-slide-4">Slide 4</a><br>
|
|
||||||
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 0px;">A</div>
|
|
||||||
</section>
|
|
||||||
<section id="stacked-slide-2" data-auto-animate>
|
|
||||||
<a href="#/stacked-slide-1">Slide 1</a><br>
|
|
||||||
<a href="#/stacked-slide-2">Slide 2</a><br>
|
|
||||||
<a href="#/stacked-slide-3">Slide 3</a><br>
|
|
||||||
<a href="#/stacked-slide-4">Slide 4</a><br>
|
|
||||||
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 25%;">A</div>
|
|
||||||
</section>
|
|
||||||
<section id="stacked-slide-3" data-auto-animate>
|
|
||||||
<a href="#/stacked-slide-1">Slide 1</a><br>
|
|
||||||
<a href="#/stacked-slide-2">Slide 2</a><br>
|
|
||||||
<a href="#/stacked-slide-3">Slide 3</a><br>
|
|
||||||
<a href="#/stacked-slide-4">Slide 4</a><br>
|
|
||||||
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 50%;">A</div>
|
|
||||||
</section>
|
|
||||||
<section id="stacked-slide-4" data-auto-animate>
|
|
||||||
<a href="#/stacked-slide-1">Slide 1</a><br>
|
|
||||||
<a href="#/stacked-slide-2">Slide 2</a><br>
|
|
||||||
<a href="#/stacked-slide-3">Slide 3</a><br>
|
|
||||||
<a href="#/stacked-slide-4">Slide 4</a><br>
|
|
||||||
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 75%;">A</div>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
<h2>Same background twice (2/2)</h2>
|
<h2>Same background twice (2/2)</h2>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<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">
|
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm">
|
||||||
<h2>Video background</h2>
|
<h2>Video background</h2>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 92 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB |
@@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
<section id="vstack">
|
<section id="vstack">
|
||||||
<h2>VStack</h2>
|
<h2>VStack</h2>
|
||||||
<p>Stacks multiple elements vertically.</p>
|
<p>Stacks multiple elements horizontally.</p>
|
||||||
<pre><code class="html" data-trim data-line-numbers>
|
<pre><code class="html" data-trim data-line-numbers>
|
||||||
<div class="r-vstack">
|
<div class="r-vstack">
|
||||||
<img width="450" height="300" src="...">
|
<img width="450" height="300" src="...">
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
<!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>
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<title>reveal.js - Markdown Example</title>
|
<title>reveal.js - Markdown Example</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../dist/reveal.css">
|
<link rel="stylesheet" href="../dist/reveal.css">
|
||||||
<link rel="stylesheet" href="../dist/theme/black.css" id="theme">
|
<link rel="stylesheet" href="../dist/theme/white.css" id="theme">
|
||||||
|
|
||||||
<link rel="stylesheet" href="../plugin/highlight/monokai.css">
|
<link rel="stylesheet" href="../plugin/highlight/monokai.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -21,6 +21,91 @@
|
|||||||
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
|
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
|
||||||
<section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
|
<section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
|
||||||
|
|
||||||
|
<!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
|
||||||
|
<section data-markdown data-separator="---">
|
||||||
|
<script type="text/template">
|
||||||
|
## Demo 1
|
||||||
|
Slide 1
|
||||||
|
---
|
||||||
|
## Demo 1
|
||||||
|
Slide 2
|
||||||
|
---
|
||||||
|
## Demo 1
|
||||||
|
Slide 3
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
|
||||||
|
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
|
||||||
|
<script type="text/template">
|
||||||
|
## Demo 2
|
||||||
|
Slide 1.1
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
## Demo 2
|
||||||
|
Slide 1.2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Demo 2
|
||||||
|
Slide 2
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
|
||||||
|
<section data-markdown>
|
||||||
|
<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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -28,19 +113,16 @@
|
|||||||
<script src="../plugin/markdown/markdown.js"></script>
|
<script src="../plugin/markdown/markdown.js"></script>
|
||||||
<script src="../plugin/highlight/highlight.js"></script>
|
<script src="../plugin/highlight/highlight.js"></script>
|
||||||
<script src="../plugin/notes/notes.js"></script>
|
<script src="../plugin/notes/notes.js"></script>
|
||||||
<script src="../plugin/math/math.js"></script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
Reveal.initialize({
|
Reveal.initialize({
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
controls: true,
|
controls: true,
|
||||||
progress: true,
|
progress: true,
|
||||||
history: true,
|
history: true,
|
||||||
center: true,
|
center: true,
|
||||||
|
|
||||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes, RevealMath.KaTeX ]
|
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,133 +1,36 @@
|
|||||||
# RUG: Turbo LLM for Rust Unit Test Generation
|
# Markdown Demo
|
||||||
|
|
||||||
Keywords: LLM, Rust, Unit Test
|
|
||||||
|
|
||||||
Research date: 2022, published date: 2025
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Introduction
|
## External 1.1
|
||||||
|
|
||||||
* Unit testing is crucial but costly.
|
Content 1.1
|
||||||
|
|
||||||
* Rust's strict type system.
|
Note: This will only appear in the speaker notes window.
|
||||||
|
|
||||||
* Existing LLM approaches often fail.
|
|
||||||
|
|
||||||
|
|
||||||
#### Rust Unit Test
|
## External 1.2
|
||||||
|
|
||||||
```rust
|
Content 1.2
|
||||||
/// Returns the sum of two numbers
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// assert_eq!(add(2, 3), 5);
|
|
||||||
/// assert_eq!(add(-1, 1), 0);
|
|
||||||
/// ```
|
|
||||||
fn add(a: i32, b: i32) -> i32 {
|
|
||||||
a + b
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### Challenge
|
|
||||||
|
|
||||||
```rust
|
|
||||||
fn encode<E: Encoder>(&self: char, encoder: E) -> Result<EncodeError> // target function
|
|
||||||
|
|
||||||
impl<W: Writer, C: Config> Encoder for EncoderImpl
|
|
||||||
|
|
||||||
pub struct EncoderImpl<W: Writer, C: Config>
|
|
||||||
impl Writer for SliceWriter
|
|
||||||
impl Writer for IoWriter
|
|
||||||
|
|
||||||
impl<T> Config for T where T: R1 + R2 + R3
|
|
||||||
pub struct Configuration<R1, R2, R3>
|
|
||||||
```
|
|
||||||
|
|
||||||
Simplified python version
|
|
||||||
|
|
||||||
```python
|
|
||||||
def encode(char_data, encoder):
|
|
||||||
result = encoder.process(char_data)
|
|
||||||
return result
|
|
||||||
|
|
||||||
class Encoder:
|
|
||||||
def __init__(self, writer, config):
|
|
||||||
self.config = config
|
|
||||||
|
|
||||||
def process(self, data):
|
|
||||||
output = self.writer.write(data, self.config)
|
|
||||||
return output
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
def __init__(self):
|
|
||||||
self.settings = {}
|
|
||||||
|
|
||||||
config = Config()
|
|
||||||
encoder = Encoder(stdout, config)
|
|
||||||
|
|
||||||
# Test code
|
|
||||||
result = encode('A', encoder)
|
|
||||||
```
|
|
||||||
|
|
||||||
LLM generated code are hard to pass the compiler.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### RUG design
|
## External 2
|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_010053.jpeg"
|
Content 2.1
|
||||||
width="75%">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_011029.jpeg" width="80%">
|
## External 3.1
|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_011348.jpeg" width="80%">
|
Content 3.1
|
||||||
|
|
||||||
|
|
||||||
|
## External 3.2
|
||||||
|
|
||||||
#### Implementation
|
Content 3.2
|
||||||
|
|
||||||
- gpt-3.5-turbo-16k-0613
|
|
||||||
- gpt-4-1106
|
|
||||||
- presence penalty set to -1
|
|
||||||
- frequency_penalty set to 0.5
|
|
||||||
- temperature set to 1 (by default)
|
|
||||||
|
|
||||||
|
|
||||||
|
## External 3.3
|
||||||
|
|
||||||
#### Eval: Comparison with Traditional Tools
|

|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_014355.jpeg" width="75%">
|
|
||||||
|
|
||||||
|
|
||||||
#### Token Consumption
|
|
||||||
|
|
||||||
- GPT-4 cost 1000$ in baseline method (send the whole context)
|
|
||||||
- RUG saved 51.3% tokens (process unique dependency only once)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Real-World Usability
|
|
||||||
|
|
||||||
> We directly leverage RUG's generated tests, without changing test bodies and send them as PRs to the open source projects.
|
|
||||||
> To our surprise, the developers are happy to merge these machine generated tests.
|
|
||||||
> RUG generated a total of 248 unit tests, of which we submitted 113 to the corresponding crates based on their quality and priority.
|
|
||||||
> So far, 53 of these unit tests have been merged with positive feedback.
|
|
||||||
|
|
||||||
> Developers chose not to merge 17 tests for two main reasons:
|
|
||||||
> first, the target functions are imported from external libraries(16),
|
|
||||||
> and the developers do not intend to include tests
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 2025 Situation
|
|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_015416.jpeg" width="60%">
|
|
||||||
|
|
||||||
|
|
||||||
<img src="./images/Screenshot_20251125_015705.jpeg" width="60%">
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>reveal.js Math Plugin</h2>
|
<h2>reveal.js Math Plugin</h2>
|
||||||
<p>Render math with KaTeX, MathJax 2 or MathJax 3</p>
|
<p>A thin wrapper for MathJax</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@@ -182,7 +182,8 @@
|
|||||||
history: true,
|
history: true,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
|
|
||||||
mathjax2: {
|
math: {
|
||||||
|
// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
|
||||||
config: 'TeX-AMS_HTML-full',
|
config: 'TeX-AMS_HTML-full',
|
||||||
TeX: {
|
TeX: {
|
||||||
Macros: {
|
Macros: {
|
||||||
@@ -192,13 +193,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// There are three typesetters available
|
plugins: [ RevealMath ]
|
||||||
// RevealMath.MathJax2 (default)
|
|
||||||
// RevealMath.MathJax3
|
|
||||||
// RevealMath.KaTeX
|
|
||||||
//
|
|
||||||
// More info at https://revealjs.com/math/
|
|
||||||
plugins: [ RevealMath.MathJax2 ]
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,10 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>Video</h2>
|
<h2>Video</h2>
|
||||||
<video src="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-autoplay></video>
|
<video src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" data-autoplay></video>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4">
|
<section data-background-video="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">
|
||||||
<h2>Background Video</h2>
|
<h2>Background Video</h2>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
<!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>
|
|
||||||
95
gulpfile.js
95
gulpfile.js
@@ -1,20 +1,22 @@
|
|||||||
const fs = require('fs');
|
|
||||||
const pkg = require('./package.json')
|
const pkg = require('./package.json')
|
||||||
|
const path = require('path')
|
||||||
const glob = require('glob')
|
const glob = require('glob')
|
||||||
const yargs = require('yargs')
|
const yargs = require('yargs')
|
||||||
|
const colors = require('colors')
|
||||||
const through = require('through2');
|
const through = require('through2');
|
||||||
const qunit = require('node-qunit-puppeteer')
|
const qunit = require('node-qunit-puppeteer')
|
||||||
|
|
||||||
const {rollup} = require('rollup')
|
const {rollup} = require('rollup')
|
||||||
const terser = require('@rollup/plugin-terser')
|
const {terser} = require('rollup-plugin-terser')
|
||||||
const babel = require('@rollup/plugin-babel').default
|
const babel = require('@rollup/plugin-babel').default
|
||||||
const commonjs = require('@rollup/plugin-commonjs')
|
const commonjs = require('@rollup/plugin-commonjs')
|
||||||
const resolve = require('@rollup/plugin-node-resolve').default
|
const resolve = require('@rollup/plugin-node-resolve').default
|
||||||
const sass = require('sass')
|
const sass = require('sass')
|
||||||
|
|
||||||
const gulp = require('gulp')
|
const gulp = require('gulp')
|
||||||
|
const tap = require('gulp-tap')
|
||||||
const zip = require('gulp-zip')
|
const zip = require('gulp-zip')
|
||||||
const header = require('gulp-header-comment')
|
const header = require('gulp-header')
|
||||||
const eslint = require('gulp-eslint')
|
const eslint = require('gulp-eslint')
|
||||||
const minify = require('gulp-clean-css')
|
const minify = require('gulp-clean-css')
|
||||||
const connect = require('gulp-connect')
|
const connect = require('gulp-connect')
|
||||||
@@ -22,23 +24,14 @@ const autoprefixer = require('gulp-autoprefixer')
|
|||||||
|
|
||||||
const root = yargs.argv.root || '.'
|
const root = yargs.argv.root || '.'
|
||||||
const port = yargs.argv.port || 8000
|
const port = yargs.argv.port || 8000
|
||||||
const host = yargs.argv.host || 'localhost'
|
|
||||||
|
|
||||||
const cssLicense = `
|
const banner = `/*!
|
||||||
reveal.js ${pkg.version}
|
* reveal.js ${pkg.version}
|
||||||
${pkg.homepage}
|
* ${pkg.homepage}
|
||||||
MIT licensed
|
* MIT licensed
|
||||||
|
*
|
||||||
Copyright (C) 2011-2024 Hakim El Hattab, https://hakim.se
|
* Copyright (C) 2020 Hakim El Hattab, https://hakim.se
|
||||||
`;
|
*/\n`
|
||||||
|
|
||||||
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
|
// Prevents warnings from opening too many test pages
|
||||||
process.setMaxListeners(20);
|
process.setMaxListeners(20);
|
||||||
@@ -67,11 +60,11 @@ const babelConfig = {
|
|||||||
// polyfilling older browsers and a larger bundle.
|
// polyfilling older browsers and a larger bundle.
|
||||||
const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) );
|
const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) );
|
||||||
babelConfigESM.presets[0][1].targets = { browsers: [
|
babelConfigESM.presets[0][1].targets = { browsers: [
|
||||||
'last 2 Chrome versions',
|
'last 2 Chrome versions', 'not Chrome < 60',
|
||||||
'last 2 Safari versions',
|
'last 2 Safari versions', 'not Safari < 10.1',
|
||||||
'last 2 iOS versions',
|
'last 2 iOS versions', 'not iOS < 10.3',
|
||||||
'last 2 Firefox versions',
|
'last 2 Firefox versions', 'not Firefox < 60',
|
||||||
'last 2 Edge versions',
|
'last 2 Edge versions', 'not Edge < 16',
|
||||||
] };
|
] };
|
||||||
|
|
||||||
let cache = {};
|
let cache = {};
|
||||||
@@ -94,7 +87,7 @@ gulp.task('js-es5', () => {
|
|||||||
name: 'Reveal',
|
name: 'Reveal',
|
||||||
file: './dist/reveal.js',
|
file: './dist/reveal.js',
|
||||||
format: 'umd',
|
format: 'umd',
|
||||||
banner: jsLicense,
|
banner: banner,
|
||||||
sourcemap: true
|
sourcemap: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -116,7 +109,7 @@ gulp.task('js-es6', () => {
|
|||||||
return bundle.write({
|
return bundle.write({
|
||||||
file: './dist/reveal.esm.js',
|
file: './dist/reveal.esm.js',
|
||||||
format: 'es',
|
format: 'es',
|
||||||
banner: jsLicense,
|
banner: banner,
|
||||||
sourcemap: true
|
sourcemap: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -169,12 +162,12 @@ function compileSass() {
|
|||||||
const transformedFile = vinylFile.clone();
|
const transformedFile = vinylFile.clone();
|
||||||
|
|
||||||
sass.render({
|
sass.render({
|
||||||
silenceDeprecations: ['legacy-js-api'],
|
|
||||||
data: transformedFile.contents.toString(),
|
data: transformedFile.contents.toString(),
|
||||||
file: transformedFile.path,
|
includePaths: ['css/', 'css/theme/template']
|
||||||
}, ( err, result ) => {
|
}, ( err, result ) => {
|
||||||
if( err ) {
|
if( err ) {
|
||||||
callback(err);
|
console.log( vinylFile.path );
|
||||||
|
console.log( err.formatted );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
transformedFile.extname = '.css';
|
transformedFile.extname = '.css';
|
||||||
@@ -193,7 +186,7 @@ gulp.task('css-core', () => gulp.src(['css/reveal.scss'])
|
|||||||
.pipe(compileSass())
|
.pipe(compileSass())
|
||||||
.pipe(autoprefixer())
|
.pipe(autoprefixer())
|
||||||
.pipe(minify({compatibility: 'ie9'}))
|
.pipe(minify({compatibility: 'ie9'}))
|
||||||
.pipe(header(cssLicense))
|
.pipe(header(banner))
|
||||||
.pipe(gulp.dest('./dist')))
|
.pipe(gulp.dest('./dist')))
|
||||||
|
|
||||||
gulp.task('css', gulp.parallel('css-themes', 'css-core'))
|
gulp.task('css', gulp.parallel('css-themes', 'css-core'))
|
||||||
@@ -203,7 +196,7 @@ gulp.task('qunit', () => {
|
|||||||
let serverConfig = {
|
let serverConfig = {
|
||||||
root,
|
root,
|
||||||
port: 8009,
|
port: 8009,
|
||||||
host: 'localhost',
|
host: '0.0.0.0',
|
||||||
name: 'test-server'
|
name: 'test-server'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +213,7 @@ gulp.task('qunit', () => {
|
|||||||
targetUrl: `http://${serverConfig.host}:${serverConfig.port}/${filename}`,
|
targetUrl: `http://${serverConfig.host}:${serverConfig.port}/${filename}`,
|
||||||
timeout: 20000,
|
timeout: 20000,
|
||||||
redirectConsole: false,
|
redirectConsole: false,
|
||||||
puppeteerArgs: ['--allow-file-access-from-files', '--no-sandbox']
|
puppeteerArgs: ['--allow-file-access-from-files']
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if( result.stats.failed > 0 ) {
|
if( result.stats.failed > 0 ) {
|
||||||
@@ -275,25 +268,20 @@ gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test'))
|
|||||||
|
|
||||||
gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
|
gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
|
||||||
|
|
||||||
gulp.task('package', gulp.series(async () => {
|
gulp.task('package', gulp.series('default', () =>
|
||||||
|
|
||||||
let dirs = [
|
gulp.src([
|
||||||
'./index.html',
|
'./index.html',
|
||||||
'./dist/**',
|
'./dist/**',
|
||||||
|
'./lib/**',
|
||||||
|
'./images/**',
|
||||||
'./plugin/**',
|
'./plugin/**',
|
||||||
'./*/*.md'
|
'./**.md'
|
||||||
];
|
]).pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
|
||||||
|
|
||||||
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 } )
|
gulp.task('reload', () => gulp.src(['*.html', '*.md'])
|
||||||
.pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
|
|
||||||
|
|
||||||
}))
|
|
||||||
|
|
||||||
gulp.task('reload', () => gulp.src(['index.html'])
|
|
||||||
.pipe(connect.reload()));
|
.pipe(connect.reload()));
|
||||||
|
|
||||||
gulp.task('serve', () => {
|
gulp.task('serve', () => {
|
||||||
@@ -301,23 +289,18 @@ gulp.task('serve', () => {
|
|||||||
connect.server({
|
connect.server({
|
||||||
root: root,
|
root: root,
|
||||||
port: port,
|
port: port,
|
||||||
host: host,
|
host: '0.0.0.0',
|
||||||
livereload: true
|
livereload: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const slidesRoot = root.endsWith('/') ? root : root + '/'
|
gulp.watch(['*.html', '*.md'], gulp.series('reload'))
|
||||||
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(['js/**'], gulp.series('js', 'reload', 'test'))
|
||||||
|
|
||||||
gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload'))
|
gulp.watch(['plugin/**/plugin.js'], gulp.series('plugins', 'reload'))
|
||||||
|
|
||||||
gulp.watch([
|
gulp.watch([
|
||||||
'css/theme/source/**/*.{sass,scss}',
|
'css/theme/source/*.{sass,scss}',
|
||||||
'css/theme/template/*.{sass,scss}',
|
'css/theme/template/*.{sass,scss}',
|
||||||
], gulp.series('css-themes', 'reload'))
|
], gulp.series('css-themes', 'reload'))
|
||||||
|
|
||||||
@@ -328,4 +311,4 @@ gulp.task('serve', () => {
|
|||||||
|
|
||||||
gulp.watch(['test/*.html'], gulp.series('test'))
|
gulp.watch(['test/*.html'], gulp.series('test'))
|
||||||
|
|
||||||
})
|
})
|
||||||
303
index.html
303
index.html
@@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
@@ -12,12 +12,307 @@
|
|||||||
|
|
||||||
<!-- Theme used for syntax highlighted code -->
|
<!-- Theme used for syntax highlighted code -->
|
||||||
<link rel="stylesheet" href="plugin/highlight/monokai.css">
|
<link rel="stylesheet" href="plugin/highlight/monokai.css">
|
||||||
|
<style>
|
||||||
|
big {
|
||||||
|
font-size: 139%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="reveal">
|
<div class="reveal">
|
||||||
<div class="slides">
|
<div class="slides">
|
||||||
<section>Slide 1</section>
|
<section>
|
||||||
<section>Slide 2</section>
|
<section>
|
||||||
|
<h2>代码如诗</h2>
|
||||||
|
<small>Python 代码风格规范 (PEP8)</small>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<section data-markdown>
|
||||||
|
### 一般注释
|
||||||
|
|
||||||
|
```python
|
||||||
|
some_code()
|
||||||
|
more_code_here()
|
||||||
|
|
||||||
|
# One sentence explaining
|
||||||
|
if not data:
|
||||||
|
do_something_here()
|
||||||
|
|
||||||
|
other_code()
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
### 行内注释
|
||||||
|
|
||||||
|
```python
|
||||||
|
words = 'Hello, World!' # Some comment here
|
||||||
|
something = 'Hahaha' # 注释不需要对齐
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 块注释
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 通常在需要 review 的晦涩难懂的代码前
|
||||||
|
# 留下 TODO、待 review 的说明
|
||||||
|
# 不要在这里流水帐式描述你的代码
|
||||||
|
# 如: 「此处判定列表各项均为有效值,然后我们...」
|
||||||
|
# 要假定 reviewer 比你更懂 Python
|
||||||
|
|
||||||
|
if 0 in [!int(node) for node in li]: # 恰到好处的注释
|
||||||
|
```
|
||||||
|
|
||||||
|
> 如果代码不够清晰以至于需要一个注释,那么或许它应该被重写。
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 函数注释
|
||||||
|
|
||||||
|
```python
|
||||||
|
def print(arg):
|
||||||
|
"""将 arg 打印在屏幕上
|
||||||
|
|
||||||
|
这个函数会调用内置方法讲 arg 输出到屏幕上,
|
||||||
|
注意这个函数不是线程安全的。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
arg: 字符串或可以调用 arg.__str__() 的对象
|
||||||
|
|
||||||
|
返回值:
|
||||||
|
返回一个整数,代表输出的字符串长度
|
||||||
|
|
||||||
|
抛出异常:
|
||||||
|
NameError: 参数没有 __str__() 方法供转化成字符串。
|
||||||
|
"""
|
||||||
|
do_some_thing()
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 类注释
|
||||||
|
|
||||||
|
```python
|
||||||
|
class SampleClass:
|
||||||
|
"""简单描述这个类
|
||||||
|
|
||||||
|
详细说明这个类...
|
||||||
|
可以有很多行说明...
|
||||||
|
|
||||||
|
类成员说名:
|
||||||
|
Blablabla
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
"""类方法说明"""
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<section><h1><code>String</code></h1></section>
|
||||||
|
<section data-markdown=>
|
||||||
|
需要拼接有空格的字符串,运用占位符
|
||||||
|
|
||||||
|
```python
|
||||||
|
x = '%s, %s!' % (a, b)
|
||||||
|
x = '{}, {}!'.format(a, b)
|
||||||
|
x = ', '.join([a, b])
|
||||||
|
```
|
||||||
|
|
||||||
|
直接拼接的字符串
|
||||||
|
|
||||||
|
```python
|
||||||
|
x = a + b
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
> 注意:使用加法循环拼接字符串,可能导致二次而非线性的运行时间。
|
||||||
|
|
||||||
|
BAD
|
||||||
|
|
||||||
|
```python
|
||||||
|
li = ['a', 'very', 'long', 'list']
|
||||||
|
result = ''
|
||||||
|
for i in li:
|
||||||
|
result = result + i
|
||||||
|
print(result)
|
||||||
|
```
|
||||||
|
|
||||||
|
GOOD
|
||||||
|
|
||||||
|
```python
|
||||||
|
result = ''.join(li)
|
||||||
|
print(result)
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
当字符串过长时,使用 `\` 漂亮地分割字符串
|
||||||
|
|
||||||
|
```python
|
||||||
|
s = '这是一个' \
|
||||||
|
'很长的字符串'
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<section>其他乱七八糟但很重要的东西</section>
|
||||||
|
<section>
|
||||||
|
<p>类名以<big>大</big>写字母开头 <code>ClassName</code></p>
|
||||||
|
<p>驼峰<big>命</big>名法 <code>someFunctionName</code></p>
|
||||||
|
<p>下划线_命名法 <code>some_variable_name</code></p>
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
### 遍历同时操作数组
|
||||||
|
|
||||||
|
> 不规范的行为
|
||||||
|
|
||||||
|
```python
|
||||||
|
li = list(range(10))
|
||||||
|
for i in li:
|
||||||
|
li.append(i)
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
### 传参传字典或列表
|
||||||
|
|
||||||
|
```python
|
||||||
|
def foo(i, arg=[]): # 正确做法 arg=None
|
||||||
|
arg.append(i)
|
||||||
|
print(arg)
|
||||||
|
|
||||||
|
foo('a')
|
||||||
|
# Output: ['a']
|
||||||
|
foo('b')
|
||||||
|
# Output: ['a', 'b']
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
### 文件中读入的字符莫名消失
|
||||||
|
|
||||||
|
复现代码
|
||||||
|
|
||||||
|
```python
|
||||||
|
raw = '第一行\n\r第二行'
|
||||||
|
|
||||||
|
for i in raw.split('\n'):
|
||||||
|
print('---start', i, 'end---')
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
# ---start 第一行 end---
|
||||||
|
# 第二行 end---
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
GOOD
|
||||||
|
|
||||||
|
```python
|
||||||
|
if age < 18:
|
||||||
|
return 'You are too small'
|
||||||
|
|
||||||
|
do_something_here()
|
||||||
|
```
|
||||||
|
|
||||||
|
BAD
|
||||||
|
|
||||||
|
```python
|
||||||
|
if age > 18:
|
||||||
|
do_something_here()
|
||||||
|
else:
|
||||||
|
return 'You are too small'
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 善用 if
|
||||||
|
|
||||||
|
GOOD
|
||||||
|
|
||||||
|
```python
|
||||||
|
if data:
|
||||||
|
break
|
||||||
|
```
|
||||||
|
|
||||||
|
BAD
|
||||||
|
|
||||||
|
```python
|
||||||
|
if data != []:
|
||||||
|
break
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<section data-markdown>
|
||||||
|
## 忍者代码
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 没人知道这个变量是什么
|
||||||
|
|
||||||
|
- a, b, j, k, l
|
||||||
|
- str, string, number, list, dict
|
||||||
|
- data
|
||||||
|
- data1
|
||||||
|
- data114514
|
||||||
|
|
||||||
|
以及见鬼的缩写
|
||||||
|
|
||||||
|
- `ObjStuAre_id`: object_student_area_id
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
> 一个变量,一杯茶,一个bug修一天
|
||||||
|
|
||||||
|
- `data`
|
||||||
|
- `date`
|
||||||
|
- `l`
|
||||||
|
- `I`
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 没人知道这两是不是同一个东西
|
||||||
|
|
||||||
|
- `showMessage`
|
||||||
|
- `displayMessage`
|
||||||
|
- `printMessage`
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 夸张的变量名
|
||||||
|
|
||||||
|
- `very_super_powerful_print_function`
|
||||||
|
- `lovely_variable`
|
||||||
|
- `nice_list`
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### 重叠外部命名空间变量
|
||||||
|
|
||||||
|
```python
|
||||||
|
id = 39
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
id += 1
|
||||||
|
|
||||||
|
# 一堆代码
|
||||||
|
|
||||||
|
print(id)
|
||||||
|
```
|
||||||
|
</section>
|
||||||
|
<section data-markdown>
|
||||||
|
#### Powerful Function !
|
||||||
|
|
||||||
|
例如某个 `check_empty_in_list()`,按字面意思会检查列表中是否有空项,可这个函数在检查到空项的同时还会「智能地」帮你删掉空项。然而使用函数的人对此一无所知,函数作者也忘了有这么回事。
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<p>一行!展现你的聪明才智!</p>
|
||||||
|
|
||||||
|
<code>
|
||||||
|
result = not os.system(' '.join(['proxychains', '-q', 'pandoc', 'README.md', 'SUMMARY.md', ' '.join([str(i)+'.md' for i in range(3, 109+1)]), '-o', '/tmp/out.epub']) or print("Failed")
|
||||||
|
</code>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<section style="text-align: left;" data-markdown>
|
||||||
|
#### References
|
||||||
|
|
||||||
|
- [现代 JavaScript 教程 - 忍者代码](https://zh.javascript.infoi/ninja-code)
|
||||||
|
- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
|
||||||
|
- [水族馆](https://aquarium39.moe)
|
||||||
|
- [你所不知道的Python冷知識](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/649905/)
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -37,4 +332,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
47
js/config.js
47
js/config.js
@@ -15,10 +15,7 @@ export default {
|
|||||||
minScale: 0.2,
|
minScale: 0.2,
|
||||||
maxScale: 2.0,
|
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,
|
controls: true,
|
||||||
|
|
||||||
// Help the user learn the controls by providing hints, for example by
|
// Help the user learn the controls by providing hints, for example by
|
||||||
@@ -68,16 +65,13 @@ export default {
|
|||||||
// Flags if we should monitor the hash and change slides accordingly
|
// Flags if we should monitor the hash and change slides accordingly
|
||||||
respondToHashChanges: true,
|
respondToHashChanges: true,
|
||||||
|
|
||||||
// Enable support for jump-to-slide navigation shortcuts
|
|
||||||
jumpToSlide: true,
|
|
||||||
|
|
||||||
// Push each slide change to the browser history. Implies `hash: true`
|
// Push each slide change to the browser history. Implies `hash: true`
|
||||||
history: false,
|
history: false,
|
||||||
|
|
||||||
// Enable keyboard shortcuts for navigation
|
// Enable keyboard shortcuts for navigation
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
|
|
||||||
// Optional function that blocks keyboard events when returning false
|
// Optional function that blocks keyboard events when retuning false
|
||||||
//
|
//
|
||||||
// If you set this to 'focused', we will only capture keyboard events
|
// If you set this to 'focused', we will only capture keyboard events
|
||||||
// for embedded decks when they are in focus
|
// for embedded decks when they are in focus
|
||||||
@@ -168,9 +162,6 @@ export default {
|
|||||||
// - false: All iframes with data-src will be loaded only when visible
|
// - false: All iframes with data-src will be loaded only when visible
|
||||||
preloadIframes: null,
|
preloadIframes: null,
|
||||||
|
|
||||||
// Prevent embedded iframes from automatically focusing on themselves
|
|
||||||
preventIframeAutoFocus: true,
|
|
||||||
|
|
||||||
// Can be used to globally disable auto-animation
|
// Can be used to globally disable auto-animation
|
||||||
autoAnimate: true,
|
autoAnimate: true,
|
||||||
|
|
||||||
@@ -262,36 +253,6 @@ export default {
|
|||||||
parallaxBackgroundHorizontal: null,
|
parallaxBackgroundHorizontal: null,
|
||||||
parallaxBackgroundVertical: 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
|
// The maximum number of pages a single slide can expand onto when printing
|
||||||
// to PDF, unlimited by default
|
// to PDF, unlimited by default
|
||||||
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
|
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
|
||||||
@@ -323,10 +284,6 @@ export default {
|
|||||||
// Time before the cursor is hidden (in ms)
|
// Time before the cursor is hidden (in ms)
|
||||||
hideCursorTime: 5000,
|
hideCursorTime: 5000,
|
||||||
|
|
||||||
// Should we automatically sort and set indices for fragments
|
|
||||||
// at each sync? (See Reveal.sync)
|
|
||||||
sortFragmentsOnSync: true,
|
|
||||||
|
|
||||||
// Script dependencies to load
|
// Script dependencies to load
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
|
||||||
|
|||||||
@@ -31,13 +31,10 @@ export default class AutoAnimate {
|
|||||||
let toSlideIndex = allSlides.indexOf( toSlide );
|
let toSlideIndex = allSlides.indexOf( toSlide );
|
||||||
let fromSlideIndex = allSlides.indexOf( fromSlide );
|
let fromSlideIndex = allSlides.indexOf( fromSlide );
|
||||||
|
|
||||||
// Ensure that;
|
// Ensure that both slides are auto-animate targets with the same data-auto-animate-id value
|
||||||
// 1. Both slides exist.
|
// (including null if absent on both) and that data-auto-animate-restart isn't set on the
|
||||||
// 2. Both slides are auto-animate targets with the same
|
// physically latter slide (independent of slide direction)
|
||||||
// data-auto-animate-id value (including null if absent on both).
|
if( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )
|
||||||
// 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' )
|
&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' )
|
||||||
&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
|
&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
|
||||||
|
|
||||||
@@ -53,19 +50,11 @@ export default class AutoAnimate {
|
|||||||
// Flag the navigation direction, needed for fragment buildup
|
// Flag the navigation direction, needed for fragment buildup
|
||||||
animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
|
animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
|
||||||
|
|
||||||
// If the from-slide is hidden because it has moved outside
|
|
||||||
// the view distance, we need to temporarily show it while
|
|
||||||
// measuring
|
|
||||||
let fromSlideIsHidden = fromSlide.style.display === 'none';
|
|
||||||
if( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;
|
|
||||||
|
|
||||||
// Inject our auto-animate styles for this transition
|
// Inject our auto-animate styles for this transition
|
||||||
let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
|
let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
|
||||||
return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
|
return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( fromSlideIsHidden ) fromSlide.style.display = 'none';
|
|
||||||
|
|
||||||
// Animate unmatched elements, if enabled
|
// Animate unmatched elements, if enabled
|
||||||
if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
|
if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
|
||||||
|
|
||||||
@@ -178,12 +167,28 @@ export default class AutoAnimate {
|
|||||||
let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
|
let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
|
||||||
toProps = this.getAutoAnimatableProperties( 'to', to, 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' ) ) {
|
if( to.classList.contains( 'fragment' ) ) {
|
||||||
|
|
||||||
// Don't auto-animate the opacity of fragments to avoid
|
// Don't auto-animate the opacity of fragments to avoid
|
||||||
// conflicts with fragment animations
|
// conflicts with fragment animations
|
||||||
delete toProps.styles['opacity'];
|
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
|
// If translation and/or scaling are enabled, css transform
|
||||||
@@ -386,14 +391,7 @@ export default class AutoAnimate {
|
|||||||
value = { value: style.to, explicitValue: true };
|
value = { value: style.to, explicitValue: true };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Use a unitless value for line-height so that it inherits properly
|
value = computedStyles[style.property];
|
||||||
if( style.property === 'line-height' ) {
|
|
||||||
value = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isNaN(value) ) {
|
|
||||||
value = computedStyles[style.property];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( value !== '' ) {
|
if( value !== '' ) {
|
||||||
@@ -448,14 +446,14 @@ export default class AutoAnimate {
|
|||||||
const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
|
const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
|
||||||
const mediaNodes = 'img, video, iframe';
|
const mediaNodes = 'img, video, iframe';
|
||||||
|
|
||||||
// Explicit matches via data-id
|
// Eplicit matches via data-id
|
||||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
|
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
|
||||||
return node.nodeName + ':::' + node.getAttribute( 'data-id' );
|
return node.nodeName + ':::' + node.getAttribute( 'data-id' );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {
|
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {
|
||||||
return node.nodeName + ':::' + node.textContent.trim();
|
return node.nodeName + ':::' + node.innerText;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Media
|
// Media
|
||||||
@@ -465,10 +463,11 @@ export default class AutoAnimate {
|
|||||||
|
|
||||||
// Code
|
// Code
|
||||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {
|
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {
|
||||||
return node.nodeName + ':::' + node.textContent.trim();
|
return node.nodeName + ':::' + node.innerText;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
pairs.forEach( pair => {
|
pairs.forEach( pair => {
|
||||||
|
|
||||||
// Disable scale transformations on text nodes, we transition
|
// Disable scale transformations on text nodes, we transition
|
||||||
// each individual text property instead
|
// each individual text property instead
|
||||||
if( matches( pair.from, textNodes ) ) {
|
if( matches( pair.from, textNodes ) ) {
|
||||||
@@ -491,7 +490,7 @@ export default class AutoAnimate {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-numbers[data-line-number]', node => {
|
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {
|
||||||
return node.getAttribute( 'data-line-number' );
|
return node.getAttribute( 'data-line-number' );
|
||||||
}, {
|
}, {
|
||||||
scale: false,
|
scale: false,
|
||||||
@@ -560,14 +559,14 @@ export default class AutoAnimate {
|
|||||||
|
|
||||||
// Retrieve the 'from' element
|
// Retrieve the 'from' element
|
||||||
if( fromMatches[key] ) {
|
if( fromMatches[key] ) {
|
||||||
const primaryIndex = toMatches[key].length - 1;
|
const pimaryIndex = toMatches[key].length - 1;
|
||||||
const secondaryIndex = fromMatches[key].length - 1;
|
const secondaryIndex = fromMatches[key].length - 1;
|
||||||
|
|
||||||
// If there are multiple identical from elements, retrieve
|
// If there are multiple identical from elements, retrieve
|
||||||
// the one at the same index as our to-element.
|
// the one at the same index as our to-element.
|
||||||
if( fromMatches[key][ primaryIndex ] ) {
|
if( fromMatches[key][ pimaryIndex ] ) {
|
||||||
fromElement = fromMatches[key][ primaryIndex ];
|
fromElement = fromMatches[key][ pimaryIndex ];
|
||||||
fromMatches[key][ primaryIndex ] = null;
|
fromMatches[key][ pimaryIndex ] = null;
|
||||||
}
|
}
|
||||||
// If there are no matching from-elements at the same index,
|
// If there are no matching from-elements at the same index,
|
||||||
// use the last one.
|
// use the last one.
|
||||||
@@ -595,7 +594,7 @@ export default class AutoAnimate {
|
|||||||
* fading of unmatched elements is turned on, these elements
|
* fading of unmatched elements is turned on, these elements
|
||||||
* will fade when going between auto-animate slides.
|
* will fade when going between auto-animate slides.
|
||||||
*
|
*
|
||||||
* Note that parents of auto-animate targets are NOT considered
|
* Note that parents of auto-animate targets are NOT considerd
|
||||||
* unmatched since fading them would break the auto-animation.
|
* unmatched since fading them would break the auto-animation.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} rootElement
|
* @param {HTMLElement} rootElement
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ export default class Backgrounds {
|
|||||||
backgroundVideo: slide.getAttribute( 'data-background-video' ),
|
backgroundVideo: slide.getAttribute( 'data-background-video' ),
|
||||||
backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
|
backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
|
||||||
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
||||||
backgroundGradient: slide.getAttribute( 'data-background-gradient' ),
|
|
||||||
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
||||||
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
||||||
backgroundTransition: slide.getAttribute( 'data-background-transition' ),
|
backgroundTransition: slide.getAttribute( 'data-background-transition' ),
|
||||||
@@ -151,7 +150,7 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
if( data.background ) {
|
if( data.background ) {
|
||||||
// Auto-wrap image urls in url(...)
|
// Auto-wrap image urls in url(...)
|
||||||
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp|webp)([?#\s]|$)/gi.test( data.background ) ) {
|
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) {
|
||||||
slide.setAttribute( 'data-background-image', data.background );
|
slide.setAttribute( 'data-background-image', data.background );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -162,14 +161,13 @@ export default class Backgrounds {
|
|||||||
// Create a hash for this combination of background settings.
|
// Create a hash for this combination of background settings.
|
||||||
// This is used to determine when two slide backgrounds are
|
// This is used to determine when two slide backgrounds are
|
||||||
// the same.
|
// the same.
|
||||||
if( data.background || data.backgroundColor || data.backgroundGradient || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
|
if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
|
||||||
element.setAttribute( 'data-background-hash', data.background +
|
element.setAttribute( 'data-background-hash', data.background +
|
||||||
data.backgroundSize +
|
data.backgroundSize +
|
||||||
data.backgroundImage +
|
data.backgroundImage +
|
||||||
data.backgroundVideo +
|
data.backgroundVideo +
|
||||||
data.backgroundIframe +
|
data.backgroundIframe +
|
||||||
data.backgroundColor +
|
data.backgroundColor +
|
||||||
data.backgroundGradient +
|
|
||||||
data.backgroundRepeat +
|
data.backgroundRepeat +
|
||||||
data.backgroundPosition +
|
data.backgroundPosition +
|
||||||
data.backgroundTransition +
|
data.backgroundTransition +
|
||||||
@@ -179,7 +177,6 @@ export default class Backgrounds {
|
|||||||
// Additional and optional background properties
|
// Additional and optional background properties
|
||||||
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
|
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
|
||||||
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
||||||
if( data.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;
|
|
||||||
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
||||||
|
|
||||||
if( dataPreload ) element.setAttribute( 'data-preload', '' );
|
if( dataPreload ) element.setAttribute( 'data-preload', '' );
|
||||||
@@ -190,30 +187,10 @@ export default class Backgrounds {
|
|||||||
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
|
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
|
||||||
if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
|
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
|
// 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
|
// signals if it is light or dark. If the slide has no background
|
||||||
// color, no class will be added
|
// color, no class will be added
|
||||||
let contrastColor = slide.getAttribute( 'data-background-color' );
|
let contrastColor = data.backgroundColor;
|
||||||
|
|
||||||
// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
|
// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
|
||||||
if( !contrastColor || !colorToRgb( contrastColor ) ) {
|
if( !contrastColor || !colorToRgb( contrastColor ) ) {
|
||||||
@@ -231,32 +208,14 @@ export default class Backgrounds {
|
|||||||
// an element with no background
|
// an element with no background
|
||||||
if( rgb && rgb.a !== 0 ) {
|
if( rgb && rgb.a !== 0 ) {
|
||||||
if( colorBrightness( contrastColor ) < 128 ) {
|
if( colorBrightness( contrastColor ) < 128 ) {
|
||||||
return 'has-dark-background';
|
slide.classList.add( 'has-dark-background' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 'has-light-background';
|
slide.classList.add( '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 );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -268,15 +227,14 @@ export default class Backgrounds {
|
|||||||
*/
|
*/
|
||||||
update( includeAll = false ) {
|
update( includeAll = false ) {
|
||||||
|
|
||||||
let config = this.Reveal.getConfig();
|
|
||||||
let currentSlide = this.Reveal.getCurrentSlide();
|
let currentSlide = this.Reveal.getCurrentSlide();
|
||||||
let indices = this.Reveal.getIndices();
|
let indices = this.Reveal.getIndices();
|
||||||
|
|
||||||
let currentBackground = null;
|
let currentBackground = null;
|
||||||
|
|
||||||
// Reverse past/future classes when in RTL mode
|
// Reverse past/future classes when in RTL mode
|
||||||
let horizontalPast = config.rtl ? 'future' : 'past',
|
let horizontalPast = this.Reveal.getConfig().rtl ? 'future' : 'past',
|
||||||
horizontalFuture = config.rtl ? 'past' : 'future';
|
horizontalFuture = this.Reveal.getConfig().rtl ? 'past' : 'future';
|
||||||
|
|
||||||
// Update the classes of all backgrounds to match the
|
// Update the classes of all backgrounds to match the
|
||||||
// states of their slides (past/present/future)
|
// states of their slides (past/present/future)
|
||||||
@@ -302,12 +260,10 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
backgroundv.classList.remove( 'past', 'present', 'future' );
|
backgroundv.classList.remove( 'past', 'present', 'future' );
|
||||||
|
|
||||||
const indexv = typeof indices.v === 'number' ? indices.v : 0;
|
if( v < indices.v ) {
|
||||||
|
|
||||||
if( v < indexv ) {
|
|
||||||
backgroundv.classList.add( 'past' );
|
backgroundv.classList.add( 'past' );
|
||||||
}
|
}
|
||||||
else if ( v > indexv ) {
|
else if ( v > indices.v ) {
|
||||||
backgroundv.classList.add( 'future' );
|
backgroundv.classList.add( 'future' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -322,53 +278,15 @@ 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
|
// Stop content inside of previous backgrounds
|
||||||
if( backgroundChanged && this.previousBackground ) {
|
if( this.previousBackground ) {
|
||||||
|
|
||||||
this.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );
|
this.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start content in the current background
|
// Start content in the current background
|
||||||
if( backgroundChanged && currentBackground ) {
|
if( currentBackground ) {
|
||||||
|
|
||||||
this.Reveal.slideContent.startEmbeddedContent( currentBackground );
|
this.Reveal.slideContent.startEmbeddedContent( currentBackground );
|
||||||
|
|
||||||
@@ -386,6 +304,14 @@ 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;
|
this.previousBackground = currentBackground;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -393,13 +319,20 @@ export default class Backgrounds {
|
|||||||
// If there's a background brightness flag for this slide,
|
// If there's a background brightness flag for this slide,
|
||||||
// bubble it to the .reveal container
|
// bubble it to the .reveal container
|
||||||
if( currentSlide ) {
|
if( currentSlide ) {
|
||||||
this.bubbleSlideContrastClassToElement( currentSlide, this.Reveal.getRevealElement() );
|
[ '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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the first background to apply without transition
|
// Allow the first background to apply without transition
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
this.element.classList.remove( 'no-transition' );
|
this.element.classList.remove( 'no-transition' );
|
||||||
}, 10 );
|
}, 1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,10 +394,4 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.element.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
41
js/controllers/controls.js
vendored
41
js/controllers/controls.js
vendored
@@ -1,4 +1,4 @@
|
|||||||
import { queryAll, enterFullscreen } from '../utils/util.js'
|
import { queryAll } from '../utils/util.js'
|
||||||
import { isAndroid } from '../utils/device.js'
|
import { isAndroid } from '../utils/device.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +12,6 @@ import { isAndroid } from '../utils/device.js'
|
|||||||
* - .navigate-left
|
* - .navigate-left
|
||||||
* - .navigate-next
|
* - .navigate-next
|
||||||
* - .navigate-prev
|
* - .navigate-prev
|
||||||
* - .enter-fullscreen
|
|
||||||
*/
|
*/
|
||||||
export default class Controls {
|
export default class Controls {
|
||||||
|
|
||||||
@@ -26,7 +25,6 @@ export default class Controls {
|
|||||||
this.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );
|
this.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );
|
||||||
this.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );
|
this.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );
|
||||||
this.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );
|
this.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );
|
||||||
this.onEnterFullscreen = this.onEnterFullscreen.bind( this );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +50,6 @@ export default class Controls {
|
|||||||
this.controlsDown = queryAll( revealElement, '.navigate-down' );
|
this.controlsDown = queryAll( revealElement, '.navigate-down' );
|
||||||
this.controlsPrev = queryAll( revealElement, '.navigate-prev' );
|
this.controlsPrev = queryAll( revealElement, '.navigate-prev' );
|
||||||
this.controlsNext = queryAll( revealElement, '.navigate-next' );
|
this.controlsNext = queryAll( revealElement, '.navigate-next' );
|
||||||
this.controlsFullscreen = queryAll( revealElement, '.enter-fullscreen' );
|
|
||||||
|
|
||||||
// The left, right and down arrows in the standard reveal.js controls
|
// The left, right and down arrows in the standard reveal.js controls
|
||||||
this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
|
this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
|
||||||
@@ -66,10 +63,7 @@ export default class Controls {
|
|||||||
*/
|
*/
|
||||||
configure( config, oldConfig ) {
|
configure( config, oldConfig ) {
|
||||||
|
|
||||||
this.element.style.display = (
|
this.element.style.display = config.controls ? 'block' : 'none';
|
||||||
config.controls &&
|
|
||||||
(config.controls !== 'speaker-only' || this.Reveal.isSpeakerNotes())
|
|
||||||
) ? 'block' : 'none';
|
|
||||||
|
|
||||||
this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
|
this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
|
||||||
this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
|
this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
|
||||||
@@ -83,10 +77,9 @@ export default class Controls {
|
|||||||
let pointerEvents = [ 'touchstart', 'click' ];
|
let pointerEvents = [ 'touchstart', 'click' ];
|
||||||
|
|
||||||
// Only support touch for Android, fixes double navigations in
|
// Only support touch for Android, fixes double navigations in
|
||||||
// stock browser. Use touchend for it to be considered a valid
|
// stock browser
|
||||||
// user interaction (so we're allowed to autoplay media).
|
|
||||||
if( isAndroid ) {
|
if( isAndroid ) {
|
||||||
pointerEvents = [ 'touchend' ];
|
pointerEvents = [ 'touchstart' ];
|
||||||
}
|
}
|
||||||
|
|
||||||
pointerEvents.forEach( eventName => {
|
pointerEvents.forEach( eventName => {
|
||||||
@@ -96,21 +89,19 @@ export default class Controls {
|
|||||||
this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
|
this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||||
this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||||
this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
|
this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||||
this.controlsFullscreen.forEach( el => el.addEventListener( eventName, this.onEnterFullscreen, false ) );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unbind() {
|
unbind() {
|
||||||
|
|
||||||
[ 'touchstart', 'touchend', 'click' ].forEach( eventName => {
|
[ 'touchstart', 'click' ].forEach( eventName => {
|
||||||
this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
|
this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
|
||||||
this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
|
this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
|
||||||
this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
|
this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
|
||||||
this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
|
this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||||
this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||||
this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
|
this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||||
this.controlsFullscreen.forEach( el => el.removeEventListener( eventName, this.onEnterFullscreen, false ) );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -150,14 +141,9 @@ export default class Controls {
|
|||||||
if( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
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' ); } );
|
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
|
// Apply fragment decorators to directional buttons based on
|
||||||
// what slide axis they are in
|
// what slide axis they are in
|
||||||
if( isVerticalStack && hasVerticalSiblings ) {
|
if( this.Reveal.isVerticalSlide( currentSlide ) ) {
|
||||||
if( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
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' ); } );
|
if( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||||
}
|
}
|
||||||
@@ -202,13 +188,6 @@ export default class Controls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.unbind();
|
|
||||||
this.element.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handlers for navigation control buttons.
|
* Event handlers for navigation control buttons.
|
||||||
*/
|
*/
|
||||||
@@ -276,13 +255,5 @@ export default class Controls {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnterFullscreen( event ) {
|
|
||||||
|
|
||||||
const config = this.Reveal.getConfig();
|
|
||||||
const viewport = this.Reveal.getViewportElement();
|
|
||||||
|
|
||||||
enterFullscreen( config.embedded ? viewport : viewport.parentElement );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -79,12 +79,6 @@ export default class Focus {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.Reveal.getRevealElement().classList.remove( 'focused' );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onRevealPointerDown( event ) {
|
onRevealPointerDown( event ) {
|
||||||
|
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|||||||
@@ -174,23 +174,24 @@ export default class Fragments {
|
|||||||
*
|
*
|
||||||
* @return {{shown: array, hidden: array}}
|
* @return {{shown: array, hidden: array}}
|
||||||
*/
|
*/
|
||||||
update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {
|
update( index, fragments ) {
|
||||||
|
|
||||||
let changedFragments = {
|
let changedFragments = {
|
||||||
shown: [],
|
shown: [],
|
||||||
hidden: []
|
hidden: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if( slide && this.Reveal.getConfig().fragments ) {
|
let currentSlide = this.Reveal.getCurrentSlide();
|
||||||
|
if( currentSlide && this.Reveal.getConfig().fragments ) {
|
||||||
|
|
||||||
fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );
|
fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );
|
||||||
|
|
||||||
if( fragments.length ) {
|
if( fragments.length ) {
|
||||||
|
|
||||||
let maxIndex = 0;
|
let maxIndex = 0;
|
||||||
|
|
||||||
if( typeof index !== 'number' ) {
|
if( typeof index !== 'number' ) {
|
||||||
let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
|
let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
|
||||||
if( currentFragment ) {
|
if( currentFragment ) {
|
||||||
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
||||||
}
|
}
|
||||||
@@ -251,32 +252,12 @@ export default class Fragments {
|
|||||||
// the current fragment index.
|
// the current fragment index.
|
||||||
index = typeof index === 'number' ? index : -1;
|
index = typeof index === 'number' ? index : -1;
|
||||||
index = Math.max( Math.min( index, maxIndex ), -1 );
|
index = Math.max( Math.min( index, maxIndex ), -1 );
|
||||||
slide.setAttribute( 'data-fragment', index );
|
currentSlide.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;
|
return changedFragments;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -331,6 +312,26 @@ export default class Fragments {
|
|||||||
|
|
||||||
let changedFragments = this.update( index, 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.controls.update();
|
||||||
this.Reveal.progress.update();
|
this.Reveal.progress.update();
|
||||||
|
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
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,6 +17,7 @@ export default class Keyboard {
|
|||||||
this.bindings = {};
|
this.bindings = {};
|
||||||
|
|
||||||
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
||||||
|
this.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,18 +32,17 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.shortcuts['N , SPACE'] = 'Next slide';
|
this.shortcuts['N , SPACE'] = 'Next slide';
|
||||||
this.shortcuts['P , Shift SPACE'] = 'Previous slide';
|
this.shortcuts['P'] = 'Previous slide';
|
||||||
this.shortcuts['← , H'] = 'Navigate left';
|
this.shortcuts['← , H'] = 'Navigate left';
|
||||||
this.shortcuts['→ , L'] = 'Navigate right';
|
this.shortcuts['→ , L'] = 'Navigate right';
|
||||||
this.shortcuts['↑ , K'] = 'Navigate up';
|
this.shortcuts['↑ , K'] = 'Navigate up';
|
||||||
this.shortcuts['↓ , J'] = 'Navigate down';
|
this.shortcuts['↓ , J'] = 'Navigate down';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shortcuts['Alt + ←/↑/→/↓'] = 'Navigate without fragments';
|
this.shortcuts['Home , Shift ←'] = 'First slide';
|
||||||
this.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';
|
this.shortcuts['End , Shift →'] = 'Last slide';
|
||||||
this.shortcuts['B , .'] = 'Pause';
|
this.shortcuts['B , .'] = 'Pause';
|
||||||
this.shortcuts['F'] = 'Fullscreen';
|
this.shortcuts['F'] = 'Fullscreen';
|
||||||
this.shortcuts['G'] = 'Jump to slide';
|
|
||||||
this.shortcuts['ESC, O'] = 'Slide overview';
|
this.shortcuts['ESC, O'] = 'Slide overview';
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -53,6 +53,7 @@ export default class Keyboard {
|
|||||||
bind() {
|
bind() {
|
||||||
|
|
||||||
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
|
document.addEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ export default class Keyboard {
|
|||||||
unbind() {
|
unbind() {
|
||||||
|
|
||||||
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
|
document.removeEventListener( 'keypress', this.onDocumentKeyPress, false );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +134,20 @@ 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.
|
* Handler for the document level 'keydown' event.
|
||||||
*
|
*
|
||||||
@@ -166,11 +182,13 @@ export default class Keyboard {
|
|||||||
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
||||||
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
||||||
|
|
||||||
// Whitelist certain modifiers for slide navigation shortcuts
|
// Whitelist specific modified + keycode combinations
|
||||||
let keyCodeUsesModifier = [32, 37, 38, 39, 40, 63, 78, 80, 191].indexOf( event.keyCode ) !== -1;
|
let prevSlideShortcut = event.shiftKey && event.keyCode === 32;
|
||||||
|
let firstSlideShortcut = event.shiftKey && keyCode === 37;
|
||||||
|
let lastSlideShortcut = event.shiftKey && keyCode === 39;
|
||||||
|
|
||||||
// Prevent all other events when a modifier is pressed
|
// Prevent all other events when a modifier is pressed
|
||||||
let unusedModifier = !( keyCodeUsesModifier && event.shiftKey || event.altKey ) &&
|
let unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&
|
||||||
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
||||||
|
|
||||||
// Disregard the event if there's a focused element or a
|
// Disregard the event if there's a focused element or a
|
||||||
@@ -178,7 +196,7 @@ export default class Keyboard {
|
|||||||
if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
|
if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
|
||||||
|
|
||||||
// While paused only allow resume keyboard events; 'b', 'v', '.'
|
// While paused only allow resume keyboard events; 'b', 'v', '.'
|
||||||
let resumeKeyCodes = [66,86,190,191,112];
|
let resumeKeyCodes = [66,86,190,191];
|
||||||
let key;
|
let key;
|
||||||
|
|
||||||
// Custom key bindings for togglePause should be able to resume
|
// Custom key bindings for togglePause should be able to resume
|
||||||
@@ -190,10 +208,6 @@ 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 ) {
|
if( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -263,68 +277,52 @@ export default class Keyboard {
|
|||||||
|
|
||||||
// P, PAGE UP
|
// P, PAGE UP
|
||||||
if( keyCode === 80 || keyCode === 33 ) {
|
if( keyCode === 80 || keyCode === 33 ) {
|
||||||
this.Reveal.prev({skipFragments: event.altKey});
|
this.Reveal.prev();
|
||||||
}
|
}
|
||||||
// N, PAGE DOWN
|
// N, PAGE DOWN
|
||||||
else if( keyCode === 78 || keyCode === 34 ) {
|
else if( keyCode === 78 || keyCode === 34 ) {
|
||||||
this.Reveal.next({skipFragments: event.altKey});
|
this.Reveal.next();
|
||||||
}
|
}
|
||||||
// H, LEFT
|
// H, LEFT
|
||||||
else if( keyCode === 72 || keyCode === 37 ) {
|
else if( keyCode === 72 || keyCode === 37 ) {
|
||||||
if( event.shiftKey ) {
|
if( firstSlideShortcut ) {
|
||||||
this.Reveal.slide( 0 );
|
this.Reveal.slide( 0 );
|
||||||
}
|
}
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
if( config.rtl ) {
|
this.Reveal.prev();
|
||||||
this.Reveal.next({skipFragments: event.altKey});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.Reveal.prev({skipFragments: event.altKey});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.left({skipFragments: event.altKey});
|
this.Reveal.left();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// L, RIGHT
|
// L, RIGHT
|
||||||
else if( keyCode === 76 || keyCode === 39 ) {
|
else if( keyCode === 76 || keyCode === 39 ) {
|
||||||
if( event.shiftKey ) {
|
if( lastSlideShortcut ) {
|
||||||
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
|
this.Reveal.slide( Number.MAX_VALUE );
|
||||||
}
|
}
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
if( config.rtl ) {
|
this.Reveal.next();
|
||||||
this.Reveal.prev({skipFragments: event.altKey});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.Reveal.next({skipFragments: event.altKey});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.right({skipFragments: event.altKey});
|
this.Reveal.right();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// K, UP
|
// K, UP
|
||||||
else if( keyCode === 75 || keyCode === 38 ) {
|
else if( keyCode === 75 || keyCode === 38 ) {
|
||||||
if( event.shiftKey ) {
|
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
this.Reveal.slide( undefined, 0 );
|
this.Reveal.prev();
|
||||||
}
|
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
|
||||||
this.Reveal.prev({skipFragments: event.altKey});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.up({skipFragments: event.altKey});
|
this.Reveal.up();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// J, DOWN
|
// J, DOWN
|
||||||
else if( keyCode === 74 || keyCode === 40 ) {
|
else if( keyCode === 74 || keyCode === 40 ) {
|
||||||
if( event.shiftKey ) {
|
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
this.Reveal.slide( undefined, Number.MAX_VALUE );
|
this.Reveal.next();
|
||||||
}
|
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
|
||||||
this.Reveal.next({skipFragments: event.altKey});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.down({skipFragments: event.altKey});
|
this.Reveal.down();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// HOME
|
// HOME
|
||||||
@@ -333,7 +331,7 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
// END
|
// END
|
||||||
else if( keyCode === 35 ) {
|
else if( keyCode === 35 ) {
|
||||||
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
|
this.Reveal.slide( Number.MAX_VALUE );
|
||||||
}
|
}
|
||||||
// SPACE
|
// SPACE
|
||||||
else if( keyCode === 32 ) {
|
else if( keyCode === 32 ) {
|
||||||
@@ -341,14 +339,14 @@ export default class Keyboard {
|
|||||||
this.Reveal.overview.deactivate();
|
this.Reveal.overview.deactivate();
|
||||||
}
|
}
|
||||||
if( event.shiftKey ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.prev({skipFragments: event.altKey});
|
this.Reveal.prev();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.next({skipFragments: event.altKey});
|
this.Reveal.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
||||||
else if( [58, 59, 66, 86, 190].includes( keyCode ) || ( keyCode === 191 && !event.shiftKey ) ) {
|
else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
|
||||||
this.Reveal.togglePause();
|
this.Reveal.togglePause();
|
||||||
}
|
}
|
||||||
// F
|
// F
|
||||||
@@ -357,28 +355,10 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
// A
|
// A
|
||||||
else if( keyCode === 65 ) {
|
else if( keyCode === 65 ) {
|
||||||
if( config.autoSlideStoppable ) {
|
if ( config.autoSlideStoppable ) {
|
||||||
this.Reveal.toggleAutoSlide( autoSlideWasPaused );
|
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 {
|
else {
|
||||||
triggered = false;
|
triggered = false;
|
||||||
}
|
}
|
||||||
@@ -398,12 +378,6 @@ export default class Keyboard {
|
|||||||
|
|
||||||
event.preventDefault && event.preventDefault();
|
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
|
// If auto-sliding is enabled we need to cue up
|
||||||
// another timeout
|
// another timeout
|
||||||
@@ -411,4 +385,4 @@ export default class Keyboard {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export default class Location {
|
export default class Location {
|
||||||
|
|
||||||
// The minimum number of milliseconds that must pass between
|
|
||||||
// calls to history.replaceState
|
|
||||||
MAX_REPLACE_STATE_FREQUENCY = 1000
|
|
||||||
|
|
||||||
constructor( Reveal ) {
|
constructor( Reveal ) {
|
||||||
|
|
||||||
this.Reveal = Reveal;
|
this.Reveal = Reveal;
|
||||||
@@ -14,8 +10,6 @@ export default class Location {
|
|||||||
// Delays updates to the URL due to a Chrome thumbnailer bug
|
// Delays updates to the URL due to a Chrome thumbnailer bug
|
||||||
this.writeURLTimeout = 0;
|
this.writeURLTimeout = 0;
|
||||||
|
|
||||||
this.replaceStateTimestamp = 0;
|
|
||||||
|
|
||||||
this.onWindowHashChange = this.onWindowHashChange.bind( this );
|
this.onWindowHashChange = this.onWindowHashChange.bind( this );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -33,23 +27,24 @@ export default class Location {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the slide indices for the given hash link.
|
* Reads the current URL (hash) and navigates accordingly.
|
||||||
*
|
|
||||||
* @param {string} [hash] the hash string that we want to
|
|
||||||
* find the indices for
|
|
||||||
*
|
|
||||||
* @returns slide indices or null
|
|
||||||
*/
|
*/
|
||||||
getIndicesFromHash( hash=window.location.hash, options={} ) {
|
readURL() {
|
||||||
|
|
||||||
|
let config = this.Reveal.getConfig();
|
||||||
|
let indices = this.Reveal.getIndices();
|
||||||
|
let currentSlide = this.Reveal.getCurrentSlide();
|
||||||
|
|
||||||
|
let hash = window.location.hash;
|
||||||
|
|
||||||
// Attempt to parse the hash as either an index or name
|
// Attempt to parse the hash as either an index or name
|
||||||
let name = hash.replace( /^#\/?/, '' );
|
let bits = hash.slice( 2 ).split( '/' ),
|
||||||
let bits = name.split( '/' );
|
name = hash.replace( /#\/?/gi, '' );
|
||||||
|
|
||||||
// If the first bit is not fully numeric and there is a name we
|
// If the first bit is not fully numeric and there is a name we
|
||||||
// can assume that this is a named link
|
// can assume that this is a named link
|
||||||
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
||||||
let slide;
|
let element;
|
||||||
|
|
||||||
let f;
|
let f;
|
||||||
|
|
||||||
@@ -60,23 +55,30 @@ export default class Location {
|
|||||||
name = name.split( '/' ).shift();
|
name = name.split( '/' ).shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the named link is a valid HTML id or data-id attribute
|
// Ensure the named link is a valid HTML ID attribute
|
||||||
try {
|
try {
|
||||||
const decodedName = decodeURIComponent( name );
|
element = document.getElementById( decodeURIComponent( name ) );
|
||||||
slide = (
|
|
||||||
document.getElementById( decodedName ) ||
|
|
||||||
document.querySelector( `[data-id="${decodedName}"]` )
|
|
||||||
).closest('.slides section');
|
|
||||||
}
|
}
|
||||||
catch ( error ) { }
|
catch ( error ) { }
|
||||||
|
|
||||||
if( slide ) {
|
// Ensure that we're not already on a slide with the same name
|
||||||
return { ...this.Reveal.getIndices( slide ), f };
|
let isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false;
|
||||||
|
|
||||||
|
if( element ) {
|
||||||
|
// If the slide exists and is not the current slide...
|
||||||
|
if ( !isSameNameAsCurrentSlide || typeof f !== 'undefined' ) {
|
||||||
|
// ...find the position of the named slide and navigate to it
|
||||||
|
let slideIndices = this.Reveal.getIndices( element );
|
||||||
|
this.Reveal.slide( slideIndices.h, slideIndices.v, f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the slide doesn't exist, navigate to the current slide
|
||||||
|
else {
|
||||||
|
this.Reveal.slide( indices.h || 0, indices.v || 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const config = this.Reveal.getConfig();
|
let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
|
||||||
let hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0;
|
|
||||||
|
|
||||||
// Read the index components of the hash
|
// Read the index components of the hash
|
||||||
let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
|
let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
|
||||||
@@ -90,32 +92,10 @@ export default class Location {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { h, v, f };
|
if( h !== indices.h || v !== indices.v || f !== undefined ) {
|
||||||
}
|
this.Reveal.slide( h, v, f );
|
||||||
|
|
||||||
// The hash couldn't be parsed or no matching named link was found
|
|
||||||
return null
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the current URL (hash) and navigates accordingly.
|
|
||||||
*/
|
|
||||||
readURL() {
|
|
||||||
|
|
||||||
const currentIndices = this.Reveal.getIndices();
|
|
||||||
const newIndices = this.getIndicesFromHash();
|
|
||||||
|
|
||||||
if( newIndices ) {
|
|
||||||
if( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
|
|
||||||
this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If no new indices are available, we're trying to navigate to
|
|
||||||
// a slide hash that does not exist
|
|
||||||
else {
|
|
||||||
this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +123,7 @@ export default class Location {
|
|||||||
let hash = this.getHash();
|
let hash = this.getHash();
|
||||||
|
|
||||||
// If we're configured to push to history OR the history
|
// If we're configured to push to history OR the history
|
||||||
// API is not available.
|
// API is not avaialble.
|
||||||
if( config.history ) {
|
if( config.history ) {
|
||||||
window.location.hash = hash;
|
window.location.hash = hash;
|
||||||
}
|
}
|
||||||
@@ -152,10 +132,10 @@ export default class Location {
|
|||||||
else if( config.hash ) {
|
else if( config.hash ) {
|
||||||
// If the hash is empty, don't add it to the URL
|
// If the hash is empty, don't add it to the URL
|
||||||
if( hash === '/' ) {
|
if( hash === '/' ) {
|
||||||
this.debouncedReplaceState( window.location.pathname + window.location.search );
|
window.history.replaceState( null, null, window.location.pathname + window.location.search );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.debouncedReplaceState( '#' + hash );
|
window.history.replaceState( null, null, '#' + hash );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// UPDATE: The below nuking of all hash changes breaks
|
// UPDATE: The below nuking of all hash changes breaks
|
||||||
@@ -173,26 +153,6 @@ export default class Location {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceState( url ) {
|
|
||||||
|
|
||||||
window.history.replaceState( null, null, url );
|
|
||||||
this.replaceStateTimestamp = Date.now();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
debouncedReplaceState( url ) {
|
|
||||||
|
|
||||||
clearTimeout( this.replaceStateTimeout );
|
|
||||||
|
|
||||||
if( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {
|
|
||||||
this.replaceState( url );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a hash URL that will resolve to the given slide location.
|
* Return a hash URL that will resolve to the given slide location.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Handles the showing of speaker notes
|
* Handles the showing and
|
||||||
*/
|
*/
|
||||||
export default class Notes {
|
export default class Notes {
|
||||||
|
|
||||||
@@ -38,12 +38,10 @@ export default class Notes {
|
|||||||
*/
|
*/
|
||||||
update() {
|
update() {
|
||||||
|
|
||||||
if( this.Reveal.getConfig().showNotes &&
|
if( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {
|
||||||
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>';
|
this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -56,11 +54,7 @@ export default class Notes {
|
|||||||
*/
|
*/
|
||||||
updateVisibility() {
|
updateVisibility() {
|
||||||
|
|
||||||
if( this.Reveal.getConfig().showNotes &&
|
if( this.Reveal.getConfig().showNotes && this.hasNotes() && !this.Reveal.print.isPrintingPDF() ) {
|
||||||
this.hasNotes() &&
|
|
||||||
!this.Reveal.isScrollView() &&
|
|
||||||
!this.Reveal.isPrintView()
|
|
||||||
) {
|
|
||||||
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -95,7 +89,7 @@ export default class Notes {
|
|||||||
* Retrieves the speaker notes from a slide. Notes can be
|
* Retrieves the speaker notes from a slide. Notes can be
|
||||||
* defined in two ways:
|
* defined in two ways:
|
||||||
* 1. As a data-notes attribute on the slide <section>
|
* 1. As a data-notes attribute on the slide <section>
|
||||||
* 2. With <aside class="notes"> elements inside the slide
|
* 2. As an <aside class="notes"> inside of the slide
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} [slide=currentSlide]
|
* @param {HTMLElement} [slide=currentSlide]
|
||||||
* @return {(string|null)}
|
* @return {(string|null)}
|
||||||
@@ -107,20 +101,14 @@ export default class Notes {
|
|||||||
return slide.getAttribute( 'data-notes' );
|
return slide.getAttribute( 'data-notes' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... or using <aside class="notes"> elements
|
// ... or using an <aside class="notes"> element
|
||||||
let notesElements = slide.querySelectorAll( 'aside.notes' );
|
let notesElement = slide.querySelector( 'aside.notes' );
|
||||||
if( notesElements ) {
|
if( notesElement ) {
|
||||||
return Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' );
|
return notesElement.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.element.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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() {
|
activate() {
|
||||||
|
|
||||||
// Only proceed if enabled in config
|
// Only proceed if enabled in config
|
||||||
if( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {
|
if( this.Reveal.getConfig().overview && !this.isActive() ) {
|
||||||
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export default class Plugins {
|
|||||||
// Flags our current state (idle -> loading -> loaded)
|
// Flags our current state (idle -> loading -> loaded)
|
||||||
this.state = 'idle';
|
this.state = 'idle';
|
||||||
|
|
||||||
// An id:instance map of currently registered plugins
|
// An id:instance map of currently registed plugins
|
||||||
this.registeredPlugins = {};
|
this.registeredPlugins = {};
|
||||||
|
|
||||||
this.asyncDependencies = [];
|
this.asyncDependencies = [];
|
||||||
@@ -171,7 +171,7 @@ export default class Plugins {
|
|||||||
/**
|
/**
|
||||||
* Registers a new plugin with this reveal.js instance.
|
* Registers a new plugin with this reveal.js instance.
|
||||||
*
|
*
|
||||||
* reveal.js waits for all registered plugins to initialize
|
* reveal.js waits for all regisered plugins to initialize
|
||||||
* before considering itself ready, as long as the plugin
|
* before considering itself ready, as long as the plugin
|
||||||
* is registered before calling `Reveal.initialize()`.
|
* is registered before calling `Reveal.initialize()`.
|
||||||
*/
|
*/
|
||||||
@@ -238,17 +238,4 @@ export default class Plugins {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
Object.values( this.registeredPlugins ).forEach( plugin => {
|
|
||||||
if( typeof plugin.destroy === 'function' ) {
|
|
||||||
plugin.destroy();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
this.registeredPlugins = {};
|
|
||||||
this.asyncDependencies = [];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,12 @@ export default class Pointer {
|
|||||||
configure( config, oldConfig ) {
|
configure( config, oldConfig ) {
|
||||||
|
|
||||||
if( config.mouseWheel ) {
|
if( config.mouseWheel ) {
|
||||||
document.addEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
document.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
||||||
|
document.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
||||||
|
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-hide the mouse pointer when its inactive
|
// Auto-hide the mouse pointer when its inactive
|
||||||
@@ -73,16 +75,6 @@ export default class Pointer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.showCursor();
|
|
||||||
|
|
||||||
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
|
||||||
document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
|
|
||||||
document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever there is mouse input at the document level
|
* Called whenever there is mouse input at the document level
|
||||||
* to determine if the cursor is active or not.
|
* to determine if the cursor is active or not.
|
||||||
@@ -123,4 +115,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.
|
* Setups up our presentation for printing/exporting to PDF.
|
||||||
*/
|
*/
|
||||||
export default class PrintView {
|
export default class Print {
|
||||||
|
|
||||||
constructor( Reveal ) {
|
constructor( Reveal ) {
|
||||||
|
|
||||||
@@ -16,13 +16,13 @@ export default class PrintView {
|
|||||||
* Configures the presentation for printing to a static
|
* Configures the presentation for printing to a static
|
||||||
* PDF.
|
* PDF.
|
||||||
*/
|
*/
|
||||||
async activate() {
|
async setupPDF() {
|
||||||
|
|
||||||
const config = this.Reveal.getConfig();
|
const config = this.Reveal.getConfig();
|
||||||
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
|
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
|
||||||
|
|
||||||
// Compute slide numbers now, before we start duplicating slides
|
// Compute slide numbers now, before we start duplicating slides
|
||||||
const injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
|
const doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
|
||||||
|
|
||||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||||
|
|
||||||
@@ -42,23 +42,18 @@ export default class PrintView {
|
|||||||
// Limit the size of certain elements to the dimensions of the slide
|
// 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}' );
|
createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
|
||||||
|
|
||||||
document.documentElement.classList.add( 'reveal-print', 'print-pdf' );
|
document.documentElement.classList.add( 'print-pdf' );
|
||||||
document.body.style.width = pageWidth + 'px';
|
document.body.style.width = pageWidth + 'px';
|
||||||
document.body.style.height = pageHeight + 'px';
|
document.body.style.height = pageHeight + 'px';
|
||||||
|
|
||||||
const viewportElement = this.Reveal.getViewportElement();
|
|
||||||
let presentationBackground;
|
|
||||||
if( viewportElement ) {
|
|
||||||
const viewportStyles = window.getComputedStyle( viewportElement );
|
|
||||||
if( viewportStyles && viewportStyles.background ) {
|
|
||||||
presentationBackground = viewportStyles.background;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure stretch elements fit on slide
|
// Make sure stretch elements fit on slide
|
||||||
await new Promise( requestAnimationFrame );
|
await new Promise( requestAnimationFrame );
|
||||||
this.Reveal.layoutSlideContents( slideWidth, slideHeight );
|
this.Reveal.layoutSlideContents( slideWidth, slideHeight );
|
||||||
|
|
||||||
|
// Re-run the slide layout so that r-fit-text is applied based on
|
||||||
|
// the printed slide size
|
||||||
|
slides.forEach( slide => this.Reveal.slideContent.layout( slide ) );
|
||||||
|
|
||||||
// Batch scrollHeight access to prevent layout thrashing
|
// Batch scrollHeight access to prevent layout thrashing
|
||||||
await new Promise( requestAnimationFrame );
|
await new Promise( requestAnimationFrame );
|
||||||
|
|
||||||
@@ -66,7 +61,6 @@ export default class PrintView {
|
|||||||
|
|
||||||
const pages = [];
|
const pages = [];
|
||||||
const pageContainer = slides[0].parentNode;
|
const pageContainer = slides[0].parentNode;
|
||||||
let slideNumber = 1;
|
|
||||||
|
|
||||||
// Slide and slide background layout
|
// Slide and slide background layout
|
||||||
slides.forEach( function( slide, index ) {
|
slides.forEach( function( slide, index ) {
|
||||||
@@ -96,13 +90,6 @@ export default class PrintView {
|
|||||||
|
|
||||||
page.className = 'pdf-page';
|
page.className = 'pdf-page';
|
||||||
page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
|
page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
|
||||||
|
|
||||||
// Copy the presentation-wide background to each individual
|
|
||||||
// page when printing
|
|
||||||
if( presentationBackground ) {
|
|
||||||
page.style.background = presentationBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
page.appendChild( slide );
|
page.appendChild( slide );
|
||||||
|
|
||||||
// Position the slide inside of the page
|
// Position the slide inside of the page
|
||||||
@@ -110,8 +97,6 @@ export default class PrintView {
|
|||||||
slide.style.top = top + 'px';
|
slide.style.top = top + 'px';
|
||||||
slide.style.width = slideWidth + 'px';
|
slide.style.width = slideWidth + 'px';
|
||||||
|
|
||||||
this.Reveal.slideContent.layout( slide );
|
|
||||||
|
|
||||||
if( slide.slideBackgroundElement ) {
|
if( slide.slideBackgroundElement ) {
|
||||||
page.insertBefore( slide.slideBackgroundElement, slide );
|
page.insertBefore( slide.slideBackgroundElement, slide );
|
||||||
}
|
}
|
||||||
@@ -145,12 +130,13 @@ export default class PrintView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject page numbers if `slideNumbers` are enabled
|
// Inject slide numbers if `slideNumbers` are enabled
|
||||||
if( injectPageNumbers ) {
|
if( doingSlideNumbers ) {
|
||||||
|
const slideNumber = index + 1;
|
||||||
const numberElement = document.createElement( 'div' );
|
const numberElement = document.createElement( 'div' );
|
||||||
numberElement.classList.add( 'slide-number' );
|
numberElement.classList.add( 'slide-number' );
|
||||||
numberElement.classList.add( 'slide-number-pdf' );
|
numberElement.classList.add( 'slide-number-pdf' );
|
||||||
numberElement.innerHTML = slideNumber++;
|
numberElement.innerHTML = slideNumber;
|
||||||
page.appendChild( numberElement );
|
page.appendChild( numberElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +150,7 @@ export default class PrintView {
|
|||||||
|
|
||||||
let previousFragmentStep;
|
let previousFragmentStep;
|
||||||
|
|
||||||
fragmentGroups.forEach( function( fragments, index ) {
|
fragmentGroups.forEach( function( fragments ) {
|
||||||
|
|
||||||
// Remove 'current-fragment' from the previous group
|
// Remove 'current-fragment' from the previous group
|
||||||
if( previousFragmentStep ) {
|
if( previousFragmentStep ) {
|
||||||
@@ -180,14 +166,6 @@ export default class PrintView {
|
|||||||
|
|
||||||
// Create a separate page for the current fragment state
|
// Create a separate page for the current fragment state
|
||||||
const clonedPage = page.cloneNode( true );
|
const clonedPage = page.cloneNode( true );
|
||||||
|
|
||||||
// Inject unique page numbers for fragments
|
|
||||||
if( injectPageNumbers ) {
|
|
||||||
const numberElement = clonedPage.querySelector( '.slide-number-pdf' );
|
|
||||||
const fragmentNumber = index + 1;
|
|
||||||
numberElement.innerHTML += '.' + fragmentNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
pages.push( clonedPage );
|
pages.push( clonedPage );
|
||||||
|
|
||||||
previousFragmentStep = fragments;
|
previousFragmentStep = fragments;
|
||||||
@@ -217,23 +195,18 @@ export default class PrintView {
|
|||||||
|
|
||||||
pages.forEach( page => pageContainer.appendChild( page ) );
|
pages.forEach( page => pageContainer.appendChild( page ) );
|
||||||
|
|
||||||
// Re-run JS-based content layout after the slide is added to page DOM
|
|
||||||
this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
|
|
||||||
|
|
||||||
// Notify subscribers that the PDF layout is good to go
|
// Notify subscribers that the PDF layout is good to go
|
||||||
this.Reveal.dispatchEvent({ type: 'pdf-ready' });
|
this.Reveal.dispatchEvent({ type: 'pdf-ready' });
|
||||||
|
|
||||||
viewportElement.classList.remove( 'loading-scroll-mode' );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the print mode is/should be activated.
|
* Checks if this instance is being used to print a PDF.
|
||||||
*/
|
*/
|
||||||
isActive() {
|
isPrintingPDF() {
|
||||||
|
|
||||||
return this.Reveal.getConfig().view === 'print';
|
return ( /print-pdf/gi ).test( window.location.search );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -101,10 +101,5 @@ export default class Progress {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.element.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,923 +0,0 @@
|
|||||||
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,5 @@
|
|||||||
import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'
|
import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'
|
||||||
|
import { extend, queryAll, closest } from '../utils/util.js'
|
||||||
import { isMobile } from '../utils/device.js'
|
import { isMobile } from '../utils/device.js'
|
||||||
|
|
||||||
import fitty from 'fitty';
|
import fitty from 'fitty';
|
||||||
@@ -9,15 +10,11 @@ import fitty from 'fitty';
|
|||||||
*/
|
*/
|
||||||
export default class SlideContent {
|
export default class SlideContent {
|
||||||
|
|
||||||
allowedToPlay = true;
|
|
||||||
|
|
||||||
constructor( Reveal ) {
|
constructor( Reveal ) {
|
||||||
|
|
||||||
this.Reveal = Reveal;
|
this.Reveal = Reveal;
|
||||||
|
|
||||||
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
|
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
|
||||||
this.preventIframeAutoFocus = this.preventIframeAutoFocus.bind( this );
|
|
||||||
this.ensureMobileMediaPlaying = this.ensureMobileMediaPlaying.bind( this );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,10 +26,6 @@ export default class SlideContent {
|
|||||||
*/
|
*/
|
||||||
shouldPreload( element ) {
|
shouldPreload( element ) {
|
||||||
|
|
||||||
if( this.Reveal.isScrollView() ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefer an explicit global preload setting
|
// Prefer an explicit global preload setting
|
||||||
let preload = this.Reveal.getConfig().preloadIframes;
|
let preload = this.Reveal.getConfig().preloadIframes;
|
||||||
|
|
||||||
@@ -55,25 +48,14 @@ export default class SlideContent {
|
|||||||
load( slide, options = {} ) {
|
load( slide, options = {} ) {
|
||||||
|
|
||||||
// Show the slide element
|
// Show the slide element
|
||||||
const displayValue = this.Reveal.getConfig().display;
|
slide.style.display = 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 and iframe elements with data-src attributes
|
// Media elements with data-src attributes
|
||||||
queryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {
|
queryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {
|
||||||
const isIframe = element.tagName === 'IFRAME';
|
if( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {
|
||||||
if( !isIframe || this.shouldPreload( element ) ) {
|
|
||||||
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
||||||
element.setAttribute( 'data-lazy-loaded', '' );
|
element.setAttribute( 'data-lazy-loaded', '' );
|
||||||
element.removeAttribute( 'data-src' );
|
element.removeAttribute( 'data-src' );
|
||||||
|
|
||||||
if( isIframe ) {
|
|
||||||
element.addEventListener( 'load', this.preventIframeAutoFocus );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -120,28 +102,19 @@ export default class SlideContent {
|
|||||||
|
|
||||||
// Images
|
// Images
|
||||||
if( backgroundImage ) {
|
if( backgroundImage ) {
|
||||||
// base64
|
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
|
||||||
if( /^data:/.test( backgroundImage.trim() ) ) {
|
return `url(${encodeURI(background.trim())})`;
|
||||||
backgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;
|
}).join( ',' );
|
||||||
}
|
|
||||||
// URL(s)
|
|
||||||
else {
|
|
||||||
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
|
|
||||||
// Decode URL(s) that are already encoded first
|
|
||||||
let decoded = decodeURI(background.trim());
|
|
||||||
return `url(${encodeRFC3986URI(decoded)})`;
|
|
||||||
}).join( ',' );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Videos
|
// Videos
|
||||||
else if ( backgroundVideo ) {
|
else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
|
||||||
let video = document.createElement( 'video' );
|
let video = document.createElement( 'video' );
|
||||||
|
|
||||||
if( backgroundVideoLoop ) {
|
if( backgroundVideoLoop ) {
|
||||||
video.setAttribute( 'loop', '' );
|
video.setAttribute( 'loop', '' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( backgroundVideoMuted || this.Reveal.isSpeakerNotes() ) {
|
if( backgroundVideoMuted ) {
|
||||||
video.muted = true;
|
video.muted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,15 +130,7 @@ export default class SlideContent {
|
|||||||
|
|
||||||
// Support comma separated lists of video sources
|
// Support comma separated lists of video sources
|
||||||
backgroundVideo.split( ',' ).forEach( source => {
|
backgroundVideo.split( ',' ).forEach( source => {
|
||||||
const sourceElement = document.createElement( 'source' );
|
video.innerHTML += '<source src="'+ source +'">';
|
||||||
sourceElement.setAttribute( 'src', source );
|
|
||||||
|
|
||||||
let type = getMimeTypeFromFile( source );
|
|
||||||
if( type ) {
|
|
||||||
sourceElement.setAttribute( 'type', type );
|
|
||||||
}
|
|
||||||
|
|
||||||
video.appendChild( sourceElement );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
backgroundContent.appendChild( video );
|
backgroundContent.appendChild( video );
|
||||||
@@ -209,14 +174,15 @@ export default class SlideContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies JS-dependent layout helpers for the scope.
|
* Applies JS-dependent layout helpers for the given slide,
|
||||||
|
* if there are any.
|
||||||
*/
|
*/
|
||||||
layout( scopeElement ) {
|
layout( slide ) {
|
||||||
|
|
||||||
// Autosize text with the r-fit-text class based on the
|
// Autosize text with the r-fit-text class based on the
|
||||||
// size of its container. This needs to happen after the
|
// size of its container. This needs to happen after the
|
||||||
// slide is visible in order to measure the text.
|
// slide is visible in order to measure the text.
|
||||||
Array.from( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
|
Array.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
|
||||||
fitty( element, {
|
fitty( element, {
|
||||||
minSize: 24,
|
minSize: 24,
|
||||||
maxSize: this.Reveal.getConfig().height * 0.8,
|
maxSize: this.Reveal.getConfig().height * 0.8,
|
||||||
@@ -295,9 +261,7 @@ export default class SlideContent {
|
|||||||
*/
|
*/
|
||||||
startEmbeddedContent( element ) {
|
startEmbeddedContent( element ) {
|
||||||
|
|
||||||
if( element ) {
|
if( element && !this.Reveal.isSpeakerNotes() ) {
|
||||||
|
|
||||||
const isSpeakerNotesWindow = this.Reveal.isSpeakerNotes();
|
|
||||||
|
|
||||||
// Restart GIFs
|
// Restart GIFs
|
||||||
queryAll( element, 'img[src$=".gif"]' ).forEach( el => {
|
queryAll( element, 'img[src$=".gif"]' ).forEach( el => {
|
||||||
@@ -323,9 +287,6 @@ export default class SlideContent {
|
|||||||
|
|
||||||
if( autoplay && typeof el.play === 'function' ) {
|
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 the media is ready, start playback
|
||||||
if( el.readyState > 1 ) {
|
if( el.readyState > 1 ) {
|
||||||
this.startEmbeddedMedia( { target: el } );
|
this.startEmbeddedMedia( { target: el } );
|
||||||
@@ -335,16 +296,10 @@ export default class SlideContent {
|
|||||||
else if( isMobile ) {
|
else if( isMobile ) {
|
||||||
let promise = el.play();
|
let promise = el.play();
|
||||||
|
|
||||||
el.addEventListener( 'canplay', this.ensureMobileMediaPlaying );
|
|
||||||
|
|
||||||
// If autoplay does not work, ensure that the controls are visible so
|
// If autoplay does not work, ensure that the controls are visible so
|
||||||
// that the viewer can start the media on their own
|
// that the viewer can start the media on their own
|
||||||
if( promise && typeof promise.catch === 'function' && el.controls === false ) {
|
if( promise && typeof promise.catch === 'function' && el.controls === false ) {
|
||||||
promise
|
promise.catch( () => {
|
||||||
.then( () => {
|
|
||||||
this.allowedToPlay = true;
|
|
||||||
})
|
|
||||||
.catch( () => {
|
|
||||||
el.controls = true;
|
el.controls = true;
|
||||||
|
|
||||||
// Once the video does start playing, hide the controls again
|
// Once the video does start playing, hide the controls again
|
||||||
@@ -363,72 +318,32 @@ export default class SlideContent {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Don't play iframe content in the speaker view since we can't
|
// Normal iframes
|
||||||
// guarantee that it's muted
|
queryAll( element, 'iframe[src]' ).forEach( el => {
|
||||||
if( !isSpeakerNotesWindow ) {
|
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Normal iframes
|
this.startEmbeddedIframe( { target: el } );
|
||||||
queryAll( element, 'iframe[src]' ).forEach( el => {
|
} );
|
||||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.startEmbeddedIframe( { target: el } );
|
// Lazy loading iframes
|
||||||
} );
|
queryAll( element, 'iframe[data-src]' ).forEach( el => {
|
||||||
|
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Lazy loading iframes
|
if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
|
||||||
queryAll( element, 'iframe[data-src]' ).forEach( el => {
|
el.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes
|
||||||
if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
|
el.addEventListener( 'load', this.startEmbeddedIframe );
|
||||||
return;
|
el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
|
||||||
}
|
}
|
||||||
|
} );
|
||||||
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
|
* Starts playing an embedded video/audio element after
|
||||||
* it has finished loading.
|
* it has finished loading.
|
||||||
@@ -441,23 +356,8 @@ export default class SlideContent {
|
|||||||
isVisible = !!closest( event.target, '.present' );
|
isVisible = !!closest( event.target, '.present' );
|
||||||
|
|
||||||
if( isAttachedToDOM && isVisible ) {
|
if( isAttachedToDOM && isVisible ) {
|
||||||
// Don't restart if media is already playing
|
event.target.currentTime = 0;
|
||||||
if( event.target.paused || event.target.ended ) {
|
event.target.play();
|
||||||
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 );
|
event.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );
|
||||||
@@ -474,8 +374,6 @@ export default class SlideContent {
|
|||||||
|
|
||||||
let iframe = event.target;
|
let iframe = event.target;
|
||||||
|
|
||||||
this.preventIframeAutoFocus( event );
|
|
||||||
|
|
||||||
if( iframe && iframe.contentWindow ) {
|
if( iframe && iframe.contentWindow ) {
|
||||||
|
|
||||||
let isAttachedToDOM = !!closest( event.target, 'html' ),
|
let isAttachedToDOM = !!closest( event.target, 'html' ),
|
||||||
@@ -530,17 +428,12 @@ export default class SlideContent {
|
|||||||
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
|
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
|
||||||
el.setAttribute('data-paused-by-reveal', '');
|
el.setAttribute('data-paused-by-reveal', '');
|
||||||
el.pause();
|
el.pause();
|
||||||
|
|
||||||
if( isMobile ) {
|
|
||||||
el.removeEventListener( 'canplay', this.ensureMobileMediaPlaying );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Generic postMessage API for non-lazy loaded iframes
|
// Generic postMessage API for non-lazy loaded iframes
|
||||||
queryAll( element, 'iframe' ).forEach( el => {
|
queryAll( element, 'iframe' ).forEach( el => {
|
||||||
if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );
|
if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );
|
||||||
el.removeEventListener( 'load', this.preventIframeAutoFocus );
|
|
||||||
el.removeEventListener( 'load', this.startEmbeddedIframe );
|
el.removeEventListener( 'load', this.startEmbeddedIframe );
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -571,46 +464,4 @@ 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,10 +1,3 @@
|
|||||||
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.
|
* Handles the display of reveal.js' optional slide number.
|
||||||
*/
|
*/
|
||||||
@@ -30,7 +23,7 @@ export default class SlideNumber {
|
|||||||
configure( config, oldConfig ) {
|
configure( config, oldConfig ) {
|
||||||
|
|
||||||
let slideNumberDisplay = 'none';
|
let slideNumberDisplay = 'none';
|
||||||
if( config.slideNumber && !this.Reveal.isPrintView() ) {
|
if( config.slideNumber && !this.Reveal.isPrintingPDF() ) {
|
||||||
if( config.showSlideNumber === 'all' ) {
|
if( config.showSlideNumber === 'all' ) {
|
||||||
slideNumberDisplay = 'block';
|
slideNumberDisplay = 'block';
|
||||||
}
|
}
|
||||||
@@ -63,7 +56,7 @@ export default class SlideNumber {
|
|||||||
|
|
||||||
let config = this.Reveal.getConfig();
|
let config = this.Reveal.getConfig();
|
||||||
let value;
|
let value;
|
||||||
let format = SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL;
|
let format = 'h.v';
|
||||||
|
|
||||||
if ( typeof config.slideNumber === 'function' ) {
|
if ( typeof config.slideNumber === 'function' ) {
|
||||||
value = config.slideNumber( slide );
|
value = config.slideNumber( slide );
|
||||||
@@ -76,7 +69,7 @@ export default class SlideNumber {
|
|||||||
// If there are ONLY vertical slides in this deck, always use
|
// If there are ONLY vertical slides in this deck, always use
|
||||||
// a flattened slide number
|
// a flattened slide number
|
||||||
if( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {
|
if( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {
|
||||||
format = SLIDE_NUMBER_FORMAT_CURRENT;
|
format = 'c';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset the current slide number by 1 to make it 1-indexed
|
// Offset the current slide number by 1 to make it 1-indexed
|
||||||
@@ -84,16 +77,16 @@ export default class SlideNumber {
|
|||||||
|
|
||||||
value = [];
|
value = [];
|
||||||
switch( format ) {
|
switch( format ) {
|
||||||
case SLIDE_NUMBER_FORMAT_CURRENT:
|
case 'c':
|
||||||
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );
|
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );
|
||||||
break;
|
break;
|
||||||
case SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL:
|
case 'c/t':
|
||||||
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );
|
value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
let indices = this.Reveal.getIndices( slide );
|
let indices = this.Reveal.getIndices( slide );
|
||||||
value.push( indices.h + horizontalOffset );
|
value.push( indices.h + horizontalOffset );
|
||||||
let sep = format === SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL ? '/' : '.';
|
let sep = format === 'h/v' ? '/' : '.';
|
||||||
if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );
|
if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,10 +123,4 @@ export default class SlideNumber {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
|
|
||||||
this.element.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ export default class Touch {
|
|||||||
isSwipePrevented( target ) {
|
isSwipePrevented( target ) {
|
||||||
|
|
||||||
// Prevent accidental swipes when scrubbing timelines
|
// Prevent accidental swipes when scrubbing timelines
|
||||||
if( matches( target, 'video[controls], audio[controls]' ) ) return true;
|
if( matches( target, 'video, audio' ) ) return true;
|
||||||
|
|
||||||
while( target && typeof target.hasAttribute === 'function' ) {
|
while( target && typeof target.hasAttribute === 'function' ) {
|
||||||
if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
|
if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
|
||||||
@@ -103,8 +103,6 @@ export default class Touch {
|
|||||||
*/
|
*/
|
||||||
onTouchStart( event ) {
|
onTouchStart( event ) {
|
||||||
|
|
||||||
this.touchCaptured = false;
|
|
||||||
|
|
||||||
if( this.isSwipePrevented( event.target ) ) return true;
|
if( this.isSwipePrevented( event.target ) ) return true;
|
||||||
|
|
||||||
this.touchStartX = event.touches[0].clientX;
|
this.touchStartX = event.touches[0].clientX;
|
||||||
@@ -216,14 +214,6 @@ export default class Touch {
|
|||||||
*/
|
*/
|
||||||
onTouchEnd( event ) {
|
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;
|
this.touchCaptured = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
982
js/reveal.js
982
js/reveal.js
File diff suppressed because it is too large
Load Diff
@@ -29,9 +29,9 @@ export const colorToRgb = ( color ) => {
|
|||||||
if( hex6 && hex6[1] ) {
|
if( hex6 && hex6[1] ) {
|
||||||
hex6 = hex6[1];
|
hex6 = hex6[1];
|
||||||
return {
|
return {
|
||||||
r: parseInt( hex6.slice( 0, 2 ), 16 ),
|
r: parseInt( hex6.substr( 0, 2 ), 16 ),
|
||||||
g: parseInt( hex6.slice( 2, 4 ), 16 ),
|
g: parseInt( hex6.substr( 2, 2 ), 16 ),
|
||||||
b: parseInt( hex6.slice( 4, 6 ), 16 )
|
b: parseInt( hex6.substr( 4, 2 ), 16 )
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 ) {
|
if( rgba ) {
|
||||||
return {
|
return {
|
||||||
r: parseInt( rgba[1], 10 ),
|
r: parseInt( rgba[1], 10 ),
|
||||||
|
|||||||
@@ -2,16 +2,9 @@
|
|||||||
export const SLIDES_SELECTOR = '.slides section';
|
export const SLIDES_SELECTOR = '.slides section';
|
||||||
export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
|
export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
|
||||||
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
|
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
|
||||||
export const HORIZONTAL_BACKGROUNDS_SELECTOR = '.backgrounds>.slide-background';
|
|
||||||
|
|
||||||
// Methods that may not be invoked via the postMessage API
|
// Methods that may not be invoked via the postMessage API
|
||||||
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/;
|
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
|
||||||
|
|
||||||
// Regex for retrieving the fragment style from a class attribute
|
// Regex for retrieving the fragment style from a class attribute
|
||||||
export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
|
export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
|
||||||
|
|
||||||
// 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';
|
|
||||||
@@ -1,8 +1,15 @@
|
|||||||
const UA = navigator.userAgent;
|
const UA = navigator.userAgent;
|
||||||
|
const testElement = document.createElement( 'div' );
|
||||||
|
|
||||||
export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
|
export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
|
||||||
( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
|
( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
|
||||||
|
|
||||||
export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
|
export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
|
||||||
|
|
||||||
export const isAndroid = /android/gi.test( UA );
|
export const isAndroid = /android/gi.test( UA );
|
||||||
|
|
||||||
|
// Flags if we should use zoom instead of transform to scale
|
||||||
|
// up slides. Zoom produces crisper results but has a lot of
|
||||||
|
// xbrowser quirks so we only use it in whitelisted browsers.
|
||||||
|
export const supportsZoom = 'zoom' in testElement.style && !isMobile &&
|
||||||
|
( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) );
|
||||||
@@ -279,35 +279,4 @@ export const getRemainingHeight = ( element, height = 0 ) => {
|
|||||||
|
|
||||||
return height;
|
return height;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileExtensionToMimeMap = {
|
|
||||||
'mp4': 'video/mp4',
|
|
||||||
'm4a': 'video/mp4',
|
|
||||||
'ogv': 'video/ogg',
|
|
||||||
'mpeg': 'video/mpeg',
|
|
||||||
'webm': 'video/webm'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Guess the MIME type for common file formats.
|
|
||||||
*/
|
|
||||||
export const getMimeTypeFromFile = ( filename='' ) => {
|
|
||||||
return fileExtensionToMimeMap[filename.split('.').pop()]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
17678
package-lock.json
generated
17678
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
62
package.json
62
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "reveal.js",
|
"name": "reveal.js",
|
||||||
"version": "5.2.1",
|
"version": "4.1.3",
|
||||||
"description": "The HTML Presentation Framework",
|
"description": "The HTML Presentation Framework",
|
||||||
"homepage": "https://revealjs.com",
|
"homepage": "https://revealjs.com",
|
||||||
"subdomain": "revealjs",
|
"subdomain": "revealjs",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"url": "git://github.com/hakimel/reveal.js.git"
|
"url": "git://github.com/hakimel/reveal.js.git"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"reveal",
|
"reveal",
|
||||||
@@ -30,43 +30,35 @@
|
|||||||
"presentation"
|
"presentation"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.23.2",
|
"@babel/core": "^7.14.3",
|
||||||
"@babel/eslint-parser": "^7.22.15",
|
"@babel/eslint-parser": "^7.14.3",
|
||||||
"@babel/preset-env": "^7.23.2",
|
"@babel/preset-env": "^7.14.2",
|
||||||
"@rollup/plugin-babel": "^6.0.4",
|
"@rollup/plugin-babel": "^5.3.0",
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
"@rollup/plugin-commonjs": "^19.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||||
"@rollup/plugin-terser": "^0.4.4",
|
"babel-plugin-transform-html-import-to-string": "0.0.1",
|
||||||
"babel-plugin-transform-html-import-to-string": "2.0.0",
|
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"core-js": "^3.33.1",
|
"core-js": "^3.12.1",
|
||||||
"fitty": "^2.3.7",
|
"fitty": "^2.3.0",
|
||||||
"glob": "^10.3.10",
|
"glob": "^7.1.7",
|
||||||
"gulp": "^5.0.0",
|
"gulp": "^4.0.2",
|
||||||
"gulp-autoprefixer": "^8.0.0",
|
"gulp-autoprefixer": "^5.0.0",
|
||||||
"gulp-clean-css": "^4.3.0",
|
"gulp-clean-css": "^4.2.0",
|
||||||
"gulp-connect": "^5.7.0",
|
"gulp-connect": "^5.7.0",
|
||||||
"gulp-eslint": "^6.0.0",
|
"gulp-eslint": "^6.0.0",
|
||||||
"gulp-header-comment": "^0.10.0",
|
"gulp-header": "^2.0.9",
|
||||||
"gulp-zip": "^5.1.0",
|
"gulp-tap": "^2.0.0",
|
||||||
"highlight.js": "^11.9.0",
|
"gulp-zip": "^4.2.0",
|
||||||
"marked": "^4.3.0",
|
"highlight.js": "^10.0.3",
|
||||||
"node-qunit-puppeteer": "^2.2.0",
|
"marked": "^2.0.3",
|
||||||
"through2": "^4.0.2",
|
"node-qunit-puppeteer": "^2.0.1",
|
||||||
"qunit": "^2.22.0",
|
"qunit": "^2.10.0",
|
||||||
"rollup": "^4.1.5",
|
"rollup": "^2.48.0",
|
||||||
"sass": "^1.79.4",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"yargs": "^17.7.2"
|
"sass": "^1.32.13",
|
||||||
|
"yargs": "^15.1.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"browserslist": "> 0.5%, IE 11, not dead",
|
||||||
"gulp-connect": {
|
|
||||||
"send": "0.19.0"
|
|
||||||
},
|
|
||||||
"gulp-header-comment": {
|
|
||||||
"moment": "2.30.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"browserslist": "> 2%, not dead",
|
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
|||||||
import hljs from 'highlight.js';
|
import hljs from 'highlight.js'
|
||||||
|
|
||||||
/* highlightjs-line-numbers.js 2.8.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
|
||||||
!function(r,o){"use strict";var e,i="hljs-ln",l="hljs-ln-line",h="hljs-ln-code",s="hljs-ln-numbers",c="hljs-ln-n",m="data-line-number",a=/\r\n|\r|\n/g;function u(e){for(var n=e.toString(),t=e.anchorNode;"TD"!==t.nodeName;)t=t.parentNode;for(var r=e.focusNode;"TD"!==r.nodeName;)r=r.parentNode;var o=parseInt(t.dataset.lineNumber),a=parseInt(r.dataset.lineNumber);if(o==a)return n;var i,l=t.textContent,s=r.textContent;for(a<o&&(i=o,o=a,a=i,i=l,l=s,s=i);0!==n.indexOf(l);)l=l.slice(1);for(;-1===n.lastIndexOf(s);)s=s.slice(0,-1);for(var c=l,u=function(e){for(var n=e;"TABLE"!==n.nodeName;)n=n.parentNode;return n}(t),d=o+1;d<a;++d){var f=p('.{0}[{1}="{2}"]',[h,m,d]);c+="\n"+u.querySelector(f).textContent}return c+="\n"+s}function n(e){try{var n=o.querySelectorAll("code.hljs,code.nohighlight");for(var t in n)n.hasOwnProperty(t)&&(n[t].classList.contains("nohljsln")||d(n[t],e))}catch(e){r.console.error("LineNumbers error: ",e)}}function d(e,n){if("object"==typeof e)e.innerHTML=f(e,n)}function f(e,n){var t,r,o=(t=e,{singleLine:function(e){return!!e.singleLine&&e.singleLine}(r=(r=n)||{}),startFrom:function(e,n){var t=1;isFinite(n.startFrom)&&(t=n.startFrom);var r=function(e,n){return e.hasAttribute(n)?e.getAttribute(n):null}(e,"data-ln-start-from");return null!==r&&(t=function(e,n){if(!e)return n;var t=Number(e);return isFinite(t)?t:n}(r,1)),t}(t,r)});return function e(n){var t=n.childNodes;for(var r in t){var o;t.hasOwnProperty(r)&&(o=t[r],0<(o.textContent.trim().match(a)||[]).length&&(0<o.childNodes.length?e(o):v(o.parentNode)))}}(e),function(e,n){var t=g(e);""===t[t.length-1].trim()&&t.pop();if(1<t.length||n.singleLine){for(var r="",o=0,a=t.length;o<a;o++)r+=p('<tr><td class="{0} {1}" {3}="{5}"><div class="{2}" {3}="{5}"></div></td><td class="{0} {4}" {3}="{5}">{6}</td></tr>',[l,s,c,m,h,o+n.startFrom,0<t[o].length?t[o]:" "]);return p('<table class="{0}">{1}</table>',[i,r])}return e}(e.innerHTML,o)}function v(e){var n=e.className;if(/hljs-/.test(n)){for(var t=g(e.innerHTML),r=0,o="";r<t.length;r++){o+=p('<span class="{0}">{1}</span>\n',[n,0<t[r].length?t[r]:" "])}e.innerHTML=o.trim()}}function g(e){return 0===e.length?[]:e.split(a)}function p(e,t){return e.replace(/\{(\d+)\}/g,function(e,n){return void 0!==t[n]?t[n]:e})}hljs?(hljs.initLineNumbersOnLoad=function(e){"interactive"===o.readyState||"complete"===o.readyState?n(e):r.addEventListener("DOMContentLoaded",function(){n(e)})},hljs.lineNumbersBlock=d,hljs.lineNumbersValue=function(e,n){if("string"!=typeof e)return;var t=document.createElement("code");return t.innerHTML=e,f(t,n)},(e=o.createElement("style")).type="text/css",e.innerHTML=p(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[i,c,m]),o.getElementsByTagName("head")[0].appendChild(e)):r.console.error("highlight.js not detected!"),document.addEventListener("copy",function(e){var n,t=window.getSelection();!function(e){for(var n=e;n;){if(n.className&&-1!==n.className.indexOf("hljs-ln-code"))return 1;n=n.parentNode}}(t.anchorNode)||(n=-1!==window.navigator.userAgent.indexOf("Edge")?u(t):t.toString(),e.clipboardData.setData("text/plain",n),e.preventDefault())})}(window,document);
|
|
||||||
|
|
||||||
|
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
||||||
|
/* Edited by Hakim for reveal.js; removed async timeout */
|
||||||
|
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=g(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[v,L,b]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"interactive"===e.readyState||"complete"===e.readyState?i(t):n.addEventListener("DOMContentLoaded",function(){i(t)})}function i(t){try{var r=e.querySelectorAll("code.hljs,code.nohighlight");for(var i in r)r.hasOwnProperty(i)&&l(r[i],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function l(n,e){"object"==typeof n&&f(function(){n.innerHTML=s(n,e)})}function o(n,e){if("string"==typeof n){var t=document.createElement("code");return t.innerHTML=n,s(t,e)}}function s(n,e){e=e||{singleLine:!1};var t=e.singleLine?0:1;return c(n),a(n.innerHTML,t)}function a(n,e){var t=u(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",i=0,l=t.length;i<l;i++)r+=g('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[j,m,L,b,p,i+1,t[i].length>0?t[i]:" "]);return g('<table class="{0}">{1}</table>',[v,r])}return n}function c(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];h(r.textContent)>0&&(r.childNodes.length>0?c(r):d(r.parentNode))}}function d(n){var e=n.className;if(/hljs-/.test(e)){for(var t=u(n.innerHTML),r=0,i="";r<t.length;r++){var l=t[r].length>0?t[r]:" ";i+=g('<span class="{0}">{1}</span>\n',[e,l])}n.innerHTML=i.trim()}}function u(n){return 0===n.length?[]:n.split(y)}function h(n){return(n.trim().match(y)||[]).length}function f(e){e()}function g(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var v="hljs-ln",m="hljs-ln-line",p="hljs-ln-code",j="hljs-ln-numbers",L="hljs-ln-n",b="data-line-number",y=/\r\n|\r|\n/g;hljs?(hljs.initLineNumbersOnLoad=r,hljs.lineNumbersBlock=l,hljs.lineNumbersValue=o,t()):n.console.error("highlight.js not detected!")}(window,document);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* reveal.js plugin that adds syntax highlight support.
|
* reveal.js plugin that adds syntax highlight support.
|
||||||
@@ -16,10 +16,10 @@ const Plugin = {
|
|||||||
HIGHLIGHT_LINE_DELIMITER: ',',
|
HIGHLIGHT_LINE_DELIMITER: ',',
|
||||||
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
||||||
|
|
||||||
hljs,
|
hljs: hljs,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Highlights code blocks within the given deck.
|
* Highlights code blocks withing the given deck.
|
||||||
*
|
*
|
||||||
* Note that this can be called multiple times if
|
* Note that this can be called multiple times if
|
||||||
* there are multiple presentations on one page.
|
* there are multiple presentations on one page.
|
||||||
@@ -30,7 +30,6 @@ const Plugin = {
|
|||||||
|
|
||||||
// Read the plugin config options and provide fallbacks
|
// Read the plugin config options and provide fallbacks
|
||||||
let config = reveal.getConfig().highlight || {};
|
let config = reveal.getConfig().highlight || {};
|
||||||
|
|
||||||
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
||||||
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
||||||
|
|
||||||
@@ -52,7 +51,7 @@ const Plugin = {
|
|||||||
block.innerHTML = betterTrim( block );
|
block.innerHTML = betterTrim( block );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Escape HTML tags unless the "data-noescape" attribute is present
|
// Escape HTML tags unless the "data-noescape" attrbute is present
|
||||||
if( config.escapeHTML && !block.hasAttribute( 'data-noescape' )) {
|
if( config.escapeHTML && !block.hasAttribute( 'data-noescape' )) {
|
||||||
block.innerHTML = block.innerHTML.replace( /</g,"<").replace(/>/g, '>' );
|
block.innerHTML = block.innerHTML.replace( /</g,"<").replace(/>/g, '>' );
|
||||||
}
|
}
|
||||||
@@ -62,19 +61,11 @@ const Plugin = {
|
|||||||
hljs.highlightElement( event.currentTarget );
|
hljs.highlightElement( event.currentTarget );
|
||||||
}, false );
|
}, false );
|
||||||
|
|
||||||
} );
|
if( config.highlightOnLoad ) {
|
||||||
|
|
||||||
// Triggers a callback function before we trigger highlighting
|
|
||||||
if( typeof config.beforeHighlight === 'function' ) {
|
|
||||||
config.beforeHighlight( hljs );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run initial highlighting for all code
|
|
||||||
if( config.highlightOnLoad ) {
|
|
||||||
Array.from( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( block => {
|
|
||||||
Plugin.highlightBlock( block );
|
Plugin.highlightBlock( block );
|
||||||
} );
|
}
|
||||||
}
|
|
||||||
|
} );
|
||||||
|
|
||||||
// If we're printing to PDF, scroll the code highlights of
|
// If we're printing to PDF, scroll the code highlights of
|
||||||
// all blocks in the deck into view at once
|
// all blocks in the deck into view at once
|
||||||
@@ -106,7 +97,7 @@ const Plugin = {
|
|||||||
|
|
||||||
var scrollState = { currentBlock: block };
|
var scrollState = { currentBlock: block };
|
||||||
|
|
||||||
// If there is more than one highlight step, generate
|
// If there is at least one highlight step, generate
|
||||||
// fragments
|
// fragments
|
||||||
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
||||||
if( highlightSteps.length > 1 ) {
|
if( highlightSteps.length > 1 ) {
|
||||||
@@ -138,11 +129,11 @@ const Plugin = {
|
|||||||
|
|
||||||
// Scroll highlights into view as we step through them
|
// Scroll highlights into view as we step through them
|
||||||
fragmentBlock.addEventListener( 'visible', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock, scrollState ) );
|
fragmentBlock.addEventListener( 'visible', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock, scrollState ) );
|
||||||
fragmentBlock.addEventListener( 'hidden', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousElementSibling, scrollState ) );
|
fragmentBlock.addEventListener( 'hidden', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousSibling, scrollState ) );
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
block.removeAttribute( 'data-fragment-index' );
|
block.removeAttribute( 'data-fragment-index' )
|
||||||
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user