7 Commits

Author SHA1 Message Date
4f622abc34 rename leetcode-20230109.md 2023-01-10 01:34:02 +08:00
ad0267d685 fix 20230109 2023-01-10 01:29:33 +08:00
cdc0582e1d Merge branch 'leetcode-20230106' into leetcode-20230109 2023-01-10 01:26:45 +08:00
b94ff8de58 leetcode-20230106.md 2023-01-10 01:23:49 +08:00
49120378d4 增加注释和c++sort,删去最后一页 2023-01-07 22:12:27 +08:00
39604791e9 fix typo 2023-01-06 21:08:24 +08:00
5612aafda7 leetcode 20230109 2023-01-06 18:35:16 +08:00
94 changed files with 11717 additions and 8393 deletions

View File

@@ -1,31 +1,24 @@
name: tests name: tests
on: on: [push]
- push
permissions:
contents: read
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: node-version: [10.x, 14.x, 16.x]
- 18
- 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
- name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1
uses: actions/setup-node@v4 with:
with: node-version: ${{ matrix.node-version }}
node-version: ${{ matrix.node-version }} - run: npm install
- run: npm run build --if-present
- run: npm install - run: npm test
- run: npm run build --if-present env:
- run: npm test CI: true
env:
CI: true

View File

@@ -1,5 +1,7 @@
/test /test
/examples /examples
.github .github
.gulpfile
.sass-cache .sass-cache
gulpfile.js gulpfile.js
CONTRIBUTING.md

View File

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

View File

@@ -46,5 +46,5 @@ Hakim's open source work is supported by <a href="https://github.com/sponsors/ha
--- ---
<div align="center"> <div align="center">
MIT licensed | Copyright © 2011-2023 Hakim El Hattab, https://hakim.se MIT licensed | Copyright © 2011-2022 Hakim El Hattab, https://hakim.se
</div> </div>

View File

@@ -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,24 @@
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;
} }
.r-fit-text { .reveal .r-fit-text {
white-space: normal !important; white-space: normal !important;
} }
section img { .reveal 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 +154,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 +166,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;
} }

View File

@@ -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;
@@ -149,7 +146,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 */

View File

@@ -19,7 +19,6 @@ html.reveal-full-page {
height: 100%; height: 100%;
height: 100vh; height: 100vh;
height: calc( var(--vh, 1vh) * 100 ); height: calc( var(--vh, 1vh) * 100 );
height: 100svh;
overflow: hidden; overflow: hidden;
} }
@@ -32,8 +31,6 @@ html.reveal-full-page {
background-color: #fff; background-color: #fff;
color: #000; color: #000;
--r-controls-spacing: 12px;
} }
// Force the presentation to cover the full viewport when we // Force the presentation to cover the full viewport when we
@@ -51,14 +48,11 @@ html.reveal-full-page {
* VIEW FRAGMENTS * VIEW FRAGMENTS
*********************************************/ *********************************************/
.reveal .fragment { .reveal .slides section .fragment {
opacity: 0;
visibility: hidden;
transition: all .2s ease; transition: all .2s ease;
will-change: opacity;
&:not(.custom) {
opacity: 0;
visibility: hidden;
will-change: opacity;
}
&.visible { &.visible {
opacity: 1; opacity: 1;
@@ -70,7 +64,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.grow { .reveal .slides section .fragment.grow {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
@@ -79,7 +73,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.shrink { .reveal .slides section .fragment.shrink {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
@@ -88,7 +82,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.zoom-in { .reveal .slides section .fragment.zoom-in {
transform: scale( 0.1 ); transform: scale( 0.1 );
&.visible { &.visible {
@@ -96,7 +90,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-out { .reveal .slides section .fragment.fade-out {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
@@ -106,7 +100,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.semi-fade-out { .reveal .slides section .fragment.semi-fade-out {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
@@ -116,7 +110,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.strike { .reveal .slides section .fragment.strike {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
@@ -125,7 +119,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-up { .reveal .slides section .fragment.fade-up {
transform: translate(0, 40px); transform: translate(0, 40px);
&.visible { &.visible {
@@ -133,7 +127,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-down { .reveal .slides section .fragment.fade-down {
transform: translate(0, -40px); transform: translate(0, -40px);
&.visible { &.visible {
@@ -141,7 +135,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-right { .reveal .slides section .fragment.fade-right {
transform: translate(-40px, 0); transform: translate(-40px, 0);
&.visible { &.visible {
@@ -149,7 +143,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-left { .reveal .slides section .fragment.fade-left {
transform: translate(40px, 0); transform: translate(40px, 0);
&.visible { &.visible {
@@ -157,8 +151,8 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-in-then-out, .reveal .slides section .fragment.fade-in-then-out,
.reveal .fragment.current-visible { .reveal .slides section .fragment.current-visible {
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
@@ -168,7 +162,7 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.fade-in-then-semi-out { .reveal .slides section .fragment.fade-in-then-semi-out {
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
@@ -183,32 +177,32 @@ html.reveal-full-page {
} }
} }
.reveal .fragment.highlight-red, .reveal .slides section .fragment.highlight-red,
.reveal .fragment.highlight-current-red, .reveal .slides section .fragment.highlight-current-red,
.reveal .fragment.highlight-green, .reveal .slides section .fragment.highlight-green,
.reveal .fragment.highlight-current-green, .reveal .slides section .fragment.highlight-current-green,
.reveal .fragment.highlight-blue, .reveal .slides section .fragment.highlight-blue,
.reveal .fragment.highlight-current-blue { .reveal .slides section .fragment.highlight-current-blue {
opacity: 1; opacity: 1;
visibility: inherit; visibility: inherit;
} }
.reveal .fragment.highlight-red.visible { .reveal .slides section .fragment.highlight-red.visible {
color: #ff2c2d color: #ff2c2d
} }
.reveal .fragment.highlight-green.visible { .reveal .slides section .fragment.highlight-green.visible {
color: #17ff2e; color: #17ff2e;
} }
.reveal .fragment.highlight-blue.visible { .reveal .slides section .fragment.highlight-blue.visible {
color: #1b91ff; color: #1b91ff;
} }
.reveal .fragment.highlight-current-red.current-fragment { .reveal .slides section .fragment.highlight-current-red.current-fragment {
color: #ff2c2d color: #ff2c2d
} }
.reveal .fragment.highlight-current-green.current-fragment { .reveal .slides section .fragment.highlight-current-green.current-fragment {
color: #17ff2e; color: #17ff2e;
} }
.reveal .fragment.highlight-current-blue.current-fragment { .reveal .slides section .fragment.highlight-current-blue.current-fragment {
color: #1b91ff; color: #1b91ff;
} }
@@ -274,11 +268,13 @@ $controlsArrowAngleActive: 36deg;
} }
.reveal .controls { .reveal .controls {
$spacing: 12px;
display: none; display: none;
position: absolute; position: absolute;
top: auto; top: auto;
bottom: var(--r-controls-spacing); bottom: $spacing;
right: var(--r-controls-spacing); right: $spacing;
left: auto; left: auto;
z-index: 11; z-index: 11;
color: #000; color: #000;
@@ -510,9 +506,7 @@ $controlsArrowAngleActive: 36deg;
// Edge aligned controls layout // Edge aligned controls layout
@media screen and (min-width: 500px) { @media screen and (min-width: 500px) {
.reveal-viewport { $spacing: 0.8em;
--r-controls-spacing: 0.8em;
}
.reveal .controls[data-controls-layout="edges"] { .reveal .controls[data-controls-layout="edges"] {
& { & {
@@ -532,24 +526,24 @@ $controlsArrowAngleActive: 36deg;
.navigate-left { .navigate-left {
top: 50%; top: 50%;
left: var(--r-controls-spacing); left: $spacing;
margin-top: -$controlArrowSize*0.5; margin-top: -$controlArrowSize*0.5;
} }
.navigate-right { .navigate-right {
top: 50%; top: 50%;
right: var(--r-controls-spacing); right: $spacing;
margin-top: -$controlArrowSize*0.5; margin-top: -$controlArrowSize*0.5;
} }
.navigate-up { .navigate-up {
top: var(--r-controls-spacing); top: $spacing;
left: 50%; left: 50%;
margin-left: -$controlArrowSize*0.5; margin-left: -$controlArrowSize*0.5;
} }
.navigate-down { .navigate-down {
bottom: calc(var(--r-controls-spacing) - #{$controlArrowSpacing} + 0.3em); bottom: $spacing - $controlArrowSpacing + 0.3em;
left: 50%; left: 50%;
margin-left: -$controlArrowSize*0.5; margin-left: -$controlArrowSize*0.5;
} }
@@ -1639,10 +1633,6 @@ $overlayHeaderPadding: 5px;
opacity: 0.4; opacity: 0.4;
} }
.reveal .hljs.has-highlights.fragment {
transition: all .2s ease;
}
.reveal .hljs:not(:first-child).fragment { .reveal .hljs:not(:first-child).fragment {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -1806,43 +1796,6 @@ $notesWidthPercent: 25%;
} }
/*********************************************
* JUMP-TO-SLIDE COMPONENT
*********************************************/
.reveal .jump-to-slide {
position: absolute;
top: 15px;
left: 15px;
z-index: 30;
font-size: 32px;
-webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
}
.reveal .jump-to-slide-input {
background: transparent;
padding: 8px;
font-size: inherit;
color: currentColor;
border: 0;
}
.reveal .jump-to-slide-input::placeholder {
color: currentColor;
opacity: 0.5;
}
.reveal.has-dark-background .jump-to-slide-input {
color: #fff;
}
.reveal.has-light-background .jump-to-slide-input {
color: #222;
}
.reveal .jump-to-slide-input:focus {
outline: none;
}
/********************************************* /*********************************************
* ZOOM PLUGIN * ZOOM PLUGIN
*********************************************/ *********************************************/
@@ -1867,234 +1820,6 @@ $notesWidthPercent: 25%;
} }
/*********************************************
* SCROLL VIEW
*********************************************/
.reveal-viewport.loading-scroll-mode {
visibility: hidden;
}
.reveal-viewport.reveal-scroll {
& {
margin: 0 auto;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
z-index: 1;
--r-scrollbar-width: 7px;
--r-scrollbar-trigger-size: 5px;
--r-controls-spacing: 8px;
}
@media screen and (max-width: 500px) {
--r-scrollbar-width: 3px;
--r-scrollbar-trigger-size: 3px;
}
.controls,
.progress,
.playback,
.backgrounds,
.slide-number,
.speaker-notes {
display: none !important;
}
.reveal {
overflow: visible;
touch-action: manipulation;
}
.slides {
position: static;
pointer-events: initial;
left: auto;
top: auto;
width: 100% !important;
margin: 0;
padding: 0;
overflow: visible;
display: block;
perspective: none;
perspective-origin: 50% 50%;
}
.scroll-page {
position: relative;
width: 100%;
height: calc(var(--page-height) + var(--page-scroll-padding));
z-index: 1;
overflow: visible;
}
.scroll-page-sticky {
position: sticky;
height: var(--page-height);
top: 0px;
}
.scroll-page-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.scroll-page section {
visibility: visible !important;
display: block !important;
position: absolute !important;
width: var(--slide-width) !important;
height: var(--slide-height) !important;
top: 50% !important;
left: 50% !important;
opacity: 1 !important;
transform: scale(var(--slide-scale)) translate(-50%, -50%) !important;
transform-style: flat !important;
transform-origin: 0 0 !important;
}
.slide-background {
display: block !important;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: auto !important;
visibility: visible;
opacity: 1;
touch-action: manipulation;
}
}
// Chromium
.reveal-viewport.reveal-scroll[data-scrollbar="true"]::-webkit-scrollbar,
.reveal-viewport.reveal-scroll[data-scrollbar="auto"]::-webkit-scrollbar {
display: none;
}
// Firefox
.reveal-viewport.reveal-scroll[data-scrollbar="true"],
.reveal-viewport.reveal-scroll[data-scrollbar="auto"] {
scrollbar-width: none;
}
.reveal.has-dark-background,
.reveal-viewport.has-dark-background {
--r-overlay-element-bg-color: 240, 240, 240;
--r-overlay-element-fg-color: 0, 0, 0;
}
.reveal.has-light-background,
.reveal-viewport.has-light-background {
--r-overlay-element-bg-color: 0, 0, 0;
--r-overlay-element-fg-color: 240, 240, 240;
}
.reveal-viewport.reveal-scroll .scrollbar {
position: sticky;
top: 50%;
z-index: 20;
opacity: 0;
transition: all 0.3s ease;
&.visible,
&:hover {
opacity: 1;
}
.scrollbar-inner {
position: absolute;
width: var(--r-scrollbar-width);
height: calc(var(--viewport-height) - var(--r-controls-spacing) * 2);
right: var(--r-controls-spacing);
top: 0;
transform: translateY(-50%);
border-radius: var(--r-scrollbar-width);
z-index: 10;
}
.scrollbar-playhead {
position: absolute;
width: var(--r-scrollbar-width);
height: var(--r-scrollbar-width);
top: 0;
left: 0;
border-radius: var(--r-scrollbar-width);
background-color: rgba(var(--r-overlay-element-bg-color), 1);
z-index: 11;
transition: background-color 0.2s ease;
}
.scrollbar-slide {
position: absolute;
width: 100%;
background-color: rgba(var(--r-overlay-element-bg-color), 0.2);
box-shadow: 0 0 0px 1px rgba(var(--r-overlay-element-fg-color), 0.1);
border-radius: var(--r-scrollbar-width);
transition: background-color 0.2s ease;
}
// Hit area
.scrollbar-slide:after {
content: '';
position: absolute;
width: 200%;
height: 100%;
top: 0;
left: -50%;
background: rgba( 0, 0, 0, 0 );
z-index: -1;
}
.scrollbar-slide:hover,
.scrollbar-slide.active {
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
}
.scrollbar-trigger {
position: absolute;
width: 100%;
transition: background-color 0.2s ease;
}
.scrollbar-slide.active.has-triggers {
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
z-index: 10;
}
.scrollbar-slide.active .scrollbar-trigger:after {
content: '';
position: absolute;
width: var(--r-scrollbar-trigger-size);
height: var(--r-scrollbar-trigger-size);
border-radius: 20px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(var(--r-overlay-element-bg-color), 1);
transition: transform 0.2s ease, opacity 0.2s ease;
opacity: 0.4;
}
.scrollbar-slide.active .scrollbar-trigger.active:after,
.scrollbar-slide.active .scrollbar-trigger.active ~ .scrollbar-trigger:after {
opacity: 1;
}
.scrollbar-slide.active .scrollbar-trigger ~ .scrollbar-trigger.active:after {
transform: translate(calc( var(--r-scrollbar-width) * -2), 0);
background-color: rgba(var(--r-overlay-element-bg-color), 1);
}
}
/********************************************* /*********************************************
* PRINT STYLES * PRINT STYLES
*********************************************/ *********************************************/

View File

@@ -27,9 +27,6 @@ $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) );

View File

@@ -1,49 +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 -----------------
@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: lighten( $linkColor, 15% );
$selectionBackgroundColor: lighten( $linkColor, 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";
// ---------------------------------------------

View File

@@ -30,7 +30,7 @@ $headingTextTransform: uppercase;
$headingFontWeight: 600; $headingFontWeight: 600;
$linkColor: #42affa; $linkColor: #42affa;
$linkColorHover: lighten( $linkColor, 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;

View File

@@ -86,21 +86,47 @@ $codeFont: "Fira Code", $systemFontsMono;
--r-list-bullet-color: #{$listBulletColor}; --r-list-bullet-color: #{$listBulletColor};
} }
.reveal { .reveal strong, .reveal b {
strong, b { color: var(--r-bold-color);
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);
}
}
} }
.reveal em, .reveal i, .reveal blockquote {
color: var(--r-italic-color);
}
.reveal code {
color: var(--r-inline-code-color);
}
// Dracula colored list bullets and numbers
.reveal ul {
list-style: none;
}
.reveal ul li::before {
content: "";
color: var(--r-list-bullet-color);
display: inline-block;
width: 1em;
margin-left: -1em
}
.reveal ol {
list-style: none;
counter-reset: li;
}
.reveal ol li::before {
content: counter(li) ".";
color: var(--r-list-bullet-color);
display: inline-block;
width: 2em;
margin-left: -2.5em;
margin-right: 0.5em;
text-align: right;
}
.reveal ol li {
counter-increment: li
}

View File

@@ -18,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;

View File

@@ -25,9 +25,6 @@ $linkColor: #51483D;
$linkColorHover: lighten( $linkColor, 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;
} }

View File

@@ -31,9 +31,6 @@ $linkColor: #00008B;
$linkColorHover: lighten( $linkColor, 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);

View File

@@ -29,9 +29,6 @@ $linkColor: #3b759e;
$linkColorHover: lighten( $linkColor, 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;

View File

@@ -51,9 +51,6 @@ $linkColor: $blue;
$linkColorHover: lighten( $linkColor, 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) );

View File

@@ -1,52 +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 -----------------
@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: lighten( $linkColor, 15% );
$selectionBackgroundColor: lighten( $linkColor, 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";
// ---------------------------------------------

View File

@@ -37,9 +37,6 @@ $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);

View File

@@ -25,6 +25,4 @@
--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};
} }

View File

@@ -38,11 +38,6 @@ $linkColorHover: lighten( $linkColor, 20% );
$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() {

View File

@@ -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() {
@@ -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/).
@@ -249,17 +249,17 @@
<p> <p>
reveal.js comes with a few themes built in: <br> reveal.js comes with a few themes built in: <br>
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. --> <!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
<a href="#/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>

6
dist/reveal.css vendored

File diff suppressed because one or more lines are too long

6
dist/reveal.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
dist/reveal.js vendored

File diff suppressed because one or more lines are too long

2
dist/reveal.js.map vendored

File diff suppressed because one or more lines are too long

16
dist/theme/beige.css vendored
View File

@@ -37,18 +37,16 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
--r-link-color-hover: #c0a86e; --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);
} }

View File

@@ -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: #068de9;
--r-link-color-hover: #8dcffc;
--r-selection-background-color: #bee4fd;
--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);
}
}

View File

@@ -34,10 +34,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color: #42affa; --r-link-color: #42affa;
--r-link-color-dark: #068de9; --r-link-color-dark: #068de9;
--r-link-color-hover: #8dcffc; --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 {

View File

@@ -42,8 +42,6 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color-hover: #dd5566; --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 {

View File

@@ -1,3 +1,4 @@
@charset "UTF-8";
/** /**
* Dracula Dark theme for reveal.js. * Dracula Dark theme for reveal.js.
* Based on https://draculatheme.com * Based on https://draculatheme.com
@@ -43,8 +44,6 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color-hover: #8BE9FD; --r-link-color-hover: #8BE9FD;
--r-selection-background-color: #44475A; --r-selection-background-color: #44475A;
--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 {
@@ -374,12 +373,42 @@ section.has-light-background, section.has-light-background h1, section.has-light
.reveal strong, .reveal b { .reveal strong, .reveal b {
color: var(--r-bold-color); color: var(--r-bold-color);
} }
.reveal em, .reveal i, .reveal blockquote { .reveal em, .reveal i, .reveal blockquote {
color: var(--r-italic-color); color: var(--r-italic-color);
} }
.reveal code { .reveal code {
color: var(--r-inline-code-color); color: var(--r-inline-code-color);
} }
.reveal ul li::marker, .reveal ol li::marker {
.reveal ul {
list-style: none;
}
.reveal ul li::before {
content: "•";
color: var(--r-list-bullet-color); color: var(--r-list-bullet-color);
display: inline-block;
width: 1em;
margin-left: -1em;
}
.reveal ol {
list-style: none;
counter-reset: li;
}
.reveal ol li::before {
content: counter(li) ".";
color: var(--r-list-bullet-color);
display: inline-block;
width: 2em;
margin-left: -2.5em;
margin-right: 0.5em;
text-align: right;
}
.reveal ol li {
counter-increment: li;
} }

16
dist/theme/league.css vendored
View File

@@ -39,18 +39,16 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color-hover: #71e9f4; --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);
} }

7
dist/theme/moon.css vendored
View File

@@ -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;
} }
@@ -39,8 +44,6 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color-hover: #78b9e6; --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 {

View File

@@ -37,8 +37,6 @@ section.has-light-background, section.has-light-background h1, section.has-light
--r-link-color-hover: #f3d7ac; --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 {

View File

@@ -40,8 +40,6 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
--r-link-color-hover: #8b7c69; --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 {

View File

@@ -39,8 +39,6 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
--r-link-color-hover: #0000f1; --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 {

2
dist/theme/sky.css vendored
View File

@@ -41,8 +41,6 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
--r-link-color-hover: #74a7cb; --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 {

View File

@@ -40,8 +40,6 @@ html * {
--r-link-color-hover: #78b9e6; --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 {

View File

@@ -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: #1a53a1;
--r-link-color-hover: #6ca0e8;
--r-selection-background-color: #98bdef;
--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);
}
}

View File

@@ -36,8 +36,6 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
--r-link-color-hover: #6ca0e8; --r-link-color-hover: #6ca0e8;
--r-selection-background-color: #98bdef; --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 {

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -99,25 +99,6 @@
</script> </script>
</section> </section>
<!-- add optional line count offset, in this case 287 -->
<section data-markdown>
<script type="text/template">
## echo.c
```c [287: 2|4,6]
/* All of the options in this arg are valid, so handle them. */
p = arg + 1;
do {
if (*p == 'n')
nflag = 0;
if (*p == 'e')
eflag = '\\';
} while (*++p);
```
[source](https://git.busybox.net/busybox/tree/coreutils/echo.c?h=1_36_stable#n287)
</script>
</section>
<!-- Images --> <!-- Images -->
<section data-markdown> <section data-markdown>
<script type="text/template"> <script type="text/template">

View File

@@ -1,118 +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://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>
</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>

View File

@@ -1,11 +1,13 @@
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
@@ -29,7 +31,7 @@ const banner = `/*!
* ${pkg.homepage} * ${pkg.homepage}
* MIT licensed * MIT licensed
* *
* Copyright (C) 2011-2023 Hakim El Hattab, https://hakim.se * Copyright (C) 2011-2022 Hakim El Hattab, https://hakim.se
*/\n` */\n`
// Prevents warnings from opening too many test pages // Prevents warnings from opening too many test pages
@@ -162,10 +164,11 @@ function compileSass() {
sass.render({ sass.render({
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';
@@ -283,7 +286,7 @@ gulp.task('package', gulp.series(() =>
)) ))
gulp.task('reload', () => gulp.src(['index.html']) gulp.task('reload', () => gulp.src(['**/*.html', '**/*.md'])
.pipe(connect.reload())); .pipe(connect.reload()));
gulp.task('serve', () => { gulp.task('serve', () => {
@@ -295,19 +298,14 @@ gulp.task('serve', () => {
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', 'eslint'))
gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload')) gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], 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'))

View File

@@ -1,40 +1,48 @@
<!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"
/>
<title>reveal.js</title> <title>reveal.js</title>
<link rel="stylesheet" href="dist/reset.css"> <link rel="stylesheet" href="dist/reset.css" />
<link rel="stylesheet" href="dist/reveal.css"> <link rel="stylesheet" href="dist/reveal.css" />
<link rel="stylesheet" href="dist/theme/black.css"> <link rel="stylesheet" href="dist/theme/black.css" />
<!-- Theme used for syntax highlighted code --> <!-- Theme used for syntax highlighted code -->
<link rel="stylesheet" href="plugin/highlight/monokai.css"> <link rel="stylesheet" href="plugin/highlight/monokai.css" />
</head> </head>
<body>
<div class="reveal">
<div class="slides">
<section>Slide 1</section>
<section>Slide 2</section>
</div>
</div>
<script src="dist/reveal.js"></script> <body>
<script src="plugin/notes/notes.js"></script> <div class="reveal">
<script src="plugin/markdown/markdown.js"></script> <div class="slides">
<script src="plugin/highlight/highlight.js"></script> <section data-markdown="leetcode-20230106.md">
<script> </section>
// More info about initialization & config: <section data-markdown="leetcode-20230109.md">
// - https://revealjs.com/initialization/ </section>
// - https://revealjs.com/config/ </div>
Reveal.initialize({ </div>
hash: true, <script src="dist/reveal.js"></script>
<script src="plugin/notes/notes.js"></script>
<script src="plugin/math/math.js"></script>
<script src="plugin/markdown/markdown.js"></script>
<script src="plugin/highlight/highlight.js"></script>
<script>
// More info about initialization & config:
// - https://revealjs.com/initialization/
// - https://revealjs.com/config/
Reveal.initialize({
hash: true,
height: 1000,
width: 1000,
// Learn about plugins: https://revealjs.com/plugins/ // Learn about plugins: https://revealjs.com/plugins/
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ] plugins: [RevealMarkdown, RevealHighlight, RevealNotes, RevealMath.KaTeX],
}); });
</script> </script>
</body> </body>
</html> </html>

View File

@@ -65,9 +65,6 @@ 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,
@@ -256,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,
@@ -317,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: [],

View File

@@ -461,7 +461,7 @@ 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' );
} ); } );
@@ -504,7 +504,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,
@@ -573,14 +573,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.
@@ -608,7 +608,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

View File

@@ -190,30 +190,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 +211,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 );
} }
/** /**
@@ -301,12 +263,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 {
@@ -362,7 +322,14 @@ 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

View File

@@ -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,7 +252,7 @@ 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 );
} }

View File

@@ -1,170 +0,0 @@
/**
* 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;
const query = this.jumpInput.value.trim( '' );
let indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );
// If no valid index was found and the input query is a
// string, fall back on a simple 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 );
}
}

View File

@@ -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 );
} }
@@ -42,7 +43,6 @@ export default class Keyboard {
this.shortcuts['Shift + &#8592;/&#8593/&#8594;/&#8595;'] = 'Jump to first/last slide'; this.shortcuts['Shift + &#8592;/&#8593/&#8594;/&#8595;'] = 'Jump to first/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.
* *
@@ -167,10 +183,10 @@ export default class Keyboard {
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 certain modifiers for slide navigation shortcuts
let keyCodeUsesModifier = [32, 37, 38, 39, 40, 78, 80, 191].indexOf( event.keyCode ) !== -1; let isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1;
// 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 = !( isNavigationKey && event.shiftKey || event.altKey ) &&
( 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
@@ -334,7 +350,7 @@ export default class Keyboard {
} }
} }
// 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
@@ -343,20 +359,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();
}
}
// ?
else if( keyCode === 191 && event.shiftKey ) {
this.Reveal.toggleHelp();
}
else { else {
triggered = false; triggered = false;
} }

View File

@@ -40,7 +40,7 @@ export default class Location {
* *
* @returns slide indices or null * @returns slide indices or null
*/ */
getIndicesFromHash( hash=window.location.hash, options={} ) { getIndicesFromHash( 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 name = hash.replace( /^#\/?/, '' );
@@ -49,7 +49,7 @@ export default class Location {
// If the first bit is not fully numeric and there is a name we // 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;
@@ -62,19 +62,17 @@ export default class Location {
// Ensure the named link is a valid HTML ID attribute // Ensure the named link is a valid HTML ID attribute
try { try {
slide = document element = document.getElementById( decodeURIComponent( name ) );
.getElementById( decodeURIComponent( name ) )
.closest('.slides section');
} }
catch ( error ) { } catch ( error ) { }
if( slide ) { if( element ) {
return { ...this.Reveal.getIndices( slide ), f }; return { ...this.Reveal.getIndices( element ), f };
} }
} }
else { else {
const config = this.Reveal.getConfig(); const config = this.Reveal.getConfig();
let hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0; let hashIndexBase = config.hashOneBasedIndex ? 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,
@@ -141,7 +139,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;
} }

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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()`.
*/ */

View File

@@ -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
@@ -77,7 +79,8 @@ export default class Pointer {
this.showCursor(); this.showCursor();
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false ); document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false );
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false ); document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false ); document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
@@ -123,4 +126,4 @@ export default class Pointer {
} }
} }

View File

@@ -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,7 +16,7 @@ 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 )
@@ -42,11 +42,11 @@ 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(); const viewportElement = document.querySelector( '.reveal-viewport' );
let presentationBackground; let presentationBackground;
if( viewportElement ) { if( viewportElement ) {
const viewportStyles = window.getComputedStyle( viewportElement ); const viewportStyles = window.getComputedStyle( viewportElement );
@@ -226,12 +226,12 @@ export default class PrintView {
} }
/** /**
* 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 );
} }
} }

View File

@@ -1,888 +0,0 @@
import { HORIZONTAL_SLIDES_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 );
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 ) => {
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 );
// Copy the presentation-wide background to each page
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 );
});
}
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
const 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 = scrollTriggerHeight + 'px';
triggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';
page.pageElement.appendChild( triggerStick );
if( i === 0 ) {
triggerStick.style.marginTop = -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 = 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];
} );
}
/**
* 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.map( ( fragments, i ) => ({
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 );
}
}
/**
* 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;
page.slideElement.classList.remove( 'present' );
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();
}
}

View File

@@ -1,4 +1,4 @@
import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js' import { extend, queryAll, closest, getMimeTypeFromFile } from '../utils/util.js'
import { isMobile } from '../utils/device.js' import { isMobile } from '../utils/device.js'
import fitty from 'fitty'; import fitty from 'fitty';
@@ -25,10 +25,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;
@@ -112,9 +108,7 @@ export default class SlideContent {
// URL(s) // URL(s)
else { else {
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => { backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
// Decode URL(s) that are already encoded first return `url(${encodeURI(background.trim())})`;
let decoded = decodeURI(background.trim());
return `url(${encodeRFC3986URI(decoded)})`;
}).join( ',' ); }).join( ',' );
} }
} }

View File

@@ -23,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';
} }

View File

@@ -1,10 +1,7 @@
import SlideContent from './controllers/slidecontent.js' import SlideContent from './controllers/slidecontent.js'
import SlideNumber from './controllers/slidenumber.js' import SlideNumber from './controllers/slidenumber.js'
import JumpToSlide from './controllers/jumptoslide.js'
import Backgrounds from './controllers/backgrounds.js' import Backgrounds from './controllers/backgrounds.js'
import AutoAnimate from './controllers/autoanimate.js' import AutoAnimate from './controllers/autoanimate.js'
import ScrollView from './controllers/scrollview.js'
import PrintView from './controllers/printview.js'
import Fragments from './controllers/fragments.js' import Fragments from './controllers/fragments.js'
import Overview from './controllers/overview.js' import Overview from './controllers/overview.js'
import Keyboard from './controllers/keyboard.js' import Keyboard from './controllers/keyboard.js'
@@ -13,6 +10,7 @@ import Controls from './controllers/controls.js'
import Progress from './controllers/progress.js' import Progress from './controllers/progress.js'
import Pointer from './controllers/pointer.js' import Pointer from './controllers/pointer.js'
import Plugins from './controllers/plugins.js' import Plugins from './controllers/plugins.js'
import Print from './controllers/print.js'
import Touch from './controllers/touch.js' import Touch from './controllers/touch.js'
import Focus from './controllers/focus.js' import Focus from './controllers/focus.js'
import Notes from './controllers/notes.js' import Notes from './controllers/notes.js'
@@ -28,7 +26,7 @@ import {
} from './utils/constants.js' } from './utils/constants.js'
// The reveal.js version // The reveal.js version
export const VERSION = '5.0.1'; export const VERSION = '4.4.0';
/** /**
* reveal.js * reveal.js
@@ -103,11 +101,8 @@ export default function( revealElement, options ) {
// may be multiple presentations running in parallel. // may be multiple presentations running in parallel.
slideContent = new SlideContent( Reveal ), slideContent = new SlideContent( Reveal ),
slideNumber = new SlideNumber( Reveal ), slideNumber = new SlideNumber( Reveal ),
jumpToSlide = new JumpToSlide( Reveal ),
autoAnimate = new AutoAnimate( Reveal ), autoAnimate = new AutoAnimate( Reveal ),
backgrounds = new Backgrounds( Reveal ), backgrounds = new Backgrounds( Reveal ),
scrollView = new ScrollView( Reveal ),
printView = new PrintView( Reveal ),
fragments = new Fragments( Reveal ), fragments = new Fragments( Reveal ),
overview = new Overview( Reveal ), overview = new Overview( Reveal ),
keyboard = new Keyboard( Reveal ), keyboard = new Keyboard( Reveal ),
@@ -116,6 +111,7 @@ export default function( revealElement, options ) {
progress = new Progress( Reveal ), progress = new Progress( Reveal ),
pointer = new Pointer( Reveal ), pointer = new Pointer( Reveal ),
plugins = new Plugins( Reveal ), plugins = new Plugins( Reveal ),
print = new Print( Reveal ),
focus = new Focus( Reveal ), focus = new Focus( Reveal ),
touch = new Touch( Reveal ), touch = new Touch( Reveal ),
notes = new Notes( Reveal ); notes = new Notes( Reveal );
@@ -142,11 +138,6 @@ export default function( revealElement, options ) {
// 5. Query params // 5. Query params
config = { ...defaultConfig, ...config, ...options, ...initOptions, ...Util.getQueryHash() }; config = { ...defaultConfig, ...config, ...options, ...initOptions, ...Util.getQueryHash() };
// Legacy support for the ?print-pdf query
if( /print-pdf/gi.test( window.location.search ) ) {
config.view = 'print';
}
setViewport(); setViewport();
// Force a layout when the whole page, incl fonts, has loaded // Force a layout when the whole page, incl fonts, has loaded
@@ -208,15 +199,12 @@ export default function( revealElement, options ) {
// Updates the presentation to match the current configuration values // Updates the presentation to match the current configuration values
configure(); configure();
// Create slide backgrounds
backgrounds.update( true );
// Activate the print/scroll view if configured
activateInitialView();
// Read the initial hash // Read the initial hash
location.readURL(); location.readURL();
// Create slide backgrounds
backgrounds.update( true );
// Notify listeners that the presentation is ready but use a 1ms // Notify listeners that the presentation is ready but use a 1ms
// timeout to ensure it's not fired synchronously after #initialize() // timeout to ensure it's not fired synchronously after #initialize()
setTimeout( () => { setTimeout( () => {
@@ -235,41 +223,19 @@ export default function( revealElement, options ) {
}); });
}, 1 ); }, 1 );
} // Special setup and config is required when printing to PDF
if( print.isPrintingPDF() ) {
removeEventListeners();
/** // The document needs to have loaded for the PDF layout
* Activates the correct reveal.js view based on our config. // measurements to be accurate
* This is only invoked once during initialization. if( document.readyState === 'complete' ) {
*/ print.setupPDF();
function activateInitialView() {
const activatePrintView = config.view === 'print';
const activateScrollView = config.view === 'scroll' || config.view === 'reader';
if( activatePrintView || activateScrollView ) {
if( activatePrintView ) {
removeEventListeners();
} }
else { else {
touch.unbind(); window.addEventListener( 'load', () => {
} print.setupPDF();
} );
// Avoid content flickering during layout
dom.viewport.classList.add( 'loading-scroll-mode' );
if( activatePrintView ) {
// The document needs to have loaded for the PDF layout
// measurements to be accurate
if( document.readyState === 'complete' ) {
printView.activate();
}
else {
window.addEventListener( 'load', () => printView.activate() );
}
}
else {
scrollView.activate();
} }
} }
@@ -287,18 +253,7 @@ export default function( revealElement, options ) {
if( !config.showHiddenSlides ) { if( !config.showHiddenSlides ) {
Util.queryAll( dom.wrapper, 'section[data-visibility="hidden"]' ).forEach( slide => { Util.queryAll( dom.wrapper, 'section[data-visibility="hidden"]' ).forEach( slide => {
const parent = slide.parentNode; slide.parentNode.removeChild( slide );
// If this slide is part of a stack and that stack will be
// empty after removing the hidden slide, remove the entire
// stack
if( parent.childElementCount === 1 && /section/i.test( parent.nodeName ) ) {
parent.remove();
}
else {
slide.remove();
}
} ); } );
} }
@@ -323,7 +278,6 @@ export default function( revealElement, options ) {
backgrounds.render(); backgrounds.render();
slideNumber.render(); slideNumber.render();
jumpToSlide.render();
controls.render(); controls.render();
progress.render(); progress.render();
notes.render(); notes.render();
@@ -417,7 +371,7 @@ export default function( revealElement, options ) {
function setupScrollPrevention() { function setupScrollPrevention() {
setInterval( () => { setInterval( () => {
if( !scrollView.isActive() && dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) { if( dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {
dom.wrapper.scrollTop = 0; dom.wrapper.scrollTop = 0;
dom.wrapper.scrollLeft = 0; dom.wrapper.scrollLeft = 0;
} }
@@ -484,8 +438,8 @@ export default function( revealElement, options ) {
dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition ); dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
// Expose our configured slide dimensions as custom props // Expose our configured slide dimensions as custom props
dom.viewport.style.setProperty( '--slide-width', typeof config.width === 'string' ? config.width : config.width + 'px' ); dom.viewport.style.setProperty( '--slide-width', config.width + 'px' );
dom.viewport.style.setProperty( '--slide-height', typeof config.height === 'string' ? config.height : config.height + 'px' ); dom.viewport.style.setProperty( '--slide-height', config.height + 'px' );
if( config.shuffle ) { if( config.shuffle ) {
shuffle(); shuffle();
@@ -617,7 +571,6 @@ export default function( revealElement, options ) {
progress.destroy(); progress.destroy();
backgrounds.destroy(); backgrounds.destroy();
slideNumber.destroy(); slideNumber.destroy();
jumpToSlide.destroy();
// Remove event listeners // Remove event listeners
document.removeEventListener( 'fullscreenchange', onFullscreenChange ); document.removeEventListener( 'fullscreenchange', onFullscreenChange );
@@ -721,26 +674,6 @@ export default function( revealElement, options ) {
} }
/**
* Dispatches a slidechanged event.
*
* @param {string} origin Used to identify multiplex clients
*/
function dispatchSlideChanged( origin ) {
dispatchEvent({
type: 'slidechanged',
data: {
indexh,
indexv,
previousSlide,
currentSlide,
origin
}
});
}
/** /**
* Dispatched a postMessage of the given type from our window. * Dispatched a postMessage of the given type from our window.
*/ */
@@ -924,10 +857,7 @@ export default function( revealElement, options ) {
*/ */
function layout() { function layout() {
if( dom.wrapper && !printView.isActive() ) { if( dom.wrapper && !print.isPrintingPDF() ) {
const viewportWidth = dom.viewport.offsetWidth;
const viewportHeight = dom.viewport.offsetHeight;
if( !config.disableLayout ) { if( !config.disableLayout ) {
@@ -941,9 +871,7 @@ export default function( revealElement, options ) {
document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' ); document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );
} }
const size = scrollView.isActive() ? const size = getComputedSlideSize();
getComputedSlideSize( viewportWidth, viewportHeight ) :
getComputedSlideSize();
const oldScale = scale; const oldScale = scale;
@@ -960,9 +888,8 @@ export default function( revealElement, options ) {
scale = Math.max( scale, config.minScale ); scale = Math.max( scale, config.minScale );
scale = Math.min( scale, config.maxScale ); scale = Math.min( scale, config.maxScale );
// Don't apply any scaling styles if scale is 1 or we're // Don't apply any scaling styles if scale is 1
// in the scroll view if( scale === 1 ) {
if( scale === 1 || scrollView.isActive() ) {
dom.slides.style.zoom = ''; dom.slides.style.zoom = '';
dom.slides.style.left = ''; dom.slides.style.left = '';
dom.slides.style.top = ''; dom.slides.style.top = '';
@@ -990,7 +917,7 @@ export default function( revealElement, options ) {
continue; continue;
} }
if( ( config.center || slide.classList.contains( 'center' ) ) ) { if( config.center || slide.classList.contains( 'center' ) ) {
// Vertical stacks are not centred since their section // Vertical stacks are not centred since their section
// children will be // children will be
if( slide.classList.contains( 'stack' ) ) { if( slide.classList.contains( 'stack' ) ) {
@@ -1016,25 +943,9 @@ export default function( revealElement, options ) {
} }
}); });
} }
// Responsively turn on the scroll mode if there is an activation
// width configured. Ignore if we're configured to always be in
// scroll mode.
if( typeof config.scrollActivationWidth === 'number' && config.view !== 'scroll' ) {
if( size.presentationWidth > 0 && size.presentationWidth <= config.scrollActivationWidth ) {
if( !scrollView.isActive() ) scrollView.activate();
}
else {
if( scrollView.isActive() ) scrollView.deactivate();
}
}
} }
dom.viewport.style.setProperty( '--slide-scale', scale ); dom.viewport.style.setProperty( '--slide-scale', scale );
dom.viewport.style.setProperty( '--viewport-width', viewportWidth + 'px' );
dom.viewport.style.setProperty( '--viewport-height', viewportHeight + 'px' );
scrollView.layout();
progress.update(); progress.update();
backgrounds.updateParallax(); backgrounds.updateParallax();
@@ -1055,6 +966,7 @@ export default function( revealElement, options ) {
* @param {string|number} height * @param {string|number} height
*/ */
function layoutSlideContents( width, height ) { function layoutSlideContents( width, height ) {
// Handle sizing of elements with the 'r-stretch' class // Handle sizing of elements with the 'r-stretch' class
Util.queryAll( dom.slides, 'section > .stretch, section > .r-stretch' ).forEach( element => { Util.queryAll( dom.slides, 'section > .stretch, section > .r-stretch' ).forEach( element => {
@@ -1091,18 +1003,10 @@ export default function( revealElement, options ) {
*/ */
function getComputedSlideSize( presentationWidth, presentationHeight ) { function getComputedSlideSize( presentationWidth, presentationHeight ) {
let width = config.width;
let height = config.height;
if( config.disableLayout ) {
width = dom.slides.offsetWidth;
height = dom.slides.offsetHeight;
}
const size = { const size = {
// Slide size // Slide size
width: width, width: config.width,
height: height, height: config.height,
// Presentation size // Presentation size
presentationWidth: presentationWidth || dom.wrapper.offsetWidth, presentationWidth: presentationWidth || dom.wrapper.offsetWidth,
@@ -1177,19 +1081,6 @@ export default function( revealElement, options ) {
} }
/**
* Checks if the current or specified slide is a stack containing
* vertical slides.
*
* @param {HTMLElement} [slide=currentSlide]
* @return {Boolean}
*/
function isVerticalStack( slide = currentSlide ) {
return slide.classList.contains( '.stack' ) || slide.querySelector( 'section' ) !== null;
}
/** /**
* Returns true if we're on the last slide in the current * Returns true if we're on the last slide in the current
* vertical stack. * vertical stack.
@@ -1299,20 +1190,6 @@ export default function( revealElement, options ) {
} }
/**
* Toggles visibility of the jump-to-slide UI.
*/
function toggleJumpToSlide( override ) {
if( typeof override === 'boolean' ) {
override ? jumpToSlide.show() : jumpToSlide.hide();
}
else {
jumpToSlide.isVisible() ? jumpToSlide.hide() : jumpToSlide.show();
}
}
/** /**
* Toggles the auto slide mode on and off. * Toggles the auto slide mode on and off.
* *
@@ -1356,7 +1233,7 @@ export default function( revealElement, options ) {
*/ */
function slide( h, v, f, origin ) { function slide( h, v, f, origin ) {
// Dispatch an event before the slide // Dispatch an event before hte slide
const slidechange = dispatchEvent({ const slidechange = dispatchEvent({
type: 'beforeslidechange', type: 'beforeslidechange',
data: { data: {
@@ -1375,14 +1252,6 @@ export default function( revealElement, options ) {
// Query all horizontal slides in the deck // Query all horizontal slides in the deck
const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ); const horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
// If we're in scroll mode, we scroll the target slide into view
// instead of running our standard slide transition
if( scrollView.isActive() ) {
const scrollToSlide = scrollView.getSlideByIndices( h, v );
if( scrollToSlide ) scrollView.scrollToSlide( scrollToSlide );
return;
}
// Abort if there are no slides // Abort if there are no slides
if( horizontalSlides.length === 0 ) return; if( horizontalSlides.length === 0 ) return;
@@ -1429,9 +1298,6 @@ export default function( revealElement, options ) {
// Detect if we're moving between two auto-animated slides // Detect if we're moving between two auto-animated slides
if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) { if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) {
transition = 'running';
autoAnimateTransition = shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexvBefore );
// If this is an auto-animated transition, we disable the // If this is an auto-animated transition, we disable the
// regular slide transition // regular slide transition
@@ -1439,9 +1305,16 @@ export default function( revealElement, options ) {
// Note 20-03-2020: // Note 20-03-2020:
// This needs to happen before we update slide visibility, // This needs to happen before we update slide visibility,
// otherwise transitions will still run in Safari. // otherwise transitions will still run in Safari.
if( autoAnimateTransition ) { if( previousSlide.hasAttribute( 'data-auto-animate' ) && currentSlide.hasAttribute( 'data-auto-animate' )
dom.slides.classList.add( 'disable-slide-transitions' ) && previousSlide.getAttribute( 'data-auto-animate-id' ) === currentSlide.getAttribute( 'data-auto-animate-id' )
&& !( ( indexh > indexhBefore || indexv > indexvBefore ) ? currentSlide : previousSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
autoAnimateTransition = true;
dom.slides.classList.add( 'disable-slide-transitions' );
} }
transition = 'running';
} }
// Update the visibility of slides now that the indices have changed // Update the visibility of slides now that the indices have changed
@@ -1500,7 +1373,16 @@ export default function( revealElement, options ) {
} }
if( slideChanged ) { if( slideChanged ) {
dispatchSlideChanged( origin ); dispatchEvent({
type: 'slidechanged',
data: {
indexh,
indexv,
previousSlide,
currentSlide,
origin
}
});
} }
// Handle embedded content // Handle embedded content
@@ -1545,71 +1427,6 @@ export default function( revealElement, options ) {
} }
/**
* Checks whether or not an auto-animation should take place between
* the two given slides.
*
* @param {HTMLElement} fromSlide
* @param {HTMLElement} toSlide
* @param {number} indexhBefore
* @param {number} indexvBefore
*
* @returns {boolean}
*/
function shouldAutoAnimateBetween( fromSlide, toSlide, indexhBefore, indexvBefore ) {
return fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' ) &&
fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) &&
!( ( indexh > indexhBefore || indexv > indexvBefore ) ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' );
}
/**
* Called anytime a new slide should be activated while in the scroll
* view. The active slide is the page that occupies the most space in
* the scrollable viewport.
*
* @param {number} pageIndex
* @param {HTMLElement} slideElement
*/
function setCurrentScrollPage( slideElement, h, v ) {
let indexhBefore = indexh || 0;
indexh = h;
indexv = v;
const slideChanged = currentSlide !== slideElement;
previousSlide = currentSlide;
currentSlide = slideElement;
if( currentSlide && previousSlide ) {
if( config.autoAnimate && shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexv ) ) {
// Run the auto-animation between our slides
autoAnimate.run( previousSlide, currentSlide );
}
}
// Start or stop embedded content like videos and iframes
if( slideChanged ) {
if( previousSlide ) {
slideContent.stopEmbeddedContent( previousSlide );
slideContent.stopEmbeddedContent( previousSlide.slideBackgroundElement );
}
slideContent.startEmbeddedContent( currentSlide );
slideContent.startEmbeddedContent( currentSlide.slideBackgroundElement );
}
requestAnimationFrame( () => {
announceStatus( getStatusText( currentSlide ) );
});
dispatchSlideChanged();
}
/** /**
* Syncs the presentation with the current DOM. Useful * Syncs the presentation with the current DOM. Useful
* when new slides or control elements are added or when * when new slides or control elements are added or when
@@ -1636,9 +1453,7 @@ export default function( revealElement, options ) {
// Write the current hash to the URL // Write the current hash to the URL
location.writeURL(); location.writeURL();
if( config.sortFragmentsOnSync === true ) { fragments.sortAll();
fragments.sortAll();
}
controls.update(); controls.update();
progress.update(); progress.update();
@@ -1755,7 +1570,7 @@ export default function( revealElement, options ) {
let slides = Util.queryAll( dom.wrapper, selector ), let slides = Util.queryAll( dom.wrapper, selector ),
slidesLength = slides.length; slidesLength = slides.length;
let printMode = scrollView.isActive() || printView.isActive(); let printMode = print.isPrintingPDF();
let loopedForwards = false; let loopedForwards = false;
let loopedBackwards = false; let loopedBackwards = false;
@@ -1867,7 +1682,7 @@ export default function( revealElement, options ) {
} }
/** /**
* Shows all fragment elements within the given container. * Shows all fragment elements within the given contaienr.
*/ */
function showFragmentsIn( container ) { function showFragmentsIn( container ) {
@@ -1879,7 +1694,7 @@ export default function( revealElement, options ) {
} }
/** /**
* Hides all fragment elements within the given container. * Hides all fragment elements within the given contaienr.
*/ */
function hideFragmentsIn( container ) { function hideFragmentsIn( container ) {
@@ -1915,7 +1730,7 @@ export default function( revealElement, options ) {
} }
// All slides need to be visible when exporting to PDF // All slides need to be visible when exporting to PDF
if( printView.isActive() ) { if( print.isPrintingPDF() ) {
viewDistance = Number.MAX_VALUE; viewDistance = Number.MAX_VALUE;
} }
@@ -2019,7 +1834,7 @@ export default function( revealElement, options ) {
} }
// If includeFragments is set, a route will be considered // If includeFragments is set, a route will be considered
// available if either a slid OR fragment is available in // availalbe if either a slid OR fragment is available in
// the given direction // the given direction
if( includeFragments === true ) { if( includeFragments === true ) {
let fragmentRoutes = fragments.availableRoutes(); let fragmentRoutes = fragments.availableRoutes();
@@ -2146,31 +1961,21 @@ export default function( revealElement, options ) {
// If a slide is specified, return the indices of that slide // If a slide is specified, return the indices of that slide
if( slide ) { if( slide ) {
// In scroll mode the original h/x index is stored on the slide let isVertical = isVerticalSlide( slide );
if( scrollView.isActive() ) { let slideh = isVertical ? slide.parentNode : slide;
h = parseInt( slide.getAttribute( 'data-index-h' ), 10 );
if( slide.getAttribute( 'data-index-v' ) ) { // Select all horizontal slides
v = parseInt( slide.getAttribute( 'data-index-v' ), 10 ); let horizontalSlides = getHorizontalSlides();
}
}
else {
let isVertical = isVerticalSlide( slide );
let slideh = isVertical ? slide.parentNode : slide;
// Select all horizontal slides // Now that we know which the horizontal slide is, get its index
let horizontalSlides = getHorizontalSlides(); h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
// Now that we know which the horizontal slide is, get its index // Assume we're not vertical
h = Math.max( horizontalSlides.indexOf( slideh ), 0 ); v = undefined;
// Assume we're not vertical // If this is a vertical slide, grab the vertical index
v = undefined; if( isVertical ) {
v = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );
// If this is a vertical slide, grab the vertical index
if( isVertical ) {
v = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );
}
} }
} }
@@ -2371,7 +2176,11 @@ export default function( revealElement, options ) {
if( currentSlide && config.autoSlide !== false ) { if( currentSlide && config.autoSlide !== false ) {
let fragment = currentSlide.querySelector( '.current-fragment[data-autoslide]' ); let fragment = currentSlide.querySelector( '.current-fragment' );
// When the slide first appears there is no "current" fragment so
// we look for a data-autoslide timing on the first fragment
if( !fragment ) fragment = currentSlide.querySelector( '.fragment' );
let fragmentAutoSlide = fragment ? fragment.getAttribute( 'data-autoslide' ) : null; let fragmentAutoSlide = fragment ? fragment.getAttribute( 'data-autoslide' ) : null;
let parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null; let parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
@@ -2843,24 +2652,17 @@ export default function( revealElement, options ) {
// Toggles the overview mode on/off // Toggles the overview mode on/off
toggleOverview: overview.toggle.bind( overview ), toggleOverview: overview.toggle.bind( overview ),
// Toggles the scroll view on/off
toggleScrollView: scrollView.toggle.bind( scrollView ),
// Toggles the "black screen" mode on/off // Toggles the "black screen" mode on/off
togglePause, togglePause,
// Toggles the auto slide mode on/off // Toggles the auto slide mode on/off
toggleAutoSlide, toggleAutoSlide,
// Toggles visibility of the jump-to-slide UI
toggleJumpToSlide,
// Slide navigation checks // Slide navigation checks
isFirstSlide, isFirstSlide,
isLastSlide, isLastSlide,
isLastVerticalSlide, isLastVerticalSlide,
isVerticalSlide, isVerticalSlide,
isVerticalStack,
// State checks // State checks
isPaused, isPaused,
@@ -2868,9 +2670,7 @@ export default function( revealElement, options ) {
isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ), isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),
isOverview: overview.isActive.bind( overview ), isOverview: overview.isActive.bind( overview ),
isFocused: focus.isFocused.bind( focus ), isFocused: focus.isFocused.bind( focus ),
isPrintingPDF: print.isPrintingPDF.bind( print ),
isScrollView: scrollView.isActive.bind( scrollView ),
isPrintView: printView.isActive.bind( printView ),
// Checks if reveal.js has been loaded and is ready for use // Checks if reveal.js has been loaded and is ready for use
isReady: () => ready, isReady: () => ready,
@@ -2879,10 +2679,6 @@ export default function( revealElement, options ) {
loadSlide: slideContent.load.bind( slideContent ), loadSlide: slideContent.load.bind( slideContent ),
unloadSlide: slideContent.unload.bind( slideContent ), unloadSlide: slideContent.unload.bind( slideContent ),
// Media playback
startEmbeddedContent: () => slideContent.startEmbeddedContent( currentSlide ),
stopEmbeddedContent: () => slideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } ),
// Preview management // Preview management
showPreview, showPreview,
hidePreview: closeOverlay, hidePreview: closeOverlay,
@@ -2943,8 +2739,6 @@ export default function( revealElement, options ) {
hasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally, hasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,
hasNavigatedVertically: () => navigationHistory.hasNavigatedVertically, hasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,
shouldAutoAnimateBetween,
// Adds/removes a custom key binding // Adds/removes a custom key binding
addKeyBinding: keyboard.addKeyBinding.bind( keyboard ), addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ), removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
@@ -2956,7 +2750,6 @@ export default function( revealElement, options ) {
registerKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ), registerKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),
getComputedSlideSize, getComputedSlideSize,
setCurrentScrollPage,
// Returns the current scale of the presentation content // Returns the current scale of the presentation content
getScale: () => scale, getScale: () => scale,
@@ -2993,14 +2786,13 @@ export default function( revealElement, options ) {
getStatusText, getStatusText,
// Controllers // Controllers
print,
focus, focus,
scroll: scrollView,
progress, progress,
controls, controls,
location, location,
overview, overview,
fragments, fragments,
backgrounds,
slideContent, slideContent,
slideNumber, slideNumber,

View File

@@ -294,20 +294,4 @@ const fileExtensionToMimeMap = {
*/ */
export const getMimeTypeFromFile = ( filename='' ) => { export const getMimeTypeFromFile = ( filename='' ) => {
return fileExtensionToMimeMap[filename.split('.').pop()] 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()}`
);
} }

154
leetcode-20230106.md Normal file
View File

@@ -0,0 +1,154 @@
### Leetcode 💻 寒假 20230106
---
### 20. Valid Parentheses
验证左右括号是否匹配 (利用Stack)
```cpp [|3-11|12-20|22-24|26|28|29-32|34-40|44|]
class Solution {
public:
// 判断左右括号是否相等
inline bool match(const char &left, const char &right) {
switch (left) {
case '(': return right == ')';
case '{': return right == '}';
case '[': return right == ']';
}
return false;
}
// 判断是不是左括号
inline bool is_left(const char &c) {
switch (c) {
case '(': return true;
case '{': return true;
case '[': return true;
}
return false;
}
bool isValid(string s) {
// 判断长度是否为偶数
if (s.length() % 2 != 0)
return false;
stack<char> myStack;
for (auto const &c : s) {
if (is_left(c)) {
myStack.push(c);
continue;
}
if (myStack.empty())
return false;
if (!match(myStack.top(), c))
return false;
myStack.pop();
}
// 如果结束之后 stack 中还有元素
return myStack.empty();
}
};
```
Note:
3-10 首先有两个辅助函数一个叫match,用来判断左右括号是否相等,
12-20 然后是另一个函数慵懒判断是不是左括号。
22-24 进入主函数,先判断一下字符串长度是基数还是偶数,
如果是基数说明里面的括号肯定是不能左右匹配的就可以直接返回false
26 然后创建一个stack类型的变量myStack
28 然后用变量c去遍历s,这里用到的是c++11的语法auto是自动推断类型
const表示c是不能被更改的and符号表示这是一个左值引用
c的类型可以简单理解为字符串中的字符
29-32 如果c是左括号那么直接往stack中添加这个c,然后直接进入下一个循环
34-40 刚刚的语句已经把做括号的情况处理掉了那么剩下的情况就是c是右括号的情况。
我们先检查stack中是否为空为空的话说明stack中没有括号可以和c互相对应
那么让函数返回false。
接著取stack中最顶的括号和c进行配对如果不匹配返回false。
最后调用stack的pop方法移除stack中最顶部的括号。
44 最后的最后所有字符都匹配完了如果stack中还残留有括号
说明这个字符串也是不匹配的
---
### 84. Largest Rectangle in Histogram
```cpp [|2-4|6-8|26-28|9-10|12-14|16-20|23|26-31|]
int largestRectangleArea(vector<int> &heights) {
int ans = 0;
// 定义 stack 储存增序长方形
stack<int> order;
// 往 stack 中添加位于 index 的高度 height 的长方形
auto append = [&ans, &order, &heights]
(int index, int value) -> void {
// 计算单个长方形面积
ans = max(ans, value);
// stack 不为空 且 需要添加的长方形矮于 stack 中的长方形
while (!order.empty() &&
value < heights[order.top()]) {
// 计算面积
int h = heights[order.top()];
order.pop();
int w = index - 1 - (order.empty() ? -1 : order.top());
ans = max(ans, h * w);
}
order.push(index);
};
for (int i = 0; i < heights.size(); i++) {
append(i, heights[i]);
}
// 处理edge case, 在最末尾添加一个高度为-1的长方形
// 这将会计算stack中所有残留的长方形的面积
append(heights.size(), -1);
return ans;
}
```
Note:
2-4 首先定义一个整数变量answer,代表这道题的计算结果,
然后定义一个stack,元素类型是整数,用来储存长方形的索引,
注意是储存的是长方形的索引不是长方形的高度。
6-8 然后由于这部分代码要在多个地方被调用所以这里我用了c++11的匿名函数
append是函数名它接受两个参数一个是index一个是value,它没有返回值所以是void。
同时这个函数可以访问并修改ans,order,height,这里的and符号是表示捕获引用变量的意思
各位理解为这个函数可以在函数内修改到函数外的变量就行了。
26-28 定义好函数之后会在一个循环中遍历题目给的这个高度列表,
然后调用函数,传入每个长方形的索引和高度
9-10 进入函数后首先计算单个长方形的面积
12-14 然后进入一个循环,
循环的条件是stack 不为空 且 需要添加的长方形矮于 stack 中的长方形
16-20 在循环内获得高度h和宽度w,注意这里先调用了pop然后在调用top,
如果stack里面是空的那么调用top会引起奇怪的错误所以一定要检查是否为空。
这里用了一个三元表达式,如果空则返回-1,否则正常返回top.
23 循环结束之后也就是需要添加的长方形比stack中的长方形都高的时候
我们可以把它添加仅stack了
26-31 这是刚刚看到调用append的代码
注意代码运行到这里stack中是还有长方形的stack中残留的长方形还没有计算面积。
所以在最末尾的位置添加一个高度为-1的长方形
由于stack中的所有长方形都是正数加个-1进去会计算stack中残留的长方形面积。

305
leetcode-20230109.md Normal file
View File

@@ -0,0 +1,305 @@
# Leetcode 💻 寒假 20230109
---
### 169. Majority Element
> The majority element is the element that appears more than [n / 2] times.
```python [3]
class Solution:
def majorityElement(self, nums: List[int]) -> int:
return sorted(nums)[(len(nums)) // 2]
```
以下操作等价
```python
print(int(5 / 2)) # 2
print(5 // 2) # 2
```
Note:
第169题找出列表中出现次数最多的元素。
题目给了一个关键信息就是这个要找的元素出现次数超过n/2,
也就是超过这个列表长度的一半。
那么最简单的写法就是对数组进行排序,然后返回他的中位数。
注意我这里写了两个除号这是python整除的意思
---
### 56. Merge Intervals
```python [|2|4|5-7|9-12|14-15]
def merge(self, intervals):
intervals.sort(key = lambda i: i[0])
ret = []
for begin, end in intervals:
if not ret:
ret.append([begin, end])
continue
# overlap
if ret[-1][1] >= begin:
ret[-1][1] = max(end, ret[-1][1])
continue
ret.append([begin, end])
return ret
```
Note:
2首先对intervals进行排序注意intervals里灭个元素都是一个列表
这里key参数我们给他传入一个lambda临时函数
这个函数是干什么的呢他的任务就是输入一个i,然后返回i的第零个元素
意思是告诉排序函数你在排序的时候要用i的第零个元素作为排序的依据
4接着我们用begin和end这两个变量遍历intervals数组
5-7我们先处理第一种特殊情况就是ret数组为空
这种情况直接把当前遍历到的begin和end添加进去就行了
9-12第二种情况是发生了overlap我们需要把ret最后一个元素的end更新为最大的end.
14-15如果上面两种特殊情况都没有发生那么我们正常把begin和end添加到列表里就行了
---
### 避免嵌套
坏👎
```python []
if gpa < 2:
return 'failed'
else:
if gpa < 3:
return "good"
else:
return "excellent"
```
好👍
```python []
if gpa < 2:
return "failed"
if gpa < 3:
return "good"
return "excellent"
```
Note:
这里有个函数根据一个整数gpa变量返回对应的字符串。
假设这里用 if 判断第一种比较接近自然语言如果gpa小于2则返回failed
不然的话接着判断如果gpa小于3则返回good,不然就返回4。
第二种方法则比较符合程序设计思想,
先从条件范围小的情况开始处理先处理gpa小于2,然后处理gpa小于3
最后一个return是精髓保证这个函数无论在什么情况下都有一个返回值。
第一种情况下很多人写着写着就忘了返回值,然后各种内存报错又找不到在哪里出错,非常痛苦
---
### 避免嵌套基本思想
```python []
if 特殊情况:
处理特殊情况()
return
if 其他特殊情况:
处理其他特殊情况()
return
做该做的事情()
```
Note:
避免嵌套的基本思想就是early return,就是说进入函数之后,
先处理特殊情况和各种边界情况处理完之后直接return这个函数也就是early return.
最后再开始做函数该做的事情一般来说这都是比较好的写法如果你去看golang代码
你能看到大量这样的写法这也是golang社区和官方建议的写法。
---
### 15. 3Sum
```python [|4-8|6]
import itertools
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
ret = {
tuple(sorted(test))
for test in itertools.combinations(nums, 3)
if sum(test) == 0
}
return list(ret)
```
### List Comprehensions
求 0 到 100 所有能被 7 整除数的平方和
```python []
sum([i ** 2 for i in range(100) if i % 7 == 0])
```
### 迭代器
标准库提供的多种高效排列组合工具
```python []
list(itertools.combinations([1,2,3,4], 3))
# [(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
```
Note:
这题的解法其实也就一行就是4-8行的这个列表生成式那么列表生成式是什么捏。
列表生成式又叫做List comprehensions, 这里有个例子假设我们要求0到100所有能被7整除数的平方和
这个计算用列表生成式一行就能实现。首先最开始是个sum函数sum函数里面是一个列表
这个列表是中的每一个元素都是i的平方那么i从哪里来的呢i是for i in range(100) 这个循环中出来的,
并且i满足i除以7的余数是0这个条件。
回到4-8行ret是一个集合集合中每个元素是 **经过排序** 的 **元组** test,
test从哪里来呢test 是 第七行 这个for循环迭代出来的变量并且这个test满足第八行的这个求和等于0的条件。
那么这个itertools.combinations是什么函数呢它是标准库中提供的排列组合迭代器。
下面给各位回忆一下高中排列组合的知识假设我们有一个列表列表中有元素1 2 3 4,每次取三个不同的元素,
那么一共有多少中不同的排列组合呢。用combinations函数就能非常方便的帮我们遍历所有排列组合。
理论上,这题就这么可以解出来了,但是实际上是不行的
```
---
但是时间复杂度 `$O(n^3)$`
3000 数组长度就是 27,000,000,000 次循环(百亿)😢
python for 循环在一般电脑上一秒钟能跑一千万次左右
思路:哈希表(字典)具有 `$O(1)$` 查找速度,使用字典代替最深的一层循环,将算法优化为 `$O(n^2)$`
```python [|5-7|9-14|16-17|18-21|22-25|27-34|36-38]
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
# 处理全是相同数字的特殊情况
if min(nums) == max(nums) and sum(nums) == 0:
return [[min(nums)] * 3]
# 生成反向字典,之后用于加速查找
reverse = {}
for key, val in enumerate(nums):
if reverse.get(val) is None:
reverse[val] = []
reverse[val].append(key)
# 创建集合,集合中元素是不可重复的
ret = set()
for index_i in range(len(nums)-2):
i = nums[index_i]
for index_j in range(index_i+1, len(nums)-1):
j = nums[index_j]
# 由于 sum((i,j,k)) == 0计算出需要的 k 是多少
k = -(i + j)
test = reverse.get(k)
# 情况1字典没有满足 sum((i,j,k))==0 的k
if test is None:
continue
# 情况2&3字典中有满足需求的k但它的索引是 i 或者 j
if len(test) == 1 and (index_i in test or index_j in test):
continue
if len(test) == 2 and (index_i in test and index_j in test):
continue
# 对 (i,j,k) 排序后放入元组中
# 利用元组不可重复的特性去掉重复结果
ret.add(tuple(sorted([i, j, k])))
return list(ret)
```
---
### 406. Queue Reconstruction by height
利用 list.insert() 能在指定位置插入元素,并把后面的元素往后移动的特点
```python [|2-3,6-8|]
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
# 按 p[0] 降序排p[0] 相同的情况下按 p[1] 升序排
people.sort(key = lambda p: (-p[0], p[1]))
res = []
for p in people:
# 在 p[1] 位置插入 p后面的元素会向后移动一位
# [TODO] 使用链表优化性能但这已经AC了能AC的就是好的👍
res.insert(p[1], p)
return res
# [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
```
⚠ python 标准库中有双向链表 `collections.deque`
⚠ c++ 标准库中也有链表 list
Note:
这道题其实也就两行代码第一行是将people排序第二行是在新数组中指定位置插入元素。
解题的关键就在利用了插入排序的特性,列表中后来插入的元素把之前插入的元素往后推一个位置。
但题外话我想提一下,
我们写算法关注算法性能,这没问题,但我自己个人是把代码简洁度看得比性能更重的。
写程序像写作一样,不光要机器能跑,还要其他人能看得懂,不光要看得懂,还要看得舒服,
怎么才算看得舒服呢,我个人认为是代码符合思维直觉,一个屏幕长度内的代码表达的信息量恰到好处,
不像流水账一样冗余,也不像汇编语言那样要盯着一行思考很久,当然我说了不算,
有本书叫《代码简洁之道》就专门讨论这类软件工程问题,感兴趣的可以找来看看。
还有就是标准库很重要,当然不是说要你把标注库背下来,
只是说要了解标准库能做到什么,还有了解你用的语言有哪些语法糖,
比如说三元表达式,不知道三元表达式这个语法糖的可以自己去查一下,
大部分现代语言比如python或者c++都有三元表达式这个语法糖,它能让代码更简短更简洁,
总的来说标准库的作用就是等你要用到相关功能的时候就知道去哪里查,而不是说自己重复造轮子
---
## C++
```cpp [|4|6-7|9-12|14-18]
#include <algorithm>
int main() {
std::array<int, 10> s = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
// 默认升序排序
std::sort(s.begin(), s.end());
// 自定义降序排序函数
std::sort(s.begin(), s.end, [](int a, int b) {
return a > b;
})
// 循环输出
for (auto const &i : s) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
```
---
### C++ 标准库中的排序以C11为例
- 快速排序平均复杂度为 `$O(N log N)$` ,最坏情况下为 `$O(N^2)$`,快排递归带来额外开销
- 堆排序比快排慢,但最坏情况下为 `$(N log N)$`
- 插入排序在大致有序的情况下表现非常好
`std::sort` 实现了 Introspective sorting集成了三种算法各自的优点
---
## End 🎉

14831
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "reveal.js", "name": "reveal.js",
"version": "5.0.2", "version": "4.4.0",
"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,37 +30,33 @@
"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": "^4.0.2", "gulp": "^4.0.2",
"gulp-autoprefixer": "^8.0.0", "gulp-autoprefixer": "^8.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": "^2.0.9", "gulp-header": "^2.0.9",
"gulp-tap": "^2.0.0", "gulp-tap": "^2.0.0",
"gulp-zip": "^5.1.0", "gulp-zip": "^4.2.0",
"highlight.js": "^11.9.0", "highlight.js": "^10.0.3",
"marked": "^4.3.0", "marked": "^4.0.12",
"node-qunit-puppeteer": "^2.1.2", "node-qunit-puppeteer": "^2.1.0",
"qunit": "^2.20.0", "qunit": "^2.17.2",
"rollup": "^4.1.5", "rollup": "^2.48.0",
"sass": "^1.69.5", "rollup-plugin-terser": "^7.0.2",
"yargs": "^17.7.2" "sass": "^1.39.2",
}, "yargs": "^15.1.0"
"overrides": {
"chokidar": "3.5.3",
"glob-parent": "6.0.2"
}, },
"browserslist": "> 2%, not dead", "browserslist": "> 2%, not dead",
"eslintConfig": { "eslintConfig": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -7,16 +7,13 @@
import { marked } from 'marked'; import { marked } from 'marked';
const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n', const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
DEFAULT_VERTICAL_SEPARATOR = null, DEFAULT_NOTES_SEPARATOR = 'notes?:',
DEFAULT_NOTES_SEPARATOR = '^\s*notes?:',
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$', DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$'; DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
// match an optional line number offset and highlight line numbers const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
// [<line numbers>] or [<offset>: <line numbers>]
const CODE_LINE_NUMBER_REGEX = /\[\s*((\d*):)?\s*([\s\d,|-]*)\]/;
const HTML_ESCAPE_MAP = { const HTML_ESCAPE_MAP = {
'&': '&amp;', '&': '&amp;',
@@ -38,22 +35,22 @@ const Plugin = () => {
function getMarkdownFromSlide( section ) { function getMarkdownFromSlide( section ) {
// look for a <script> or <textarea data-template> wrapper // look for a <script> or <textarea data-template> wrapper
const template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' ); var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
// strip leading whitespace so it isn't evaluated as code // strip leading whitespace so it isn't evaluated as code
let text = ( template || section ).textContent; var text = ( template || section ).textContent;
// restore script end tags // restore script end tags
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' ); text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
const leadingWs = text.match( /^\n?(\s*)/ )[1].length, var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
leadingTabs = text.match( /^\n?(\t*)/ )[1].length; leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
if( leadingTabs > 0 ) { if( leadingTabs > 0 ) {
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}(.*)','g'), function(m, p1) { return '\n' + p1 ; } ); text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
} }
else if( leadingWs > 1 ) { else if( leadingWs > 1 ) {
text = text.replace( new RegExp('\\n? {' + leadingWs + '}(.*)', 'g'), function(m, p1) { return '\n' + p1 ; } ); text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
} }
return text; return text;
@@ -68,11 +65,11 @@ const Plugin = () => {
*/ */
function getForwardedAttributes( section ) { function getForwardedAttributes( section ) {
const attributes = section.attributes; var attributes = section.attributes;
const result = []; var result = [];
for( let i = 0, len = attributes.length; i < len; i++ ) { for( var i = 0, len = attributes.length; i < len; i++ ) {
const name = attributes[i].name, var name = attributes[i].name,
value = attributes[i].value; value = attributes[i].value;
// disregard attributes that are used for markdown loading/parsing // disregard attributes that are used for markdown loading/parsing
@@ -95,12 +92,10 @@ const Plugin = () => {
* values for what's not defined. * values for what's not defined.
*/ */
function getSlidifyOptions( options ) { function getSlidifyOptions( options ) {
const markdownConfig = deck?.getConfig?.().markdown;
options = options || {}; options = options || {};
options.separator = options.separator || markdownConfig?.separator || DEFAULT_SLIDE_SEPARATOR; options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
options.verticalSeparator = options.verticalSeparator || markdownConfig?.verticalSeparator || DEFAULT_VERTICAL_SEPARATOR; options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
options.notesSeparator = options.notesSeparator || markdownConfig?.notesSeparator || DEFAULT_NOTES_SEPARATOR;
options.attributes = options.attributes || ''; options.attributes = options.attributes || '';
return options; return options;
@@ -114,7 +109,7 @@ const Plugin = () => {
options = getSlidifyOptions( options ); options = getSlidifyOptions( options );
const notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) ); var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
if( notesMatch.length === 2 ) { if( notesMatch.length === 2 ) {
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>'; content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
@@ -136,10 +131,10 @@ const Plugin = () => {
options = getSlidifyOptions( options ); options = getSlidifyOptions( options );
const separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ), var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
horizontalSeparatorRegex = new RegExp( options.separator ); horizontalSeparatorRegex = new RegExp( options.separator );
let matches, var matches,
lastIndex = 0, lastIndex = 0,
isHorizontal, isHorizontal,
wasHorizontal = true, wasHorizontal = true,
@@ -148,7 +143,7 @@ const Plugin = () => {
// iterate until all blocks between separators are stacked up // iterate until all blocks between separators are stacked up
while( matches = separatorRegex.exec( markdown ) ) { while( matches = separatorRegex.exec( markdown ) ) {
const notes = null; var notes = null;
// determine direction (horizontal by default) // determine direction (horizontal by default)
isHorizontal = horizontalSeparatorRegex.test( matches[0] ); isHorizontal = horizontalSeparatorRegex.test( matches[0] );
@@ -177,10 +172,10 @@ const Plugin = () => {
// add the remaining slide // add the remaining slide
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) ); ( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
let markdownSections = ''; var markdownSections = '';
// flatten the hierarchical stack, and insert <section data-markdown> tags // flatten the hierarchical stack, and insert <section data-markdown> tags
for( let i = 0, len = sectionStack.length; i < len; i++ ) { for( var i = 0, len = sectionStack.length; i < len; i++ ) {
// vertical // vertical
if( sectionStack[i] instanceof Array ) { if( sectionStack[i] instanceof Array ) {
markdownSections += '<section '+ options.attributes +'>'; markdownSections += '<section '+ options.attributes +'>';
@@ -209,7 +204,7 @@ const Plugin = () => {
return new Promise( function( resolve ) { return new Promise( function( resolve ) {
const externalPromises = []; var externalPromises = [];
[].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) { [].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
@@ -262,13 +257,13 @@ const Plugin = () => {
return new Promise( function( resolve, reject ) { return new Promise( function( resolve, reject ) {
const xhr = new XMLHttpRequest(), var xhr = new XMLHttpRequest(),
url = section.getAttribute( 'data-markdown' ); url = section.getAttribute( 'data-markdown' );
const datacharset = section.getAttribute( 'data-charset' ); var datacharset = section.getAttribute( 'data-charset' );
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if( datacharset !== null && datacharset !== '' ) { if( datacharset != null && datacharset != '' ) {
xhr.overrideMimeType( 'text/html; charset=' + datacharset ); xhr.overrideMimeType( 'text/html; charset=' + datacharset );
} }
@@ -313,17 +308,17 @@ const Plugin = () => {
*/ */
function addAttributeInElement( node, elementTarget, separator ) { function addAttributeInElement( node, elementTarget, separator ) {
const markdownClassesInElementsRegex = new RegExp( separator, 'mg' ); var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
const markdownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' ); var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
let nodeValue = node.nodeValue; var nodeValue = node.nodeValue;
let matches, var matches,
matchesClass; matchesClass;
if( matches = markdownClassesInElementsRegex.exec( nodeValue ) ) { if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
const classes = matches[1]; var classes = matches[1];
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( markdownClassesInElementsRegex.lastIndex ); nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
node.nodeValue = nodeValue; node.nodeValue = nodeValue;
while( matchesClass = markdownClassRegex.exec( classes ) ) { while( matchesClass = mardownClassRegex.exec( classes ) ) {
if( matchesClass[2] ) { if( matchesClass[2] ) {
elementTarget.setAttribute( matchesClass[1], matchesClass[2] ); elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
} else { } else {
@@ -341,34 +336,34 @@ const Plugin = () => {
*/ */
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) { function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
if ( element !== null && element.childNodes !== undefined && element.childNodes.length > 0 ) { if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
let previousParentElement = element; var previousParentElement = element;
for( let i = 0; i < element.childNodes.length; i++ ) { for( var i = 0; i < element.childNodes.length; i++ ) {
const childElement = element.childNodes[i]; var childElement = element.childNodes[i];
if ( i > 0 ) { if ( i > 0 ) {
let j = i - 1; var j = i - 1;
while ( j >= 0 ) { while ( j >= 0 ) {
const aPreviousChildElement = element.childNodes[j]; var aPreviousChildElement = element.childNodes[j];
if ( typeof aPreviousChildElement.setAttribute === 'function' && aPreviousChildElement.tagName !== "BR" ) { if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
previousParentElement = aPreviousChildElement; previousParentElement = aPreviousChildElement;
break; break;
} }
j = j - 1; j = j - 1;
} }
} }
let parentSection = section; var parentSection = section;
if( childElement.nodeName === "section" ) { if( childElement.nodeName == "section" ) {
parentSection = childElement ; parentSection = childElement ;
previousParentElement = childElement ; previousParentElement = childElement ;
} }
if ( typeof childElement.setAttribute === 'function' || childElement.nodeType === Node.COMMENT_NODE ) { if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes ); addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
} }
} }
} }
if ( element.nodeType === Node.COMMENT_NODE ) { if ( element.nodeType == Node.COMMENT_NODE ) {
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) === false ) { if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
addAttributeInElement( element, section, separatorSectionAttributes ); addAttributeInElement( element, section, separatorSectionAttributes );
} }
} }
@@ -380,14 +375,14 @@ const Plugin = () => {
*/ */
function convertSlides() { function convertSlides() {
const sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])'); var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
[].slice.call( sections ).forEach( function( section ) { [].slice.call( sections ).forEach( function( section ) {
section.setAttribute( 'data-markdown-parsed', true ) section.setAttribute( 'data-markdown-parsed', true )
const notes = section.querySelector( 'aside.notes' ); var notes = section.querySelector( 'aside.notes' );
const markdown = getMarkdownFromSlide( section ); var markdown = getMarkdownFromSlide( section );
section.innerHTML = marked( markdown ); section.innerHTML = marked( markdown );
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) || addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
@@ -434,23 +429,14 @@ const Plugin = () => {
renderer.code = ( code, language ) => { renderer.code = ( code, language ) => {
// Off by default // Off by default
let lineNumberOffset = '';
let lineNumbers = ''; let lineNumbers = '';
// Users can opt in to show line numbers and highlight // Users can opt in to show line numbers and highlight
// specific lines. // specific lines.
// ```javascript [] show line numbers // ```javascript [] show line numbers
// ```javascript [1,4-8] highlights lines 1 and 4-8 // ```javascript [1,4-8] highlights lines 1 and 4-8
// optional line number offset:
// ```javascript [25: 1,4-8] start line numbering at 25,
// highlights lines 1 (numbered as 25) and 4-8 (numbered as 28-32)
if( CODE_LINE_NUMBER_REGEX.test( language ) ) { if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
let lineNumberOffsetMatch = language.match( CODE_LINE_NUMBER_REGEX )[2]; lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
if (lineNumberOffsetMatch){
lineNumberOffset = `data-ln-start-from="${lineNumberOffsetMatch.trim()}"`;
}
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[3].trim();
lineNumbers = `data-line-numbers="${lineNumbers}"`; lineNumbers = `data-line-numbers="${lineNumbers}"`;
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim(); language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
} }
@@ -460,9 +446,7 @@ const Plugin = () => {
// highlight.js is able to read it // highlight.js is able to read it
code = escapeForHTML( code ); code = escapeForHTML( code );
// return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`; return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
return `<pre><code ${lineNumbers} ${lineNumberOffset} class="${language}">${code}</code></pre>`;
}; };
} }

View File

@@ -3,4 +3,4 @@ const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(",
* This plugin is a wrapper for the MathJax2, * This plugin is a wrapper for the MathJax2,
* MathJax3 and KaTeX typesetter plugins. * MathJax3 and KaTeX typesetter plugins.
*/ */
var a=Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const a=t=>new Promise(((e,a)=>{const n=document.createElement("script");n.type="text/javascript",n.onload=e,n.onerror=a,n.src=t,document.head.append(n)}));return{id:"katex",init:function(n){t=n;let i=t.getConfig().katex||{},s={...e,...i};const{local:l,version:o,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",p=s.local?"":"@"+s.version,u=d+p+"/dist/katex.min.css",h=d+p+"/dist/contrib/mhchem.min.js",x=d+p+"/dist/contrib/auto-render.min.js",m=[d+p+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(n.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(u),async function(t){for(const e of t)await a(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(a){t=a;let n=t.getConfig().mathjax3||{},i={...e,...n};i.tex={...e.tex,...n.tex},i.options={...e.options,...n.options},i.startup={...e.startup,...n.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let a=document.createElement("script");a.type="text/javascript",a.id="MathJax-script",a.src=t,a.async=!0,a.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(a)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export{a as default}; var a=Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const a=t=>new Promise(((e,a)=>{const n=document.createElement("script");n.type="text/javascript",n.onload=e,n.onerror=a,n.src=t,document.head.append(n)}));return{id:"katex",init:function(n){t=n;let i=t.getConfig().katex||{},s={...e,...i};const{local:l,version:o,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",p=s.local?"":"@"+s.version,u=d+p+"/dist/katex.min.css",h=d+p+"/dist/contrib/mhchem.min.js",x=d+p+"/dist/contrib/auto-render.min.js",m=[d+p+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(n.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(u),async function(t){for(const e of t)await a(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(a){t=a;let n=t.getConfig().mathjax3||{},i={...e,...n};i.tex={...e.tex,...n.tex},i.options={...e.options,...n.options},i.startup={...e.startup,...n.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let a=document.createElement("script");a.type="text/javascript",a.id="MathJax-script",a.src=t,a.async=!0,a.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(a)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export default a;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -146,12 +146,8 @@ const Plugin = () => {
} }
// Look for notes defined in an aside element // Look for notes defined in an aside element
if( notesElements && notesElements.length ) { if( notesElements ) {
// Ignore notes inside of fragments since those are shown messageData.notes = Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' );
// individually when stepping through fragments
notesElements = Array.from( notesElements ).filter( notesElement => notesElement.closest( '.fragment' ) === null );
messageData.notes = notesElements.map( notesElement => notesElement.innerHTML ).join( '\n' );
messageData.markdown = notesElements[0] && typeof notesElements[0].getAttribute( 'data-markdown' ) === 'string'; messageData.markdown = notesElements[0] && typeof notesElements[0].getAttribute( 'data-markdown' ) === 'string';
} }

View File

@@ -533,8 +533,8 @@
var urlSeparator = /\?/.test(data.url) ? '&' : '?'; var urlSeparator = /\?/.test(data.url) ? '&' : '?';
var hash = '#/' + data.state.indexh + '/' + data.state.indexv; var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
var currentURL = data.url + urlSeparator + params + '&scrollActivationWidth=false&postMessageEvents=true' + hash; var currentURL = data.url + urlSeparator + params + '&postMessageEvents=true' + hash;
var upcomingURL = data.url + urlSeparator + params + '&scrollActivationWidth=false&controls=false' + hash; var upcomingURL = data.url + urlSeparator + params + '&controls=false' + hash;
currentSlide = document.createElement( 'iframe' ); currentSlide = document.createElement( 'iframe' );
currentSlide.setAttribute( 'width', 1280 ); currentSlide.setAttribute( 'width', 1280 );

View File

@@ -4,4 +4,4 @@
* *
* @author Jon Snyder <snyder.jon@gmail.com>, February 2013 * @author Jon Snyder <snyder.jon@gmail.com>, February 2013
*/ */
const e=()=>{let e,t,n,l,o,i,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML='<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>\n\t\t</span>',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){if(13===t.keyCode)t.preventDefault(),function(){if(i){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),o=0)}l&&(l.length&&l.length<=o&&(o=0),l.length>o&&(e.slide(l[o].h,l[o].v),o++))}(),i=!1;else i=!0}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,o=n||"EM",i=new RegExp("^(?:"+o+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!i.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n<t.childNodes.length;n++)this.hiliteWords(t.childNodes[n]);var l,p;if(3==t.nodeType)if((l=t.nodeValue)&&(p=d.exec(l))){for(var u=t;null!=u&&"SECTION"!=u.nodeName;)u=u.parentNode;var h=e.getIndices(u),f=c.length,y=!1;for(n=0;n<f;n++)c[n].h===h.h&&c[n].v===h.v&&(y=!0);y||c.push(h),s[p[0].toLowerCase()]||(s[p[0].toLowerCase()]=r[a++%r.length]);var g=document.createElement(o);g.appendChild(document.createTextNode(p[0])),g.style.backgroundColor=s[p[0].toLowerCase()],g.style.fontStyle="inherit",g.style.color="#000";var v=t.splitText(p.index);v.nodeValue=v.nodeValue.substring(p[0].length),t.parentNode.insertBefore(g,v)}}},this.remove=function(){for(var e,t=document.getElementsByTagName(o);t.length&&(e=t[0]);)e.parentNode.replaceChild(e.firstChild,e)},this.apply=function(e){if(null!=e&&e)return this.remove(),this.setRegex(e),this.hiliteWords(l),c}}return{id:"search",init:n=>{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}};export{e as default}; export default()=>{let e,t,n,l,i,o,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML='<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>\n\t\t</span>',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){switch(t.keyCode){case 13:t.preventDefault(),function(){if(o){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),i=0)}l&&(l.length&&l.length<=i&&(i=0),l.length>i&&(e.slide(l[i].h,l[i].v),i++))}(),o=!1;break;default:o=!0}}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,i=n||"EM",o=new RegExp("^(?:"+i+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!o.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n<t.childNodes.length;n++)this.hiliteWords(t.childNodes[n]);var l,p;if(3==t.nodeType)if((l=t.nodeValue)&&(p=d.exec(l))){for(var u=t;null!=u&&"SECTION"!=u.nodeName;)u=u.parentNode;var h=e.getIndices(u),f=c.length,y=!1;for(n=0;n<f;n++)c[n].h===h.h&&c[n].v===h.v&&(y=!0);y||c.push(h),s[p[0].toLowerCase()]||(s[p[0].toLowerCase()]=r[a++%r.length]);var g=document.createElement(i);g.appendChild(document.createTextNode(p[0])),g.style.backgroundColor=s[p[0].toLowerCase()],g.style.fontStyle="inherit",g.style.color="#000";var v=t.splitText(p.index);v.nodeValue=v.nodeValue.substring(p[0].length),t.parentNode.insertBefore(g,v)}}},this.remove=function(){for(var e,t=document.getElementsByTagName(i);t.length&&(e=t[0]);)e.parentNode.replaceChild(e.firstChild,e)},this.apply=function(e){if(null!=e&&e)return this.remove(),this.setRegex(e),this.hiliteWords(l),c}}return{id:"search",init:n=>{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}};

View File

@@ -4,4 +4,4 @@
* by navigatating to that slide and highlighting it. * by navigatating to that slide and highlighting it.
* *
* @author Jon Snyder <snyder.jon@gmail.com>, February 2013 * @author Jon Snyder <snyder.jon@gmail.com>, February 2013
*/return()=>{let e,t,n,l,o,i,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML='<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>\n\t\t</span>',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){if(13===t.keyCode)t.preventDefault(),function(){if(i){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),o=0)}l&&(l.length&&l.length<=o&&(o=0),l.length>o&&(e.slide(l[o].h,l[o].v),o++))}(),i=!1;else i=!0}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,o=n||"EM",i=new RegExp("^(?:"+o+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!i.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n<t.childNodes.length;n++)this.hiliteWords(t.childNodes[n]);var l,f;if(3==t.nodeType)if((l=t.nodeValue)&&(f=d.exec(l))){for(var p=t;null!=p&&"SECTION"!=p.nodeName;)p=p.parentNode;var u=e.getIndices(p),h=c.length,y=!1;for(n=0;n<h;n++)c[n].h===u.h&&c[n].v===u.v&&(y=!0);y||c.push(u),s[f[0].toLowerCase()]||(s[f[0].toLowerCase()]=r[a++%r.length]);var g=document.createElement(o);g.appendChild(document.createTextNode(f[0])),g.style.backgroundColor=s[f[0].toLowerCase()],g.style.fontStyle="inherit",g.style.color="#000";var v=t.splitText(f.index);v.nodeValue=v.nodeValue.substring(f[0].length),t.parentNode.insertBefore(g,v)}}},this.remove=function(){for(var e,t=document.getElementsByTagName(o);t.length&&(e=t[0]);)e.parentNode.replaceChild(e.firstChild,e)},this.apply=function(e){if(null!=e&&e)return this.remove(),this.setRegex(e),this.hiliteWords(l),c}}return{id:"search",init:n=>{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}}})); */return()=>{let e,t,n,l,o,i,r;function s(){t=document.createElement("div"),t.classList.add("searchbox"),t.style.position="absolute",t.style.top="10px",t.style.right="10px",t.style.zIndex=10,t.innerHTML='<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>\n\t\t</span>',n=t.querySelector(".searchinput"),n.style.width="240px",n.style.fontSize="14px",n.style.padding="4px 6px",n.style.color="#000",n.style.background="#fff",n.style.borderRadius="2px",n.style.border="0",n.style.outline="0",n.style.boxShadow="0 2px 18px rgba(0, 0, 0, 0.2)",n.style["-webkit-appearance"]="none",e.getRevealElement().appendChild(t),n.addEventListener("keyup",(function(t){switch(t.keyCode){case 13:t.preventDefault(),function(){if(i){var t=n.value;""===t?(r&&r.remove(),l=null):(r=new c("slidecontent"),l=r.apply(t),o=0)}l&&(l.length&&l.length<=o&&(o=0),l.length>o&&(e.slide(l[o].h,l[o].v),o++))}(),i=!1;break;default:i=!0}}),!1),d()}function a(){t||s(),t.style.display="inline",n.focus(),n.select()}function d(){t||s(),t.style.display="none",r&&r.remove()}function c(t,n){var l=document.getElementById(t)||document.body,o=n||"EM",i=new RegExp("^(?:"+o+"|SCRIPT|FORM)$"),r=["#ff6","#a0ffff","#9f9","#f99","#f6f"],s=[],a=0,d="",c=[];this.setRegex=function(e){e=e.replace(/^[^\w]+|[^\w]+$/g,"").replace(/[^\w'-]+/g,"|"),d=new RegExp("("+e+")","i")},this.getRegex=function(){return d.toString().replace(/^\/\\b\(|\)\\b\/i$/g,"").replace(/\|/g," ")},this.hiliteWords=function(t){if(null!=t&&t&&d&&!i.test(t.nodeName)){if(t.hasChildNodes())for(var n=0;n<t.childNodes.length;n++)this.hiliteWords(t.childNodes[n]);var l,f;if(3==t.nodeType)if((l=t.nodeValue)&&(f=d.exec(l))){for(var u=t;null!=u&&"SECTION"!=u.nodeName;)u=u.parentNode;var p=e.getIndices(u),h=c.length,y=!1;for(n=0;n<h;n++)c[n].h===p.h&&c[n].v===p.v&&(y=!0);y||c.push(p),s[f[0].toLowerCase()]||(s[f[0].toLowerCase()]=r[a++%r.length]);var g=document.createElement(o);g.appendChild(document.createTextNode(f[0])),g.style.backgroundColor=s[f[0].toLowerCase()],g.style.fontStyle="inherit",g.style.color="#000";var v=t.splitText(f.index);v.nodeValue=v.nodeValue.substring(f[0].length),t.parentNode.insertBefore(g,v)}}},this.remove=function(){for(var e,t=document.getElementsByTagName(o);t.length&&(e=t[0]);)e.parentNode.replaceChild(e.firstChild,e)},this.apply=function(e){if(null!=e&&e)return this.remove(),this.setRegex(e),this.hiliteWords(l),c}}return{id:"search",init:n=>{e=n,e.registerKeyboardShortcut("CTRL + Shift + F","Search"),document.addEventListener("keydown",(function(e){"F"==e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t||s(),"inline"!==t.style.display?a():d())}),!1)},open:a}}}));

View File

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

View File

@@ -65,7 +65,6 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
QUnit.config.reorder = false; QUnit.config.reorder = false;
const slides = Array.prototype.map.call( document.querySelectorAll( '.slides section' ), slide => { const slides = Array.prototype.map.call( document.querySelectorAll( '.slides section' ), slide => {

View File

@@ -31,7 +31,6 @@
var externalScriptSequence = ''; var externalScriptSequence = '';
var scriptCount = 0; var scriptCount = 0;
QUnit.config.testTimeout = 30000;
QUnit.config.autostart = false; QUnit.config.autostart = false;
QUnit.module( 'Async Dependencies' ); QUnit.module( 'Async Dependencies' );

View File

@@ -30,10 +30,6 @@
<script> <script>
window.externalScriptSequence = ''; window.externalScriptSequence = '';
QUnit.config.testTimeout = 30000;
QUnit.config.autostart = false;
QUnit.module( 'Dependencies' );
Reveal.initialize({ Reveal.initialize({
dependencies: [ dependencies: [
{ src: 'assets/external-script-a.js' }, { src: 'assets/external-script-a.js' },
@@ -42,7 +38,7 @@
] ]
}).then( () => { }).then( () => {
QUnit.start(); QUnit.module( 'Dependencies' );
QUnit.test( 'Load synchronous scripts', function( assert ) { QUnit.test( 'Load synchronous scripts', function( assert ) {
assert.strictEqual( window.externalScriptSequence, 'ABC', 'Loaded and executed in order' ); assert.strictEqual( window.externalScriptSequence, 'ABC', 'Loaded and executed in order' );

View File

@@ -40,13 +40,9 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
QUnit.config.autostart = false;
QUnit.module( 'Grid Navigation' );
Reveal.initialize().then( () => { Reveal.initialize().then( () => {
QUnit.start(); QUnit.module( 'Grid Navigation' );
QUnit.test( 'Disabled', function( assert ) { QUnit.test( 'Disabled', function( assert ) {
Reveal.right(); Reveal.right();

View File

@@ -34,8 +34,6 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
Reveal.initialize({ viewDistance: 3 }).then( () => { Reveal.initialize({ viewDistance: 3 }).then( () => {
function getIframe( index ) { function getIframe( index ) {

View File

@@ -34,8 +34,6 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
Reveal.initialize({ viewDistance: 2 }).then( () => { Reveal.initialize({ viewDistance: 2 }).then( () => {
var defaultIframe = document.querySelector( '.default-iframe' ), var defaultIframe = document.querySelector( '.default-iframe' ),

View File

@@ -274,13 +274,6 @@
``` ```
</script> </script>
</section> </section>
<section data-markdown class="with-offset">
<script type="text/template">
```[123:]
code
```
</script>
</section>
<section data-markdown class="with-line-highlights-and-lanugage"> <section data-markdown class="with-line-highlights-and-lanugage">
<script type="text/template"> <script type="text/template">
```javascript [1,2,3] ```javascript [1,2,3]
@@ -288,20 +281,6 @@
``` ```
</script> </script>
</section> </section>
<section data-markdown class="with-line-highlights-offset-and-lanugage">
<script type="text/template">
```javascript [456: 3,4,5]
code
```
</script>
</section>
<section data-markdown class="with-line-offset-and-lanugage">
<script type="text/template">
```javascript [756:]
code
```
</script>
</section>
<section data-markdown class="with-code-in-fragment"> <section data-markdown class="with-code-in-fragment">
<script type="text/template"> <script type="text/template">
```js ```js
@@ -319,8 +298,6 @@
import Markdown from '../plugin/markdown/markdown.esm.js' import Markdown from '../plugin/markdown/markdown.esm.js'
import Highlight from '../plugin/highlight/highlight.esm.js' import Highlight from '../plugin/highlight/highlight.esm.js'
QUnit.config.testTimeout = 30000;
let deck1 = new Reveal( document.querySelector( '.deck1' ), { plugins: [ Markdown ] }) let deck1 = new Reveal( document.querySelector( '.deck1' ), { plugins: [ Markdown ] })
deck1.addEventListener( 'ready', function() { deck1.addEventListener( 'ready', function() {
@@ -481,22 +458,9 @@
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights .hljs[data-line-numbers="1,2,3"]' ).length, 1 ); assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights .hljs[data-line-numbers="1,2,3"]' ).length, 1 );
}); });
QUnit.test( '```[234: ] line offset only', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-offset .hljs[data-ln-start-from="123"]' ).length, 1 );
});
QUnit.test( '```javascript [1,2,3] enables line highlights and sets language', function( assert ) { QUnit.test( '```javascript [1,2,3] enables line highlights and sets language', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights-and-lanugage .hljs.javascript[data-line-numbers="1,2,3"]' ).length, 1 ); assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights-and-lanugage .hljs.javascript[data-line-numbers="1,2,3"]' ).length, 1 );
}); });
QUnit.test( '```javascript [123: 3,4,5] add line offset and enables line highlights and sets language', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights-offset-and-lanugage .hljs.javascript[data-line-numbers="3,4,5"]' ).length, 1 );
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights-offset-and-lanugage .hljs.javascript[data-ln-start-from="456"]' ).length, 1 );
});
QUnit.test( '```javascript [756:] add line offset and sets no line highlights and sets language', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-offset-and-lanugage .hljs.javascript[data-ln-start-from="756"]' ).length, 1 );
});
QUnit.test( '```block should allow custom fragment', function( assert ) { QUnit.test( '```block should allow custom fragment', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-code-in-fragment pre.fragment' ).length, 1 ); assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-code-in-fragment pre.fragment' ).length, 1 );

View File

@@ -40,7 +40,6 @@
<script src="../plugin/zoom/zoom.js"></script> <script src="../plugin/zoom/zoom.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
QUnit.module( 'Multiple reveal.js instances' ); QUnit.module( 'Multiple reveal.js instances' );
let r1 = new Reveal( document.querySelector( '.deck1 .reveal' ), { let r1 = new Reveal( document.querySelector( '.deck1 .reveal' ), {

View File

@@ -41,7 +41,6 @@
import Reveal from '../dist/reveal.esm.js'; import Reveal from '../dist/reveal.esm.js';
import Zoom from '../plugin/zoom/zoom.esm.js'; import Zoom from '../plugin/zoom/zoom.esm.js';
QUnit.config.testTimeout = 30000;
QUnit.module( 'Multiple reveal.js instances' ); QUnit.module( 'Multiple reveal.js instances' );
let r1 = new Reveal( document.querySelector( '.deck1 .reveal' ), { let r1 = new Reveal( document.querySelector( '.deck1 .reveal' ), {

View File

@@ -75,13 +75,8 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
QUnit.config.autostart = false;
Reveal.initialize({ pdf: true }).then( function() { Reveal.initialize({ pdf: true }).then( function() {
QUnit.start();
// Only one test for now, we're mainly ensuring that there // Only one test for now, we're mainly ensuring that there
// are no execution errors when running PDF mode // are no execution errors when running PDF mode

View File

@@ -29,7 +29,6 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
QUnit.module( 'Plugins' ); QUnit.module( 'Plugins' );
var initCounter = { PluginB: 0, PluginC: 0, PluginD: 0 }; var initCounter = { PluginB: 0, PluginC: 0, PluginD: 0 };

View File

@@ -1,115 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Test Scroll View</title>
<link rel="stylesheet" href="../dist/reveal.css">
<link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css">
<script src="../node_modules/qunit/qunit/qunit.js"></script>
</head>
<body style="overflow: auto;">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div class="reveal" style="opacity: 0; pointer-events: none;">
<div class="slides">
<section>
<h1>slide 1</h1>
</section>
<section>
<h1>slide 2</h1>
</section>
<section>
<h1>slide 3</h1>
<p class="fragment">fragment 1</p>
<p class="fragment">fragment 2</p>
<p class="fragment">fragment 3</p>
</section>
<section>
<h1>slide 4</h1>
</section>
</div>
</div>
<script src="../dist/reveal.js"></script>
<script>
QUnit.config.testTimeout = 30000;
QUnit.config.reorder = false;
function getScrollHeight() {
return Reveal.getViewportElement().scrollHeight;
}
function getViewportHeight() {
return Reveal.getViewportElement().offsetHeight;
}
Reveal.initialize({ view: 'scroll' }).then( async () => {
QUnit.module( 'Scroll View' );
QUnit.test( 'Activates', assert => {
assert.ok( getScrollHeight() > getViewportHeight(), 'Is overflowing' );
});
QUnit.test( 'Can be toggled via API', assert => {
Reveal.toggleScrollView( false );
assert.ok( getScrollHeight() <= getViewportHeight(), 'Is not overflowing' );
Reveal.toggleScrollView( true );
assert.ok( getScrollHeight() > getViewportHeight(), 'Is overflowing' );
});
QUnit.test( 'Changes present slide when scrolling', assert => {
assert.timeout( 200 );
assert.expect( 2 );
const slides = document.querySelectorAll( '.reveal .slides section' );
assert.ok( slides[0].classList.contains( 'present' ), 'First slide is present' );
Reveal.getViewportElement().scrollTop = getViewportHeight() * 1;
return new Promise( resolve => {
setTimeout(() => {
assert.ok( slides[1].classList.contains( 'present' ), 'Second slide is present' );
resolve();
}, 100);
} );
});
QUnit.test( 'Fires slideschanged event when scrolling', assert => {
assert.timeout( 200 );
assert.expect( 2 );
const slides = document.querySelectorAll( '.reveal .slides section' );
return new Promise( resolve => {
let callback = ( event ) => {
Reveal.off( 'slidechanged', callback );
assert.ok( true, 'slidechanged event fired' );
assert.ok( event.currentSlide.classList.contains( 'present' ), 'slidechanged provides reference to currentSlide' );
resolve();
}
Reveal.on( 'slidechanged', callback );
Reveal.getViewportElement().scrollTop = getViewportHeight() * 2;
});
});
} );
</script>
</body>
</html>

View File

@@ -39,95 +39,97 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
Reveal.initialize(); Reveal.initialize().then( function() {
console.log(Reveal);
QUnit.module( 'State' ); QUnit.module( 'State' );
QUnit.test( 'Fire events when changing slide', function( assert ) { QUnit.test( 'Fire events when changing slide', function( assert ) {
assert.expect( 2 ); assert.expect( 2 );
var state1 = assert.async(); var state1 = assert.async();
var state2 = assert.async(); var state2 = assert.async();
var _onState1 = function( event ) { var _onState1 = function( event ) {
assert.ok( true, 'state1 fired' ); assert.ok( true, 'state1 fired' );
state1(); state1();
} }
var _onState2 = function( event ) { var _onState2 = function( event ) {
assert.ok( true, 'state2 fired' ); assert.ok( true, 'state2 fired' );
state2(); state2();
} }
Reveal.on( 'state1', _onState1 ); Reveal.on( 'state1', _onState1 );
Reveal.on( 'state2', _onState2 ); Reveal.on( 'state2', _onState2 );
Reveal.slide( 1 ); Reveal.slide( 1 );
Reveal.slide( 3 ); Reveal.slide( 3 );
Reveal.off( 'state1', _onState1 ); Reveal.off( 'state1', _onState1 );
Reveal.off( 'state2', _onState2 ); Reveal.off( 'state2', _onState2 );
}); });
QUnit.test( 'Fire state events for vertical slides', function( assert ) { QUnit.test( 'Fire state events for vertical slides', function( assert ) {
assert.expect( 2 ); assert.expect( 2 );
var done = assert.async( 2 ); var done = assert.async( 2 );
var _onState1 = function( event ) { var _onState1 = function( event ) {
assert.ok( true, 'state1 fired' ); assert.ok( true, 'state1 fired' );
done(); done();
} }
var _onState3 = function( event ) { var _onState3 = function( event ) {
assert.ok( true, 'state3 fired' ); assert.ok( true, 'state3 fired' );
done(); done();
} }
Reveal.on( 'state1', _onState1 ); Reveal.on( 'state1', _onState1 );
Reveal.on( 'state3', _onState3 ); Reveal.on( 'state3', _onState3 );
Reveal.slide( 0 ); Reveal.slide( 0 );
Reveal.slide( 4, 1 ); Reveal.slide( 4, 1 );
Reveal.slide( 4, 2 ); Reveal.slide( 4, 2 );
Reveal.off( 'state1', _onState1 ); Reveal.off( 'state1', _onState1 );
Reveal.off( 'state3', _onState3 ); Reveal.off( 'state3', _onState3 );
}); });
QUnit.test( 'No events if state remains unchanged', function( assert ) { QUnit.test( 'No events if state remains unchanged', function( assert ) {
var stateChanges = 0; var stateChanges = 0;
var _onEvent = function( event ) { var _onEvent = function( event ) {
stateChanges += 1; stateChanges += 1;
} }
Reveal.on( 'state1', _onEvent ); Reveal.on( 'state1', _onEvent );
Reveal.slide( 0 ); // no state Reveal.slide( 0 ); // no state
Reveal.slide( 1 ); // state1 Reveal.slide( 1 ); // state1
Reveal.slide( 2 ); // state1 Reveal.slide( 2 ); // state1
Reveal.prev(); // state1 Reveal.prev(); // state1
Reveal.next(); // state1 Reveal.next(); // state1
Reveal.slide( 4, 1 ); // state1 Reveal.slide( 4, 1 ); // state1
Reveal.slide( 0 ); // no state Reveal.slide( 0 ); // no state
Reveal.off( 'state1', _onEvent ); Reveal.off( 'state1', _onEvent );
assert.strictEqual( stateChanges, 1, 'no event was fired when going to slide with same state' ); assert.strictEqual( stateChanges, 1, 'no event was fired when going to slide with same state' );
}); });
QUnit.test( 'Event order', function( assert ) { QUnit.test( 'Event order', function( assert ) {
var _onEvent = function( event ) { var _onEvent = function( event ) {
assert.ok( Reveal.getCurrentSlide() == document.querySelector( '#slide2' ), 'correct current slide immediately after state event' ); assert.ok( Reveal.getCurrentSlide() == document.querySelector( '#slide2' ), 'correct current slide immediately after state event' );
} }
Reveal.on( 'state1', _onEvent ); Reveal.on( 'state1', _onEvent );
Reveal.slide( 0 ); Reveal.slide( 0 );
Reveal.slide( 1 ); Reveal.slide( 1 );
Reveal.off( 'state1', _onEvent ); Reveal.off( 'state1', _onEvent );
}); });
} );
</script> </script>
</body> </body>

View File

@@ -83,8 +83,6 @@
<script src="../dist/reveal.js"></script> <script src="../dist/reveal.js"></script>
<script> <script>
QUnit.config.testTimeout = 30000;
window.location.hash = ''; window.location.hash = '';
Reveal.configure({maxScale: 1.11}); Reveal.configure({maxScale: 1.11});